Library to switch 433MHz remote controlled sockets.
Embed:
(wiki syntax)
Show/hide line numbers
RCSwitch.cpp
00001 /* 00002 RCSwitch - Ported from the Arduino libary for remote control outlet switches 00003 Copyright (c) 2011 Suat Özgür. All right reserved. 00004 00005 Contributors: 00006 - Andre Koehler / info(at)tomate-online(dot)de 00007 - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com 00008 - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46 00009 - Dominik Fischer / dom_fischer(at)web(dot)de 00010 - Frank Oltmanns / <first name>.<last name>(at)gmail(dot)com 00011 - Chris Dick / Porting to mbed 00012 00013 Project home: http://code.google.com/p/rc-switch/ 00014 00015 This library is free software; you can redistribute it and/or 00016 modify it under the terms of the GNU Lesser General Public 00017 License as published by the Free Software Foundation; either 00018 version 2.1 of the License, or (at your option) any later version. 00019 00020 This library is distributed in the hope that it will be useful, 00021 but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 Lesser General Public License for more details. 00024 00025 You should have received a copy of the GNU Lesser General Public 00026 License along with this library; if not, write to the Free Software 00027 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 */ 00029 #include "RCSwitch.h " 00030 00031 unsigned long RCSwitch::nReceivedValue = NULL; 00032 unsigned int RCSwitch::nReceivedBitlength = 0; 00033 unsigned int RCSwitch::nReceivedDelay = 0; 00034 unsigned int RCSwitch::nReceivedProtocol = 0; 00035 int RCSwitch::nReceiveTolerance = 60; 00036 unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; 00037 bool RCSwitch::TransmitEnablePin = false; 00038 bool RCSwitch::ReceiveEnabled = true; 00039 bool RCSwitch::TransmitEnable = true; 00040 00041 /** Class constructor. 00042 * The constructor assigns the specified pinout, attatches 00043 * an Interrupt to the receive pin. for the LPC1768 this must not 00044 * be pins 19 and 20. For the KL25Z, the pin must be on ports A or C 00045 * @param tx Transmitter pin of the RF module. 00046 * @param rx Receiver pin of the RF module. 00047 */ 00048 RCSwitch::RCSwitch(PinName tx, PinName rx) 00049 : 00050 _tx(DigitalOut(tx)), 00051 _rx(InterruptIn(rx)), 00052 _tx_en(NC) 00053 { 00054 nReceivedDelay = 0; 00055 RCSwitch::nReceivedValue = NULL; 00056 nReceivedBitlength = 0; 00057 ReceiveEnabled = true; 00058 TransmitEnable = true; 00059 TransmitEnablePin = false; 00060 setRepeatTransmit(15); 00061 setProtocol(1); 00062 setReceiveTolerance(60); 00063 _rx.rise(this, &RCSwitch::RCSwitchRxPinChange); 00064 _rx.fall(this, &RCSwitch::RCSwitchRxPinChange); 00065 timer.start(); 00066 } 00067 00068 /** Class constructor. 00069 * The constructor assigns the specified pinout, attatches 00070 * an Interrupt to the receive pin. for the LPC1768 this must not 00071 * be pins 19 and 20. For the KL25Z, the pin must be on ports A or C 00072 * @param tx Transmitter pin of the RF module. 00073 * @param rx Receiver pin of the RF module. 00074 * @param tx_en Enable pin of the transmitter 00075 */ 00076 RCSwitch::RCSwitch(PinName tx, PinName rx, PinName tx_en) 00077 : 00078 _tx(DigitalOut(tx)), 00079 _rx(InterruptIn(rx)), 00080 _tx_en(DigitalOut(tx_en)) 00081 { 00082 nReceivedDelay = 0; 00083 RCSwitch::nReceivedValue = NULL; 00084 nReceivedBitlength = 0; 00085 ReceiveEnabled = true; 00086 TransmitEnable = false; 00087 TransmitEnablePin = true; 00088 setRepeatTransmit(15); 00089 setProtocol(1); 00090 setReceiveTolerance(60); 00091 _rx.rise(this, &RCSwitch::RCSwitchRxPinChange); 00092 _rx.fall(this, &RCSwitch::RCSwitchRxPinChange); 00093 timer.start(); 00094 00095 } 00096 00097 /** 00098 * Set protocol to be used in transmission 00099 * @param nProtocol Protocol type ot transmit 00100 */ 00101 void RCSwitch::setProtocol(int nProtocol) { 00102 this->nProtocol = nProtocol; 00103 if (nProtocol == 1){ 00104 this->setPulseLength(350); 00105 } 00106 else if (nProtocol == 2) { 00107 this->setPulseLength(650); 00108 } 00109 else if (nProtocol == 3) { 00110 this->setPulseLength(100); 00111 } 00112 } 00113 00114 /** 00115 * Set protocol to be used in transmission 00116 * @param nProtocol Protocol type ot transmit 00117 * @param nPulseLength Length of each pulse 00118 */ 00119 void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { 00120 this->nProtocol = nProtocol; 00121 this->setPulseLength(nPulseLength); 00122 } 00123 00124 00125 /** 00126 * Set pulse length in micro seconds 00127 * @param nPulseLength the Length of the pulse 00128 */ 00129 void RCSwitch::setPulseLength(int nPulseLength) { 00130 this->nPulseLength = nPulseLength; 00131 } 00132 00133 /** 00134 * Set number of times to repeat transmission 00135 * @param nRepeat Number of repeats 00136 */ 00137 void RCSwitch::setRepeatTransmit(int nRepeatTransmit) { 00138 this->nRepeatTransmit = nRepeatTransmit; 00139 } 00140 00141 /** 00142 * Set receive tolerance 00143 * @param nPercent Percentage tolerance of the receiver 00144 */ 00145 void RCSwitch::setReceiveTolerance(int nPercent) { 00146 RCSwitch::nReceiveTolerance = nPercent; 00147 } 00148 00149 00150 /** 00151 * Enable the transmitter 00152 */ 00153 void RCSwitch::enableTransmit() { 00154 if (TransmitEnablePin == true) 00155 { 00156 _tx_en = true; 00157 } 00158 TransmitEnable = true; 00159 } 00160 00161 /** 00162 * Disable the transmitter 00163 */ 00164 void RCSwitch::disableTransmit() { 00165 if (TransmitEnablePin == true) 00166 { 00167 _tx_en = false; 00168 } 00169 TransmitEnable = false; 00170 } 00171 00172 /** 00173 * Switch a remote switch on (Type D REV) 00174 * 00175 * @param sGroup Code of the switch group (A,B,C,D) 00176 * @param nDevice Number of the switch itself (1..3) 00177 */ 00178 void RCSwitch::switchOn(char sGroup, int nDevice) { 00179 this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) ); 00180 } 00181 00182 /** 00183 * Switch a remote switch off (Type D REV) 00184 * 00185 * @param sGroup Code of the switch group (A,B,C,D) 00186 * @param nDevice Number of the switch itself (1..3) 00187 */ 00188 void RCSwitch::switchOff(char sGroup, int nDevice) { 00189 this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) ); 00190 } 00191 00192 /** 00193 * Switch a remote switch on (Type C Intertechno) 00194 * 00195 * @param sFamily Familycode (a..f) 00196 * @param nGroup Number of group (1..4) 00197 * @param nDevice Number of device (1..4) 00198 */ 00199 void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) { 00200 this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) ); 00201 } 00202 00203 /** 00204 * Switch a remote switch off (Type C Intertechno) 00205 * 00206 * @param sFamily Familycode (a..f) 00207 * @param nGroup Number of group (1..4) 00208 * @param nDevice Number of device (1..4) 00209 */ 00210 void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) { 00211 this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) ); 00212 } 00213 00214 /** 00215 * Switch a remote switch on (Type B with two rotary/sliding switches) 00216 * 00217 * @param nAddressCode Number of the switch group (1..4) 00218 * @param nChannelCode Number of the switch itself (1..4) 00219 */ 00220 void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { 00221 this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); 00222 } 00223 00224 /** 00225 * Switch a remote switch off (Type B with two rotary/sliding switches) 00226 * 00227 * @param nAddressCode Number of the switch group (1..4) 00228 * @param nChannelCode Number of the switch itself (1..4) 00229 */ 00230 void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { 00231 this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); 00232 } 00233 00234 /** 00235 * Deprecated, use switchOn(char* sGroup, char* sDevice) instead! 00236 * Switch a remote switch on (Type A with 10 pole DIP switches) 00237 * 00238 * @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") 00239 * @param nChannelCode Number of the switch itself (1..5) 00240 */ 00241 void RCSwitch::switchOn(char* sGroup, int nChannel) { 00242 char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; 00243 this->switchOn(sGroup, code[nChannel]); 00244 } 00245 00246 /** 00247 * Deprecated, use switchOff(char* sGroup, char* sDevice) instead! 00248 * Switch a remote switch off (Type A with 10 pole DIP switches) 00249 * 00250 * @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") 00251 * @param nChannelCode Number of the switch itself (1..5) 00252 */ 00253 void RCSwitch::switchOff(char* sGroup, int nChannel) { 00254 char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; 00255 this->switchOff(sGroup, code[nChannel]); 00256 } 00257 00258 /** 00259 * Switch a remote switch on (Type A with 10 pole DIP switches) 00260 * 00261 * @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") 00262 * @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") 00263 */ 00264 void RCSwitch::switchOn(char* sGroup, char* sDevice) { 00265 this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) ); 00266 } 00267 00268 /** 00269 * Switch a remote switch off (Type A with 10 pole DIP switches) 00270 * 00271 * @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") 00272 * @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") 00273 */ 00274 void RCSwitch::switchOff(char* sGroup, char* sDevice) { 00275 this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) ); 00276 } 00277 00278 /** 00279 * Returns a char[13], representing the Code Word to be send. 00280 * A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used. 00281 * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit) 00282 * 00283 * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ 00284 * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | 00285 * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | 00286 * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ 00287 * 00288 * @param nAddressCode Number of the switch group (1..4) 00289 * @param nChannelCode Number of the switch itself (1..4) 00290 * @param bStatus Wether to switch on (true) or off (false) 00291 * 00292 * @return char[13] 00293 */ 00294 char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) { 00295 int nReturnPos = 0; 00296 static char sReturn[13]; 00297 00298 char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; 00299 if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { 00300 return '\0'; 00301 } 00302 for (int i = 0; i<4; i++) { 00303 sReturn[nReturnPos++] = code[nAddressCode][i]; 00304 } 00305 00306 for (int i = 0; i<4; i++) { 00307 sReturn[nReturnPos++] = code[nChannelCode][i]; 00308 } 00309 00310 sReturn[nReturnPos++] = 'F'; 00311 sReturn[nReturnPos++] = 'F'; 00312 sReturn[nReturnPos++] = 'F'; 00313 00314 if (bStatus) { 00315 sReturn[nReturnPos++] = 'F'; 00316 } else { 00317 sReturn[nReturnPos++] = '0'; 00318 } 00319 00320 sReturn[nReturnPos] = '\0'; 00321 00322 return sReturn; 00323 } 00324 00325 /** 00326 * Returns a char[13], representing the Code Word to be send. 00327 * 00328 * getCodeWordA(char*, char*) 00329 * 00330 */ 00331 char* RCSwitch::getCodeWordA(char* sGroup, char* sDevice, bool bOn) { 00332 static char sDipSwitches[13]; 00333 int i = 0; 00334 int j = 0; 00335 00336 for (i=0; i < 5; i++) { 00337 if (sGroup[i] == '0') { 00338 sDipSwitches[j++] = 'F'; 00339 } else { 00340 sDipSwitches[j++] = '0'; 00341 } 00342 } 00343 00344 for (i=0; i < 5; i++) { 00345 if (sDevice[i] == '0') { 00346 sDipSwitches[j++] = 'F'; 00347 } else { 00348 sDipSwitches[j++] = '0'; 00349 } 00350 } 00351 00352 if ( bOn ) { 00353 sDipSwitches[j++] = '0'; 00354 sDipSwitches[j++] = 'F'; 00355 } else { 00356 sDipSwitches[j++] = 'F'; 00357 sDipSwitches[j++] = '0'; 00358 } 00359 00360 sDipSwitches[j] = '\0'; 00361 00362 return sDipSwitches; 00363 } 00364 00365 /** 00366 * Like getCodeWord (Type C = Intertechno) 00367 */ 00368 char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) { 00369 static char sReturn[13]; 00370 int nReturnPos = 0; 00371 00372 if ( (char)sFamily < 97 || (char)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { 00373 return '\0'; 00374 } 00375 00376 char* sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); 00377 char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; 00378 for (int i = 0; i<4; i++) { 00379 sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i]; 00380 } 00381 for (int i = 0; i<4; i++) { 00382 sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); 00383 } 00384 sReturn[nReturnPos++] = '0'; 00385 sReturn[nReturnPos++] = 'F'; 00386 sReturn[nReturnPos++] = 'F'; 00387 if (bStatus) { 00388 sReturn[nReturnPos++] = 'F'; 00389 } else { 00390 sReturn[nReturnPos++] = '0'; 00391 } 00392 sReturn[nReturnPos] = '\0'; 00393 return sReturn; 00394 } 00395 00396 /** 00397 * Decoding for the REV Switch Type 00398 * 00399 * Returns a char[13], representing the Tristate to be send. 00400 * A Code Word consists of 7 address bits and 5 command data bits. 00401 * A Code Bit can have 3 different states: "F" (floating), "0" (low), "1" (high) 00402 * 00403 * +-------------------------------+--------------------------------+-----------------------+ 00404 * | 4 bits address (switch group) | 3 bits address (device number) | 5 bits (command data) | 00405 * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | on=00010 off=00001 | 00406 * +-------------------------------+--------------------------------+-----------------------+ 00407 * 00408 * Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/ 00409 * 00410 * @param sGroup Name of the switch group (A..D, resp. a..d) 00411 * @param nDevice Number of the switch itself (1..3) 00412 * @param bStatus Wether to switch on (true) or off (false) 00413 * 00414 * @return char[13] 00415 */ 00416 00417 char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus){ 00418 static char sReturn[13]; 00419 int nReturnPos = 0; 00420 00421 // Building 4 bits address 00422 // (Potential problem if dec2binWcharfill not returning correct string) 00423 char *sGroupCode; 00424 switch(sGroup){ 00425 case 'a': 00426 case 'A': 00427 sGroupCode = dec2binWcharfill(8, 4, 'F'); break; 00428 case 'b': 00429 case 'B': 00430 sGroupCode = dec2binWcharfill(4, 4, 'F'); break; 00431 case 'c': 00432 case 'C': 00433 sGroupCode = dec2binWcharfill(2, 4, 'F'); break; 00434 case 'd': 00435 case 'D': 00436 sGroupCode = dec2binWcharfill(1, 4, 'F'); break; 00437 default: 00438 return '\0'; 00439 } 00440 00441 for (int i = 0; i<4; i++) 00442 { 00443 sReturn[nReturnPos++] = sGroupCode[i]; 00444 } 00445 00446 00447 // Building 3 bits address 00448 // (Potential problem if dec2binWcharfill not returning correct string) 00449 char *sDevice; 00450 switch(nDevice) { 00451 case 1: 00452 sDevice = dec2binWcharfill(4, 3, 'F'); break; 00453 case 2: 00454 sDevice = dec2binWcharfill(2, 3, 'F'); break; 00455 case 3: 00456 sDevice = dec2binWcharfill(1, 3, 'F'); break; 00457 default: 00458 return '\0'; 00459 } 00460 00461 for (int i = 0; i<3; i++) 00462 sReturn[nReturnPos++] = sDevice[i]; 00463 00464 // fill up rest with zeros 00465 for (int i = 0; i<5; i++) 00466 sReturn[nReturnPos++] = '0'; 00467 00468 // encode on or off 00469 if (bStatus) 00470 sReturn[10] = '1'; 00471 else 00472 sReturn[11] = '1'; 00473 00474 // last position terminate string 00475 sReturn[12] = '\0'; 00476 return sReturn; 00477 00478 } 00479 00480 /** 00481 * Sends a codeword 00482 * @param sCodeWord Codeword to be sent 00483 */ 00484 void RCSwitch::sendTriState(char* sCodeWord) { 00485 for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) { 00486 int i = 0; 00487 while (sCodeWord[i] != '\0') { 00488 switch(sCodeWord[i]) { 00489 case '0': 00490 this->sendT0(); 00491 break; 00492 case 'F': 00493 this->sendTF(); 00494 break; 00495 case '1': 00496 this->sendT1(); 00497 break; 00498 } 00499 i++; 00500 } 00501 this->sendSync(); 00502 } 00503 } 00504 00505 void RCSwitch::send(unsigned long Code, unsigned int length) { 00506 this->send( this->dec2binWzerofill(Code, length) ); 00507 } 00508 00509 void RCSwitch::send(char* sCodeWord) { 00510 for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) { 00511 int i = 0; 00512 while (sCodeWord[i] != '\0') { 00513 switch(sCodeWord[i]) { 00514 case '0': 00515 this->send0(); 00516 break; 00517 case '1': 00518 this->send1(); 00519 break; 00520 } 00521 i++; 00522 } 00523 this->sendSync(); 00524 } 00525 } 00526 00527 void RCSwitch::transmit(int nHighPulses, int nLowPulses) { 00528 bool disabled_Receive = false; 00529 00530 if (TransmitEnable) { 00531 if (ReceiveEnabled) { 00532 this->disableReceive(); 00533 disabled_Receive = true; 00534 } 00535 _tx = 1; 00536 wait_us(this->nPulseLength * nHighPulses); 00537 _tx = 0; 00538 wait_us(this->nPulseLength *nLowPulses); 00539 if(disabled_Receive){ 00540 this->enableReceive(); 00541 } 00542 } 00543 } 00544 /** 00545 * Sends a "0" Bit 00546 * _ 00547 * Waveform Protocol 1: | |___ 00548 * _ 00549 * Waveform Protocol 2: | |__ 00550 */ 00551 void RCSwitch::send0() { 00552 if (this->nProtocol == 1){ 00553 this->transmit(1,3); 00554 } 00555 else if (this->nProtocol == 2) { 00556 this->transmit(1,2); 00557 } 00558 else if (this->nProtocol == 3) { 00559 this->transmit(4,11); 00560 } 00561 } 00562 00563 /** 00564 * Sends a "1" Bit 00565 * ___ 00566 * Waveform Protocol 1: | |_ 00567 * __ 00568 * Waveform Protocol 2: | |_ 00569 */ 00570 void RCSwitch::send1() { 00571 if (this->nProtocol == 1){ 00572 this->transmit(3,1); 00573 } 00574 else if (this->nProtocol == 2) { 00575 this->transmit(2,1); 00576 } 00577 else if (this->nProtocol == 3) { 00578 this->transmit(9,6); 00579 } 00580 } 00581 00582 00583 /** 00584 * Sends a Tri-State "0" Bit 00585 * _ _ 00586 * Waveform: | |___| |___ 00587 */ 00588 void RCSwitch::sendT0() { 00589 this->transmit(1,3); 00590 this->transmit(1,3); 00591 } 00592 00593 /** 00594 * Sends a Tri-State "1" Bit 00595 * ___ ___ 00596 * Waveform: | |_| |_ 00597 */ 00598 void RCSwitch::sendT1() { 00599 this->transmit(3,1); 00600 this->transmit(3,1); 00601 } 00602 00603 /** 00604 * Sends a Tri-State "F" Bit 00605 * _ ___ 00606 * Waveform: | |___| |_ 00607 */ 00608 void RCSwitch::sendTF() { 00609 this->transmit(1,3); 00610 this->transmit(3,1); 00611 } 00612 00613 /** 00614 * Sends a "Sync" Bit 00615 * _ 00616 * Waveform Protocol 1: | |_______________________________ 00617 * _ 00618 * Waveform Protocol 2: | |__________ 00619 */ 00620 void RCSwitch::sendSync() { 00621 00622 if (this->nProtocol == 1){ 00623 this->transmit(1,31); 00624 } 00625 else if (this->nProtocol == 2) { 00626 this->transmit(1,10); 00627 } 00628 else if (this->nProtocol == 3) { 00629 this->transmit(1,71); 00630 } 00631 } 00632 00633 /** 00634 * Enable receiving data 00635 */ 00636 void RCSwitch::enableReceive() { 00637 RCSwitch::nReceivedValue = NULL; 00638 RCSwitch::nReceivedBitlength = NULL; 00639 _rx.enable_irq(); 00640 ReceiveEnabled = true; 00641 } 00642 00643 /** 00644 * Disable receiving data This disables the interrupt 00645 * which may disable the port 00646 */ 00647 void RCSwitch::disableReceive() { 00648 _rx.disable_irq(); 00649 ReceiveEnabled = false; 00650 } 00651 00652 bool RCSwitch::available() { 00653 return RCSwitch::nReceivedValue != NULL; 00654 } 00655 00656 void RCSwitch::resetAvailable() { 00657 RCSwitch::nReceivedValue = NULL; 00658 } 00659 00660 unsigned long RCSwitch::getReceivedValue() { 00661 return RCSwitch::nReceivedValue; 00662 } 00663 00664 unsigned int RCSwitch::getReceivedBitlength() { 00665 return RCSwitch::nReceivedBitlength; 00666 } 00667 00668 unsigned int RCSwitch::getReceivedDelay() { 00669 return nReceivedDelay; 00670 } 00671 00672 unsigned int RCSwitch::getReceivedProtocol() { 00673 return RCSwitch::nReceivedProtocol; 00674 } 00675 00676 unsigned int* RCSwitch::getReceivedRawdata() { 00677 return RCSwitch::timings; 00678 } 00679 00680 /** 00681 * 00682 */ 00683 bool RCSwitch::receiveProtocol1(unsigned int changeCount){ 00684 00685 unsigned long code = 0; 00686 unsigned long delay = RCSwitch::timings[0] / 31; 00687 unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; 00688 00689 for (int i = 1; i<changeCount ; i=i+2) { 00690 00691 if (RCSwitch::timings[i] > delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*3-delayTolerance && RCSwitch::timings[i+1] < delay*3+delayTolerance) { 00692 code = code << 1; 00693 } else if (RCSwitch::timings[i] > delay*3-delayTolerance && RCSwitch::timings[i] < delay*3+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { 00694 code+=1; 00695 code = code << 1; 00696 } else { 00697 // Failed 00698 i = changeCount; 00699 code = 0; 00700 } 00701 } 00702 code = code >> 1; 00703 if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise 00704 RCSwitch::nReceivedValue = code; 00705 RCSwitch::nReceivedBitlength = changeCount / 2; 00706 nReceivedDelay = delay; 00707 RCSwitch::nReceivedProtocol = 1; 00708 } 00709 00710 if (code == 0){ 00711 return false; 00712 } 00713 return true; 00714 } 00715 00716 bool RCSwitch::receiveProtocol2(unsigned int changeCount){ 00717 00718 unsigned long code = 0; 00719 unsigned long delay = RCSwitch::timings[0] / 10; 00720 unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; 00721 00722 for (int i = 1; i<changeCount ; i=i+2) { 00723 00724 if (RCSwitch::timings[i] > delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*2-delayTolerance && RCSwitch::timings[i+1] < delay*2+delayTolerance) { 00725 code = code << 1; 00726 } else if (RCSwitch::timings[i] > delay*2-delayTolerance && RCSwitch::timings[i] < delay*2+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { 00727 code+=1; 00728 code = code << 1; 00729 } else { 00730 // Failed 00731 i = changeCount; 00732 code = 0; 00733 } 00734 } 00735 code = code >> 1; 00736 if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise 00737 RCSwitch::nReceivedValue = code; 00738 RCSwitch::nReceivedBitlength = changeCount / 2; 00739 nReceivedDelay = delay; 00740 RCSwitch::nReceivedProtocol = 2; 00741 } 00742 00743 if (code == 0){ 00744 return false; 00745 } 00746 return true; 00747 } 00748 00749 /** Protocol 3 is used by BL35P02. 00750 * 00751 */ 00752 bool RCSwitch::receiveProtocol3(unsigned int changeCount){ 00753 00754 unsigned long code = 0; 00755 unsigned long delay = RCSwitch::timings[0] / PROTOCOL3_SYNC_FACTOR; 00756 unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; 00757 00758 for (int i = 1; i<changeCount ; i=i+2) { 00759 00760 if (RCSwitch::timings[i] > delay*PROTOCOL3_0_HIGH_CYCLES - delayTolerance 00761 && RCSwitch::timings[i] < delay*PROTOCOL3_0_HIGH_CYCLES + delayTolerance 00762 && RCSwitch::timings[i+1] > delay*PROTOCOL3_0_LOW_CYCLES - delayTolerance 00763 && RCSwitch::timings[i+1] < delay*PROTOCOL3_0_LOW_CYCLES + delayTolerance) { 00764 code = code << 1; 00765 } else if (RCSwitch::timings[i] > delay*PROTOCOL3_1_HIGH_CYCLES - delayTolerance 00766 && RCSwitch::timings[i] < delay*PROTOCOL3_1_HIGH_CYCLES + delayTolerance 00767 && RCSwitch::timings[i+1] > delay*PROTOCOL3_1_LOW_CYCLES - delayTolerance 00768 && RCSwitch::timings[i+1] < delay*PROTOCOL3_1_LOW_CYCLES + delayTolerance) { 00769 code+=1; 00770 code = code << 1; 00771 } else { 00772 // Failed 00773 i = changeCount; 00774 code = 0; 00775 } 00776 } 00777 code = code >> 1; 00778 if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise 00779 RCSwitch::nReceivedValue = code; 00780 RCSwitch::nReceivedBitlength = changeCount / 2; 00781 nReceivedDelay = delay; 00782 RCSwitch::nReceivedProtocol = 3; 00783 } 00784 00785 if (code == 0){ 00786 return false; 00787 } 00788 return true; 00789 } 00790 00791 void RCSwitch::RCSwitchRxPinChange() { 00792 00793 static unsigned int duration; 00794 static unsigned int changeCount; 00795 static unsigned int repeatCount; 00796 timer.stop(); 00797 duration = timer.read_us(); 00798 timer.reset(); 00799 timer.start(); 00800 00801 00802 if (duration > 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) { 00803 repeatCount++; 00804 changeCount--; 00805 00806 if (repeatCount == 2) { 00807 if (receiveProtocol1(changeCount) == false){ 00808 if (receiveProtocol2(changeCount) == false){ 00809 if (receiveProtocol3(changeCount) == false){ 00810 //failed 00811 } 00812 } 00813 } 00814 repeatCount = 0; 00815 } 00816 changeCount = 0; 00817 } else if (duration > 5000) { 00818 00819 changeCount = 0; 00820 } 00821 00822 if (changeCount >= RCSWITCH_MAX_CHANGES) { 00823 changeCount = 0; 00824 repeatCount = 0; 00825 } 00826 RCSwitch::timings[changeCount++] = duration; 00827 } 00828 00829 /** 00830 * Turns a decimal value to its binary representation 00831 */ 00832 char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ 00833 return dec2binWcharfill(Dec, bitLength, '0'); 00834 } 00835 00836 char* RCSwitch::dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill){ 00837 static char bin[64]; 00838 unsigned int i=0; 00839 00840 while (Dec > 0) { 00841 bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill; 00842 Dec = Dec >> 1; 00843 } 00844 00845 for (unsigned int j = 0; j< bitLength; j++) { 00846 if (j >= bitLength - i) { 00847 bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; 00848 }else { 00849 bin[j] = fill; 00850 } 00851 } 00852 bin[bitLength] = '\0'; 00853 00854 return bin; 00855 } 00856 00857 00858
Generated on Thu Jul 14 2022 01:54:18 by 1.7.2