RC outlet switch for mbed based on: https://github.com/sui77/rc-switch
Dependencies: mbed
RCSwitch.cpp@0:7d511a9bdaba, 2017-01-02 (annotated)
- Committer:
- ttajmajer
- Date:
- Mon Jan 02 13:41:03 2017 +0000
- Revision:
- 0:7d511a9bdaba
RC switch
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ttajmajer | 0:7d511a9bdaba | 1 | /* |
ttajmajer | 0:7d511a9bdaba | 2 | RCSwitch - Arduino libary for remote control outlet switches |
ttajmajer | 0:7d511a9bdaba | 3 | Copyright (c) 2011 Suat Özgür. All right reserved. |
ttajmajer | 0:7d511a9bdaba | 4 | |
ttajmajer | 0:7d511a9bdaba | 5 | Contributors: |
ttajmajer | 0:7d511a9bdaba | 6 | - Andre Koehler / info(at)tomate-online(dot)de |
ttajmajer | 0:7d511a9bdaba | 7 | - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com |
ttajmajer | 0:7d511a9bdaba | 8 | - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46 |
ttajmajer | 0:7d511a9bdaba | 9 | - Dominik Fischer / dom_fischer(at)web(dot)de |
ttajmajer | 0:7d511a9bdaba | 10 | - Frank Oltmanns / <first name>.<last name>(at)gmail(dot)com |
ttajmajer | 0:7d511a9bdaba | 11 | - Andreas Steinel / A.<lastname>(at)gmail(dot)com |
ttajmajer | 0:7d511a9bdaba | 12 | - Max Horn / max(at)quendi(dot)de |
ttajmajer | 0:7d511a9bdaba | 13 | - Robert ter Vehn / <first name>.<last name>(at)gmail(dot)com |
ttajmajer | 0:7d511a9bdaba | 14 | - Johann Richard / <first name>.<last name>(at)gmail(dot)com |
ttajmajer | 0:7d511a9bdaba | 15 | - Vlad Gheorghe / <first name>.<last name>(at)gmail(dot)com https://github.com/vgheo |
ttajmajer | 0:7d511a9bdaba | 16 | |
ttajmajer | 0:7d511a9bdaba | 17 | Project home: https://github.com/sui77/rc-switch/ |
ttajmajer | 0:7d511a9bdaba | 18 | |
ttajmajer | 0:7d511a9bdaba | 19 | This library is free software; you can redistribute it and/or |
ttajmajer | 0:7d511a9bdaba | 20 | modify it under the terms of the GNU Lesser General Public |
ttajmajer | 0:7d511a9bdaba | 21 | License as published by the Free Software Foundation; either |
ttajmajer | 0:7d511a9bdaba | 22 | version 2.1 of the License, or (at your option) any later version. |
ttajmajer | 0:7d511a9bdaba | 23 | |
ttajmajer | 0:7d511a9bdaba | 24 | This library is distributed in the hope that it will be useful, |
ttajmajer | 0:7d511a9bdaba | 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
ttajmajer | 0:7d511a9bdaba | 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
ttajmajer | 0:7d511a9bdaba | 27 | Lesser General Public License for more details. |
ttajmajer | 0:7d511a9bdaba | 28 | |
ttajmajer | 0:7d511a9bdaba | 29 | You should have received a copy of the GNU Lesser General Public |
ttajmajer | 0:7d511a9bdaba | 30 | License along with this library; if not, write to the Free Software |
ttajmajer | 0:7d511a9bdaba | 31 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
ttajmajer | 0:7d511a9bdaba | 32 | */ |
ttajmajer | 0:7d511a9bdaba | 33 | |
ttajmajer | 0:7d511a9bdaba | 34 | #include "RCSwitch.h" |
ttajmajer | 0:7d511a9bdaba | 35 | |
ttajmajer | 0:7d511a9bdaba | 36 | |
ttajmajer | 0:7d511a9bdaba | 37 | /* Format for protocol definitions: |
ttajmajer | 0:7d511a9bdaba | 38 | * {pulselength, Sync bit, "0" bit, "1" bit} |
ttajmajer | 0:7d511a9bdaba | 39 | * |
ttajmajer | 0:7d511a9bdaba | 40 | * pulselength: pulse length in microseconds, e.g. 350 |
ttajmajer | 0:7d511a9bdaba | 41 | * Sync bit: {1, 31} means 1 high pulse and 31 low pulses |
ttajmajer | 0:7d511a9bdaba | 42 | * (perceived as a 31*pulselength long pulse, total length of sync bit is |
ttajmajer | 0:7d511a9bdaba | 43 | * 32*pulselength microseconds), i.e: |
ttajmajer | 0:7d511a9bdaba | 44 | * _ |
ttajmajer | 0:7d511a9bdaba | 45 | * | |_______________________________ (don't count the vertical bars) |
ttajmajer | 0:7d511a9bdaba | 46 | * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse |
ttajmajer | 0:7d511a9bdaba | 47 | * and 3 low pulses, total length (1+3)*pulselength, i.e: |
ttajmajer | 0:7d511a9bdaba | 48 | * _ |
ttajmajer | 0:7d511a9bdaba | 49 | * | |___ |
ttajmajer | 0:7d511a9bdaba | 50 | * "1" bit: waveform for a data bit of value "1", e.g. {3,1}: |
ttajmajer | 0:7d511a9bdaba | 51 | * ___ |
ttajmajer | 0:7d511a9bdaba | 52 | * | |_ |
ttajmajer | 0:7d511a9bdaba | 53 | * |
ttajmajer | 0:7d511a9bdaba | 54 | * These are combined to form Tri-State bits when sending or receiving codes. |
ttajmajer | 0:7d511a9bdaba | 55 | */ |
ttajmajer | 0:7d511a9bdaba | 56 | |
ttajmajer | 0:7d511a9bdaba | 57 | static const RCSwitch::Protocol proto[] = { |
ttajmajer | 0:7d511a9bdaba | 58 | { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1 |
ttajmajer | 0:7d511a9bdaba | 59 | { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2 |
ttajmajer | 0:7d511a9bdaba | 60 | { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3 |
ttajmajer | 0:7d511a9bdaba | 61 | { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4 |
ttajmajer | 0:7d511a9bdaba | 62 | { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5 |
ttajmajer | 0:7d511a9bdaba | 63 | { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 6 (HT6P20B) |
ttajmajer | 0:7d511a9bdaba | 64 | }; |
ttajmajer | 0:7d511a9bdaba | 65 | |
ttajmajer | 0:7d511a9bdaba | 66 | enum { |
ttajmajer | 0:7d511a9bdaba | 67 | numProto = sizeof(proto) / sizeof(proto[0]) |
ttajmajer | 0:7d511a9bdaba | 68 | }; |
ttajmajer | 0:7d511a9bdaba | 69 | |
ttajmajer | 0:7d511a9bdaba | 70 | |
ttajmajer | 0:7d511a9bdaba | 71 | |
ttajmajer | 0:7d511a9bdaba | 72 | |
ttajmajer | 0:7d511a9bdaba | 73 | RCSwitch::RCSwitch(PinName outpin_num): _outpin(outpin_num) { |
ttajmajer | 0:7d511a9bdaba | 74 | this->nTransmitterPin = outpin_num; |
ttajmajer | 0:7d511a9bdaba | 75 | _outpin.output(); |
ttajmajer | 0:7d511a9bdaba | 76 | this->setRepeatTransmit(10); |
ttajmajer | 0:7d511a9bdaba | 77 | this->setProtocol(1); |
ttajmajer | 0:7d511a9bdaba | 78 | } |
ttajmajer | 0:7d511a9bdaba | 79 | |
ttajmajer | 0:7d511a9bdaba | 80 | /** |
ttajmajer | 0:7d511a9bdaba | 81 | * Sets the protocol to send. |
ttajmajer | 0:7d511a9bdaba | 82 | */ |
ttajmajer | 0:7d511a9bdaba | 83 | void RCSwitch::setProtocol(Protocol protocol) { |
ttajmajer | 0:7d511a9bdaba | 84 | this->protocol = protocol; |
ttajmajer | 0:7d511a9bdaba | 85 | } |
ttajmajer | 0:7d511a9bdaba | 86 | |
ttajmajer | 0:7d511a9bdaba | 87 | /** |
ttajmajer | 0:7d511a9bdaba | 88 | * Sets the protocol to send, from a list of predefined protocols |
ttajmajer | 0:7d511a9bdaba | 89 | */ |
ttajmajer | 0:7d511a9bdaba | 90 | void RCSwitch::setProtocol(int nProtocol) { |
ttajmajer | 0:7d511a9bdaba | 91 | if (nProtocol < 1 || nProtocol > numProto) { |
ttajmajer | 0:7d511a9bdaba | 92 | nProtocol = 1; // TODO: trigger an error, e.g. "bad protocol" ??? |
ttajmajer | 0:7d511a9bdaba | 93 | } |
ttajmajer | 0:7d511a9bdaba | 94 | memcpy(&this->protocol, &proto[nProtocol-1], sizeof(Protocol)); |
ttajmajer | 0:7d511a9bdaba | 95 | |
ttajmajer | 0:7d511a9bdaba | 96 | } |
ttajmajer | 0:7d511a9bdaba | 97 | |
ttajmajer | 0:7d511a9bdaba | 98 | /** |
ttajmajer | 0:7d511a9bdaba | 99 | * Sets the protocol to send with pulse length in microseconds. |
ttajmajer | 0:7d511a9bdaba | 100 | */ |
ttajmajer | 0:7d511a9bdaba | 101 | void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { |
ttajmajer | 0:7d511a9bdaba | 102 | setProtocol(nProtocol); |
ttajmajer | 0:7d511a9bdaba | 103 | this->setPulseLength(nPulseLength); |
ttajmajer | 0:7d511a9bdaba | 104 | } |
ttajmajer | 0:7d511a9bdaba | 105 | |
ttajmajer | 0:7d511a9bdaba | 106 | |
ttajmajer | 0:7d511a9bdaba | 107 | /** |
ttajmajer | 0:7d511a9bdaba | 108 | * Sets pulse length in microseconds |
ttajmajer | 0:7d511a9bdaba | 109 | */ |
ttajmajer | 0:7d511a9bdaba | 110 | void RCSwitch::setPulseLength(int nPulseLength) { |
ttajmajer | 0:7d511a9bdaba | 111 | this->protocol.pulseLength = nPulseLength; |
ttajmajer | 0:7d511a9bdaba | 112 | } |
ttajmajer | 0:7d511a9bdaba | 113 | |
ttajmajer | 0:7d511a9bdaba | 114 | /** |
ttajmajer | 0:7d511a9bdaba | 115 | * Sets Repeat Transmits |
ttajmajer | 0:7d511a9bdaba | 116 | */ |
ttajmajer | 0:7d511a9bdaba | 117 | void RCSwitch::setRepeatTransmit(int nRepeatTransmit) { |
ttajmajer | 0:7d511a9bdaba | 118 | this->nRepeatTransmit = nRepeatTransmit; |
ttajmajer | 0:7d511a9bdaba | 119 | } |
ttajmajer | 0:7d511a9bdaba | 120 | |
ttajmajer | 0:7d511a9bdaba | 121 | /** |
ttajmajer | 0:7d511a9bdaba | 122 | * Switch a remote switch on (Type D REV) |
ttajmajer | 0:7d511a9bdaba | 123 | * |
ttajmajer | 0:7d511a9bdaba | 124 | * @param sGroup Code of the switch group (A,B,C,D) |
ttajmajer | 0:7d511a9bdaba | 125 | * @param nDevice Number of the switch itself (1..3) |
ttajmajer | 0:7d511a9bdaba | 126 | */ |
ttajmajer | 0:7d511a9bdaba | 127 | void RCSwitch::switchOn(char sGroup, int nDevice) { |
ttajmajer | 0:7d511a9bdaba | 128 | this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) ); |
ttajmajer | 0:7d511a9bdaba | 129 | } |
ttajmajer | 0:7d511a9bdaba | 130 | |
ttajmajer | 0:7d511a9bdaba | 131 | /** |
ttajmajer | 0:7d511a9bdaba | 132 | * Switch a remote switch off (Type D REV) |
ttajmajer | 0:7d511a9bdaba | 133 | * |
ttajmajer | 0:7d511a9bdaba | 134 | * @param sGroup Code of the switch group (A,B,C,D) |
ttajmajer | 0:7d511a9bdaba | 135 | * @param nDevice Number of the switch itself (1..3) |
ttajmajer | 0:7d511a9bdaba | 136 | */ |
ttajmajer | 0:7d511a9bdaba | 137 | void RCSwitch::switchOff(char sGroup, int nDevice) { |
ttajmajer | 0:7d511a9bdaba | 138 | this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) ); |
ttajmajer | 0:7d511a9bdaba | 139 | } |
ttajmajer | 0:7d511a9bdaba | 140 | |
ttajmajer | 0:7d511a9bdaba | 141 | /** |
ttajmajer | 0:7d511a9bdaba | 142 | * Switch a remote switch on (Type C Intertechno) |
ttajmajer | 0:7d511a9bdaba | 143 | * |
ttajmajer | 0:7d511a9bdaba | 144 | * @param sFamily Familycode (a..f) |
ttajmajer | 0:7d511a9bdaba | 145 | * @param nGroup Number of group (1..4) |
ttajmajer | 0:7d511a9bdaba | 146 | * @param nDevice Number of device (1..4) |
ttajmajer | 0:7d511a9bdaba | 147 | */ |
ttajmajer | 0:7d511a9bdaba | 148 | void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) { |
ttajmajer | 0:7d511a9bdaba | 149 | this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) ); |
ttajmajer | 0:7d511a9bdaba | 150 | } |
ttajmajer | 0:7d511a9bdaba | 151 | |
ttajmajer | 0:7d511a9bdaba | 152 | /** |
ttajmajer | 0:7d511a9bdaba | 153 | * Switch a remote switch off (Type C Intertechno) |
ttajmajer | 0:7d511a9bdaba | 154 | * |
ttajmajer | 0:7d511a9bdaba | 155 | * @param sFamily Familycode (a..f) |
ttajmajer | 0:7d511a9bdaba | 156 | * @param nGroup Number of group (1..4) |
ttajmajer | 0:7d511a9bdaba | 157 | * @param nDevice Number of device (1..4) |
ttajmajer | 0:7d511a9bdaba | 158 | */ |
ttajmajer | 0:7d511a9bdaba | 159 | void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) { |
ttajmajer | 0:7d511a9bdaba | 160 | this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) ); |
ttajmajer | 0:7d511a9bdaba | 161 | } |
ttajmajer | 0:7d511a9bdaba | 162 | |
ttajmajer | 0:7d511a9bdaba | 163 | /** |
ttajmajer | 0:7d511a9bdaba | 164 | * Switch a remote switch on (Type B with two rotary/sliding switches) |
ttajmajer | 0:7d511a9bdaba | 165 | * |
ttajmajer | 0:7d511a9bdaba | 166 | * @param nAddressCode Number of the switch group (1..4) |
ttajmajer | 0:7d511a9bdaba | 167 | * @param nChannelCode Number of the switch itself (1..4) |
ttajmajer | 0:7d511a9bdaba | 168 | */ |
ttajmajer | 0:7d511a9bdaba | 169 | void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { |
ttajmajer | 0:7d511a9bdaba | 170 | this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); |
ttajmajer | 0:7d511a9bdaba | 171 | } |
ttajmajer | 0:7d511a9bdaba | 172 | |
ttajmajer | 0:7d511a9bdaba | 173 | /** |
ttajmajer | 0:7d511a9bdaba | 174 | * Switch a remote switch off (Type B with two rotary/sliding switches) |
ttajmajer | 0:7d511a9bdaba | 175 | * |
ttajmajer | 0:7d511a9bdaba | 176 | * @param nAddressCode Number of the switch group (1..4) |
ttajmajer | 0:7d511a9bdaba | 177 | * @param nChannelCode Number of the switch itself (1..4) |
ttajmajer | 0:7d511a9bdaba | 178 | */ |
ttajmajer | 0:7d511a9bdaba | 179 | void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { |
ttajmajer | 0:7d511a9bdaba | 180 | this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); |
ttajmajer | 0:7d511a9bdaba | 181 | } |
ttajmajer | 0:7d511a9bdaba | 182 | |
ttajmajer | 0:7d511a9bdaba | 183 | /** |
ttajmajer | 0:7d511a9bdaba | 184 | * Deprecated, use switchOn(const char* sGroup, const char* sDevice) instead! |
ttajmajer | 0:7d511a9bdaba | 185 | * Switch a remote switch on (Type A with 10 pole DIP switches) |
ttajmajer | 0:7d511a9bdaba | 186 | * |
ttajmajer | 0:7d511a9bdaba | 187 | * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 188 | * @param nChannelCode Number of the switch itself (1..5) |
ttajmajer | 0:7d511a9bdaba | 189 | */ |
ttajmajer | 0:7d511a9bdaba | 190 | void RCSwitch::switchOn(const char* sGroup, int nChannel) { |
ttajmajer | 0:7d511a9bdaba | 191 | const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; |
ttajmajer | 0:7d511a9bdaba | 192 | this->switchOn(sGroup, code[nChannel]); |
ttajmajer | 0:7d511a9bdaba | 193 | } |
ttajmajer | 0:7d511a9bdaba | 194 | |
ttajmajer | 0:7d511a9bdaba | 195 | /** |
ttajmajer | 0:7d511a9bdaba | 196 | * Deprecated, use switchOff(const char* sGroup, const char* sDevice) instead! |
ttajmajer | 0:7d511a9bdaba | 197 | * Switch a remote switch off (Type A with 10 pole DIP switches) |
ttajmajer | 0:7d511a9bdaba | 198 | * |
ttajmajer | 0:7d511a9bdaba | 199 | * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 200 | * @param nChannelCode Number of the switch itself (1..5) |
ttajmajer | 0:7d511a9bdaba | 201 | */ |
ttajmajer | 0:7d511a9bdaba | 202 | void RCSwitch::switchOff(const char* sGroup, int nChannel) { |
ttajmajer | 0:7d511a9bdaba | 203 | const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; |
ttajmajer | 0:7d511a9bdaba | 204 | this->switchOff(sGroup, code[nChannel]); |
ttajmajer | 0:7d511a9bdaba | 205 | } |
ttajmajer | 0:7d511a9bdaba | 206 | |
ttajmajer | 0:7d511a9bdaba | 207 | /** |
ttajmajer | 0:7d511a9bdaba | 208 | * Switch a remote switch on (Type A with 10 pole DIP switches) |
ttajmajer | 0:7d511a9bdaba | 209 | * |
ttajmajer | 0:7d511a9bdaba | 210 | * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 211 | * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 212 | */ |
ttajmajer | 0:7d511a9bdaba | 213 | void RCSwitch::switchOn(const char* sGroup, const char* sDevice) { |
ttajmajer | 0:7d511a9bdaba | 214 | this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) ); |
ttajmajer | 0:7d511a9bdaba | 215 | } |
ttajmajer | 0:7d511a9bdaba | 216 | |
ttajmajer | 0:7d511a9bdaba | 217 | /** |
ttajmajer | 0:7d511a9bdaba | 218 | * Switch a remote switch off (Type A with 10 pole DIP switches) |
ttajmajer | 0:7d511a9bdaba | 219 | * |
ttajmajer | 0:7d511a9bdaba | 220 | * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 221 | * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") |
ttajmajer | 0:7d511a9bdaba | 222 | */ |
ttajmajer | 0:7d511a9bdaba | 223 | void RCSwitch::switchOff(const char* sGroup, const char* sDevice) { |
ttajmajer | 0:7d511a9bdaba | 224 | this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) ); |
ttajmajer | 0:7d511a9bdaba | 225 | } |
ttajmajer | 0:7d511a9bdaba | 226 | |
ttajmajer | 0:7d511a9bdaba | 227 | |
ttajmajer | 0:7d511a9bdaba | 228 | /** |
ttajmajer | 0:7d511a9bdaba | 229 | * Returns a char[13], representing the code word to be send. |
ttajmajer | 0:7d511a9bdaba | 230 | * |
ttajmajer | 0:7d511a9bdaba | 231 | */ |
ttajmajer | 0:7d511a9bdaba | 232 | char* RCSwitch::getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus) { |
ttajmajer | 0:7d511a9bdaba | 233 | static char sReturn[13]; |
ttajmajer | 0:7d511a9bdaba | 234 | int nReturnPos = 0; |
ttajmajer | 0:7d511a9bdaba | 235 | |
ttajmajer | 0:7d511a9bdaba | 236 | for (int i = 0; i < 5; i++) { |
ttajmajer | 0:7d511a9bdaba | 237 | sReturn[nReturnPos++] = (sGroup[i] == '0') ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 238 | } |
ttajmajer | 0:7d511a9bdaba | 239 | |
ttajmajer | 0:7d511a9bdaba | 240 | for (int i = 0; i < 5; i++) { |
ttajmajer | 0:7d511a9bdaba | 241 | sReturn[nReturnPos++] = (sDevice[i] == '0') ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 242 | } |
ttajmajer | 0:7d511a9bdaba | 243 | |
ttajmajer | 0:7d511a9bdaba | 244 | sReturn[nReturnPos++] = bStatus ? '0' : 'F'; |
ttajmajer | 0:7d511a9bdaba | 245 | sReturn[nReturnPos++] = bStatus ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 246 | |
ttajmajer | 0:7d511a9bdaba | 247 | sReturn[nReturnPos] = '\0'; |
ttajmajer | 0:7d511a9bdaba | 248 | return sReturn; |
ttajmajer | 0:7d511a9bdaba | 249 | } |
ttajmajer | 0:7d511a9bdaba | 250 | |
ttajmajer | 0:7d511a9bdaba | 251 | /** |
ttajmajer | 0:7d511a9bdaba | 252 | * Encoding for type B switches with two rotary/sliding switches. |
ttajmajer | 0:7d511a9bdaba | 253 | * |
ttajmajer | 0:7d511a9bdaba | 254 | * The code word is a tristate word and with following bit pattern: |
ttajmajer | 0:7d511a9bdaba | 255 | * |
ttajmajer | 0:7d511a9bdaba | 256 | * +-----------------------------+-----------------------------+----------+------------+ |
ttajmajer | 0:7d511a9bdaba | 257 | * | 4 bits address | 4 bits address | 3 bits | 1 bit | |
ttajmajer | 0:7d511a9bdaba | 258 | * | switch group | switch number | not used | on / off | |
ttajmajer | 0:7d511a9bdaba | 259 | * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | FFF | on=F off=0 | |
ttajmajer | 0:7d511a9bdaba | 260 | * +-----------------------------+-----------------------------+----------+------------+ |
ttajmajer | 0:7d511a9bdaba | 261 | * |
ttajmajer | 0:7d511a9bdaba | 262 | * @param nAddressCode Number of the switch group (1..4) |
ttajmajer | 0:7d511a9bdaba | 263 | * @param nChannelCode Number of the switch itself (1..4) |
ttajmajer | 0:7d511a9bdaba | 264 | * @param bStatus Whether to switch on (true) or off (false) |
ttajmajer | 0:7d511a9bdaba | 265 | * |
ttajmajer | 0:7d511a9bdaba | 266 | * @return char[13], representing a tristate code word of length 12 |
ttajmajer | 0:7d511a9bdaba | 267 | */ |
ttajmajer | 0:7d511a9bdaba | 268 | char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) { |
ttajmajer | 0:7d511a9bdaba | 269 | static char sReturn[13]; |
ttajmajer | 0:7d511a9bdaba | 270 | int nReturnPos = 0; |
ttajmajer | 0:7d511a9bdaba | 271 | |
ttajmajer | 0:7d511a9bdaba | 272 | if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { |
ttajmajer | 0:7d511a9bdaba | 273 | return 0; |
ttajmajer | 0:7d511a9bdaba | 274 | } |
ttajmajer | 0:7d511a9bdaba | 275 | |
ttajmajer | 0:7d511a9bdaba | 276 | for (int i = 1; i <= 4; i++) { |
ttajmajer | 0:7d511a9bdaba | 277 | sReturn[nReturnPos++] = (nAddressCode == i) ? '0' : 'F'; |
ttajmajer | 0:7d511a9bdaba | 278 | } |
ttajmajer | 0:7d511a9bdaba | 279 | |
ttajmajer | 0:7d511a9bdaba | 280 | for (int i = 1; i <= 4; i++) { |
ttajmajer | 0:7d511a9bdaba | 281 | sReturn[nReturnPos++] = (nChannelCode == i) ? '0' : 'F'; |
ttajmajer | 0:7d511a9bdaba | 282 | } |
ttajmajer | 0:7d511a9bdaba | 283 | |
ttajmajer | 0:7d511a9bdaba | 284 | sReturn[nReturnPos++] = 'F'; |
ttajmajer | 0:7d511a9bdaba | 285 | sReturn[nReturnPos++] = 'F'; |
ttajmajer | 0:7d511a9bdaba | 286 | sReturn[nReturnPos++] = 'F'; |
ttajmajer | 0:7d511a9bdaba | 287 | |
ttajmajer | 0:7d511a9bdaba | 288 | sReturn[nReturnPos++] = bStatus ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 289 | |
ttajmajer | 0:7d511a9bdaba | 290 | sReturn[nReturnPos] = '\0'; |
ttajmajer | 0:7d511a9bdaba | 291 | return sReturn; |
ttajmajer | 0:7d511a9bdaba | 292 | } |
ttajmajer | 0:7d511a9bdaba | 293 | |
ttajmajer | 0:7d511a9bdaba | 294 | /** |
ttajmajer | 0:7d511a9bdaba | 295 | * Like getCodeWord (Type C = Intertechno) |
ttajmajer | 0:7d511a9bdaba | 296 | */ |
ttajmajer | 0:7d511a9bdaba | 297 | char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) { |
ttajmajer | 0:7d511a9bdaba | 298 | static char sReturn[13]; |
ttajmajer | 0:7d511a9bdaba | 299 | int nReturnPos = 0; |
ttajmajer | 0:7d511a9bdaba | 300 | |
ttajmajer | 0:7d511a9bdaba | 301 | int nFamily = (int)sFamily - 'a'; |
ttajmajer | 0:7d511a9bdaba | 302 | if ( nFamily < 0 || nFamily > 15 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { |
ttajmajer | 0:7d511a9bdaba | 303 | return 0; |
ttajmajer | 0:7d511a9bdaba | 304 | } |
ttajmajer | 0:7d511a9bdaba | 305 | |
ttajmajer | 0:7d511a9bdaba | 306 | // encode the family into four bits |
ttajmajer | 0:7d511a9bdaba | 307 | sReturn[nReturnPos++] = (nFamily & 1) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 308 | sReturn[nReturnPos++] = (nFamily & 2) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 309 | sReturn[nReturnPos++] = (nFamily & 4) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 310 | sReturn[nReturnPos++] = (nFamily & 8) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 311 | |
ttajmajer | 0:7d511a9bdaba | 312 | // encode the device and group |
ttajmajer | 0:7d511a9bdaba | 313 | sReturn[nReturnPos++] = ((nDevice-1) & 1) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 314 | sReturn[nReturnPos++] = ((nDevice-1) & 2) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 315 | sReturn[nReturnPos++] = ((nGroup-1) & 1) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 316 | sReturn[nReturnPos++] = ((nGroup-1) & 2) ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 317 | |
ttajmajer | 0:7d511a9bdaba | 318 | // encode the status code |
ttajmajer | 0:7d511a9bdaba | 319 | sReturn[nReturnPos++] = '0'; |
ttajmajer | 0:7d511a9bdaba | 320 | sReturn[nReturnPos++] = 'F'; |
ttajmajer | 0:7d511a9bdaba | 321 | sReturn[nReturnPos++] = 'F'; |
ttajmajer | 0:7d511a9bdaba | 322 | sReturn[nReturnPos++] = bStatus ? 'F' : '0'; |
ttajmajer | 0:7d511a9bdaba | 323 | |
ttajmajer | 0:7d511a9bdaba | 324 | sReturn[nReturnPos] = '\0'; |
ttajmajer | 0:7d511a9bdaba | 325 | return sReturn; |
ttajmajer | 0:7d511a9bdaba | 326 | } |
ttajmajer | 0:7d511a9bdaba | 327 | |
ttajmajer | 0:7d511a9bdaba | 328 | /** |
ttajmajer | 0:7d511a9bdaba | 329 | * Encoding for the REV Switch Type |
ttajmajer | 0:7d511a9bdaba | 330 | * |
ttajmajer | 0:7d511a9bdaba | 331 | * The code word is a tristate word and with following bit pattern: |
ttajmajer | 0:7d511a9bdaba | 332 | * |
ttajmajer | 0:7d511a9bdaba | 333 | * +-----------------------------+-------------------+----------+--------------+ |
ttajmajer | 0:7d511a9bdaba | 334 | * | 4 bits address | 3 bits address | 3 bits | 2 bits | |
ttajmajer | 0:7d511a9bdaba | 335 | * | switch group | device number | not used | on / off | |
ttajmajer | 0:7d511a9bdaba | 336 | * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FF 2=F0F 3=FF0 | 000 | on=10 off=01 | |
ttajmajer | 0:7d511a9bdaba | 337 | * +-----------------------------+-------------------+----------+--------------+ |
ttajmajer | 0:7d511a9bdaba | 338 | * |
ttajmajer | 0:7d511a9bdaba | 339 | * Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/ |
ttajmajer | 0:7d511a9bdaba | 340 | * |
ttajmajer | 0:7d511a9bdaba | 341 | * @param sGroup Name of the switch group (A..D, resp. a..d) |
ttajmajer | 0:7d511a9bdaba | 342 | * @param nDevice Number of the switch itself (1..3) |
ttajmajer | 0:7d511a9bdaba | 343 | * @param bStatus Whether to switch on (true) or off (false) |
ttajmajer | 0:7d511a9bdaba | 344 | * |
ttajmajer | 0:7d511a9bdaba | 345 | * @return char[13], representing a tristate code word of length 12 |
ttajmajer | 0:7d511a9bdaba | 346 | */ |
ttajmajer | 0:7d511a9bdaba | 347 | char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) { |
ttajmajer | 0:7d511a9bdaba | 348 | static char sReturn[13]; |
ttajmajer | 0:7d511a9bdaba | 349 | int nReturnPos = 0; |
ttajmajer | 0:7d511a9bdaba | 350 | |
ttajmajer | 0:7d511a9bdaba | 351 | // sGroup must be one of the letters in "abcdABCD" |
ttajmajer | 0:7d511a9bdaba | 352 | int nGroup = (sGroup >= 'a') ? (int)sGroup - 'a' : (int)sGroup - 'A'; |
ttajmajer | 0:7d511a9bdaba | 353 | if ( nGroup < 0 || nGroup > 3 || nDevice < 1 || nDevice > 3) { |
ttajmajer | 0:7d511a9bdaba | 354 | return 0; |
ttajmajer | 0:7d511a9bdaba | 355 | } |
ttajmajer | 0:7d511a9bdaba | 356 | |
ttajmajer | 0:7d511a9bdaba | 357 | for (int i = 0; i < 4; i++) { |
ttajmajer | 0:7d511a9bdaba | 358 | sReturn[nReturnPos++] = (nGroup == i) ? '1' : 'F'; |
ttajmajer | 0:7d511a9bdaba | 359 | } |
ttajmajer | 0:7d511a9bdaba | 360 | |
ttajmajer | 0:7d511a9bdaba | 361 | for (int i = 1; i <= 3; i++) { |
ttajmajer | 0:7d511a9bdaba | 362 | sReturn[nReturnPos++] = (nDevice == i) ? '1' : 'F'; |
ttajmajer | 0:7d511a9bdaba | 363 | } |
ttajmajer | 0:7d511a9bdaba | 364 | |
ttajmajer | 0:7d511a9bdaba | 365 | sReturn[nReturnPos++] = '0'; |
ttajmajer | 0:7d511a9bdaba | 366 | sReturn[nReturnPos++] = '0'; |
ttajmajer | 0:7d511a9bdaba | 367 | sReturn[nReturnPos++] = '0'; |
ttajmajer | 0:7d511a9bdaba | 368 | |
ttajmajer | 0:7d511a9bdaba | 369 | sReturn[nReturnPos++] = bStatus ? '1' : '0'; |
ttajmajer | 0:7d511a9bdaba | 370 | sReturn[nReturnPos++] = bStatus ? '0' : '1'; |
ttajmajer | 0:7d511a9bdaba | 371 | |
ttajmajer | 0:7d511a9bdaba | 372 | sReturn[nReturnPos] = '\0'; |
ttajmajer | 0:7d511a9bdaba | 373 | return sReturn; |
ttajmajer | 0:7d511a9bdaba | 374 | } |
ttajmajer | 0:7d511a9bdaba | 375 | |
ttajmajer | 0:7d511a9bdaba | 376 | /** |
ttajmajer | 0:7d511a9bdaba | 377 | * @param sCodeWord a tristate code word consisting of the letter 0, 1, F |
ttajmajer | 0:7d511a9bdaba | 378 | */ |
ttajmajer | 0:7d511a9bdaba | 379 | void RCSwitch::sendTriState(const char* sCodeWord) { |
ttajmajer | 0:7d511a9bdaba | 380 | // turn the tristate code word into the corresponding bit pattern, then send it |
ttajmajer | 0:7d511a9bdaba | 381 | unsigned long code = 0; |
ttajmajer | 0:7d511a9bdaba | 382 | unsigned int length = 0; |
ttajmajer | 0:7d511a9bdaba | 383 | for (const char* p = sCodeWord; *p; p++) { |
ttajmajer | 0:7d511a9bdaba | 384 | code <<= 2L; |
ttajmajer | 0:7d511a9bdaba | 385 | switch (*p) { |
ttajmajer | 0:7d511a9bdaba | 386 | case '0': |
ttajmajer | 0:7d511a9bdaba | 387 | // bit pattern 00 |
ttajmajer | 0:7d511a9bdaba | 388 | break; |
ttajmajer | 0:7d511a9bdaba | 389 | case 'F': |
ttajmajer | 0:7d511a9bdaba | 390 | // bit pattern 01 |
ttajmajer | 0:7d511a9bdaba | 391 | code |= 1L; |
ttajmajer | 0:7d511a9bdaba | 392 | break; |
ttajmajer | 0:7d511a9bdaba | 393 | case '1': |
ttajmajer | 0:7d511a9bdaba | 394 | // bit pattern 11 |
ttajmajer | 0:7d511a9bdaba | 395 | code |= 3L; |
ttajmajer | 0:7d511a9bdaba | 396 | break; |
ttajmajer | 0:7d511a9bdaba | 397 | } |
ttajmajer | 0:7d511a9bdaba | 398 | length += 2; |
ttajmajer | 0:7d511a9bdaba | 399 | } |
ttajmajer | 0:7d511a9bdaba | 400 | this->send(code, length); |
ttajmajer | 0:7d511a9bdaba | 401 | } |
ttajmajer | 0:7d511a9bdaba | 402 | |
ttajmajer | 0:7d511a9bdaba | 403 | /** |
ttajmajer | 0:7d511a9bdaba | 404 | * @param sCodeWord a binary code word consisting of the letter 0, 1 |
ttajmajer | 0:7d511a9bdaba | 405 | */ |
ttajmajer | 0:7d511a9bdaba | 406 | void RCSwitch::send(const char* sCodeWord) { |
ttajmajer | 0:7d511a9bdaba | 407 | // turn the tristate code word into the corresponding bit pattern, then send it |
ttajmajer | 0:7d511a9bdaba | 408 | unsigned long code = 0; |
ttajmajer | 0:7d511a9bdaba | 409 | unsigned int length = 0; |
ttajmajer | 0:7d511a9bdaba | 410 | for (const char* p = sCodeWord; *p; p++) { |
ttajmajer | 0:7d511a9bdaba | 411 | code <<= 1L; |
ttajmajer | 0:7d511a9bdaba | 412 | if (*p != '0') |
ttajmajer | 0:7d511a9bdaba | 413 | code |= 1L; |
ttajmajer | 0:7d511a9bdaba | 414 | length++; |
ttajmajer | 0:7d511a9bdaba | 415 | } |
ttajmajer | 0:7d511a9bdaba | 416 | this->send(code, length); |
ttajmajer | 0:7d511a9bdaba | 417 | } |
ttajmajer | 0:7d511a9bdaba | 418 | |
ttajmajer | 0:7d511a9bdaba | 419 | /** |
ttajmajer | 0:7d511a9bdaba | 420 | * Transmit the first 'length' bits of the integer 'code'. The |
ttajmajer | 0:7d511a9bdaba | 421 | * bits are sent from MSB to LSB, i.e., first the bit at position length-1, |
ttajmajer | 0:7d511a9bdaba | 422 | * then the bit at position length-2, and so on, till finally the bit at position 0. |
ttajmajer | 0:7d511a9bdaba | 423 | */ |
ttajmajer | 0:7d511a9bdaba | 424 | void RCSwitch::send(unsigned long code, unsigned int length) { |
ttajmajer | 0:7d511a9bdaba | 425 | if (this->nTransmitterPin == -1) |
ttajmajer | 0:7d511a9bdaba | 426 | return; |
ttajmajer | 0:7d511a9bdaba | 427 | |
ttajmajer | 0:7d511a9bdaba | 428 | |
ttajmajer | 0:7d511a9bdaba | 429 | |
ttajmajer | 0:7d511a9bdaba | 430 | for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) { |
ttajmajer | 0:7d511a9bdaba | 431 | for (int i = length-1; i >= 0; i--) { |
ttajmajer | 0:7d511a9bdaba | 432 | if (code & (1L << i)) |
ttajmajer | 0:7d511a9bdaba | 433 | this->transmit(protocol.one); |
ttajmajer | 0:7d511a9bdaba | 434 | else |
ttajmajer | 0:7d511a9bdaba | 435 | this->transmit(protocol.zero); |
ttajmajer | 0:7d511a9bdaba | 436 | } |
ttajmajer | 0:7d511a9bdaba | 437 | this->transmit(protocol.syncFactor); |
ttajmajer | 0:7d511a9bdaba | 438 | } |
ttajmajer | 0:7d511a9bdaba | 439 | |
ttajmajer | 0:7d511a9bdaba | 440 | |
ttajmajer | 0:7d511a9bdaba | 441 | } |
ttajmajer | 0:7d511a9bdaba | 442 | |
ttajmajer | 0:7d511a9bdaba | 443 | /** |
ttajmajer | 0:7d511a9bdaba | 444 | * Transmit a single high-low pulse. |
ttajmajer | 0:7d511a9bdaba | 445 | */ |
ttajmajer | 0:7d511a9bdaba | 446 | void RCSwitch::transmit(HighLow pulses) { |
ttajmajer | 0:7d511a9bdaba | 447 | uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH; |
ttajmajer | 0:7d511a9bdaba | 448 | uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW; |
ttajmajer | 0:7d511a9bdaba | 449 | |
ttajmajer | 0:7d511a9bdaba | 450 | _outpin.write(firstLogicLevel); |
ttajmajer | 0:7d511a9bdaba | 451 | wait_us( this->protocol.pulseLength * pulses.high); |
ttajmajer | 0:7d511a9bdaba | 452 | _outpin.write(secondLogicLevel); |
ttajmajer | 0:7d511a9bdaba | 453 | wait_us( this->protocol.pulseLength * pulses.low); |
ttajmajer | 0:7d511a9bdaba | 454 | |
ttajmajer | 0:7d511a9bdaba | 455 | } |