RC outlet switch for mbed based on: https://github.com/sui77/rc-switch

Dependencies:   mbed

Committer:
ttajmajer
Date:
Mon Jan 02 13:41:03 2017 +0000
Revision:
0:7d511a9bdaba
RC switch

Who changed what in which revision?

UserRevisionLine numberNew 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 }