Library to switch 433MHz remote controlled sockets.

Dependents:   RCswitch_example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RCSwitch.cpp Source File

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