Merge branch 'master' of mjesec.ffzg.hr:/git/Arduino
[Arduino] / libraries / RCSwitch / RCSwitch.cpp
1 /*\r
2   RCSwitch - Arduino libary for remote control outlet switches\r
3   Copyright (c) 2011 Suat Özgür.  All right reserved.\r
4   \r
5   Contributors:\r
6   - Andre Koehler / info(at)tomate-online(dot)de\r
7   - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com\r
8   - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46\r
9   - Dominik Fischer / dom_fischer(at)web(dot)de\r
10   \r
11   Project home: http://code.google.com/p/rc-switch/\r
12 \r
13   This library is free software; you can redistribute it and/or\r
14   modify it under the terms of the GNU Lesser General Public\r
15   License as published by the Free Software Foundation; either\r
16   version 2.1 of the License, or (at your option) any later version.\r
17 \r
18   This library is distributed in the hope that it will be useful,\r
19   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
21   Lesser General Public License for more details.\r
22 \r
23   You should have received a copy of the GNU Lesser General Public\r
24   License along with this library; if not, write to the Free Software\r
25   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
26 */\r
27 \r
28 #include "RCSwitch.h"\r
29 \r
30 unsigned long RCSwitch::nReceivedValue = NULL;\r
31 unsigned int RCSwitch::nReceivedBitlength = 0;\r
32 unsigned int RCSwitch::nReceivedDelay = 0;\r
33 unsigned int RCSwitch::nReceivedProtocol = 0;\r
34 unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES];\r
35 int RCSwitch::nReceiveTolerance = 60;\r
36 \r
37 RCSwitch::RCSwitch() {\r
38   this->nReceiverInterrupt = -1;\r
39   this->nTransmitterPin = -1;\r
40   RCSwitch::nReceivedValue = NULL;\r
41   this->setPulseLength(350);\r
42   this->setRepeatTransmit(10);\r
43   this->setReceiveTolerance(60);\r
44   this->setProtocol(1);\r
45 }\r
46 \r
47 /**\r
48   * Sets the protocol to send.\r
49   */\r
50 void RCSwitch::setProtocol(int nProtocol) {\r
51   this->nProtocol = nProtocol;\r
52   if (nProtocol == 1){\r
53           this->setPulseLength(350);\r
54   }\r
55   else if (nProtocol == 2) {\r
56           this->setPulseLength(650);\r
57   }\r
58 }\r
59 \r
60 /**\r
61   * Sets the protocol to send with pulse length in microseconds.\r
62   */\r
63 void RCSwitch::setProtocol(int nProtocol, int nPulseLength) {\r
64   this->nProtocol = nProtocol;\r
65   if (nProtocol == 1){\r
66           this->setPulseLength(nPulseLength);\r
67   }\r
68   else if (nProtocol == 2) {\r
69           this->setPulseLength(nPulseLength);\r
70   }\r
71 }\r
72 \r
73 \r
74 /**\r
75   * Sets pulse length in microseconds\r
76   */\r
77 void RCSwitch::setPulseLength(int nPulseLength) {\r
78   this->nPulseLength = nPulseLength;\r
79 }\r
80 \r
81 /**\r
82  * Sets Repeat Transmits\r
83  */\r
84 void RCSwitch::setRepeatTransmit(int nRepeatTransmit) {\r
85   this->nRepeatTransmit = nRepeatTransmit;\r
86 }\r
87 \r
88 /**\r
89  * Set Receiving Tolerance\r
90  */\r
91 void RCSwitch::setReceiveTolerance(int nPercent) {\r
92   RCSwitch::nReceiveTolerance = nPercent;\r
93 }\r
94   \r
95 \r
96 /**\r
97  * Enable transmissions\r
98  *\r
99  * @param nTransmitterPin    Arduino Pin to which the sender is connected to\r
100  */\r
101 void RCSwitch::enableTransmit(int nTransmitterPin) {\r
102   this->nTransmitterPin = nTransmitterPin;\r
103   pinMode(this->nTransmitterPin, OUTPUT);\r
104 }\r
105 \r
106 /**\r
107   * Disable transmissions\r
108   */\r
109 void RCSwitch::disableTransmit() {\r
110   this->nTransmitterPin = -1;\r
111 }\r
112 \r
113 /**\r
114  * Switch a remote switch on (Type C Intertechno)\r
115  *\r
116  * @param sFamily  Familycode (a..f)\r
117  * @param nGroup   Number of group (1..4)\r
118  * @param nDevice  Number of device (1..4)\r
119   */\r
120 void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) {\r
121   this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) );\r
122 }\r
123 \r
124 /**\r
125  * Switch a remote switch off (Type C Intertechno)\r
126  *\r
127  * @param sFamily  Familycode (a..f)\r
128  * @param nGroup   Number of group (1..4)\r
129  * @param nDevice  Number of device (1..4)\r
130  */\r
131 void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) {\r
132   this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) );\r
133 }\r
134 \r
135 /**\r
136  * Switch a remote switch on (Type B with two rotary/sliding switches)\r
137  *\r
138  * @param nAddressCode  Number of the switch group (1..4)\r
139  * @param nChannelCode  Number of the switch itself (1..4)\r
140  */\r
141 void RCSwitch::switchOn(int nAddressCode, int nChannelCode) {\r
142   this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) );\r
143 }\r
144 \r
145 /**\r
146  * Switch a remote switch off (Type B with two rotary/sliding switches)\r
147  *\r
148  * @param nAddressCode  Number of the switch group (1..4)\r
149  * @param nChannelCode  Number of the switch itself (1..4)\r
150  */\r
151 void RCSwitch::switchOff(int nAddressCode, int nChannelCode) {\r
152   this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) );\r
153 }\r
154 \r
155 /**\r
156  * Deprecated, use switchOn(char* sGroup, char* sDevice) instead!\r
157  * Switch a remote switch on (Type A with 10 pole DIP switches)\r
158  *\r
159  * @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")\r
160  * @param nChannelCode  Number of the switch itself (1..5)\r
161  */\r
162 void RCSwitch::switchOn(char* sGroup, int nChannel) {\r
163   char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };\r
164   this->switchOn(sGroup, code[nChannel]);\r
165 }\r
166 \r
167 /**\r
168  * Deprecated, use switchOff(char* sGroup, char* sDevice) instead!\r
169  * Switch a remote switch off (Type A with 10 pole DIP switches)\r
170  *\r
171  * @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")\r
172  * @param nChannelCode  Number of the switch itself (1..5)\r
173  */\r
174 void RCSwitch::switchOff(char* sGroup, int nChannel) {\r
175   char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };\r
176   this->switchOff(sGroup, code[nChannel]);\r
177 }\r
178 \r
179 /**\r
180  * Switch a remote switch on (Type A with 10 pole DIP switches)\r
181  *\r
182  * @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")\r
183  * @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")\r
184  */\r
185 void RCSwitch::switchOn(char* sGroup, char* sDevice) {\r
186         this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) );\r
187 }\r
188 \r
189 /**\r
190  * Switch a remote switch off (Type A with 10 pole DIP switches)\r
191  *\r
192  * @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")\r
193  * @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")\r
194  */\r
195 void RCSwitch::switchOff(char* sGroup, char* sDevice) {\r
196         this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) );\r
197 }\r
198 \r
199 /**\r
200  * Returns a char[13], representing the Code Word to be send.\r
201  * 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.\r
202  * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit)\r
203  *\r
204  * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+\r
205  * | 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 |\r
206  * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0   | 1=0FFF 2=F0FF 3=FF0F 4=FFF0    | F                                       | F                                       | on=FF off=F0         | S          |\r
207  * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+\r
208  *\r
209  * @param nAddressCode  Number of the switch group (1..4)\r
210  * @param nChannelCode  Number of the switch itself (1..4)\r
211  * @param bStatus       Wether to switch on (true) or off (false)\r
212  *\r
213  * @return char[13]\r
214  */\r
215 char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) {\r
216    int nReturnPos = 0;\r
217    static char sReturn[13];\r
218    \r
219    char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" };\r
220    if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) {\r
221     return '\0';\r
222    }\r
223    for (int i = 0; i<4; i++) {\r
224      sReturn[nReturnPos++] = code[nAddressCode][i];\r
225    }\r
226 \r
227    for (int i = 0; i<4; i++) {\r
228      sReturn[nReturnPos++] = code[nChannelCode][i];\r
229    }\r
230    \r
231    sReturn[nReturnPos++] = 'F';\r
232    sReturn[nReturnPos++] = 'F';\r
233    sReturn[nReturnPos++] = 'F';\r
234    \r
235    if (bStatus) {\r
236       sReturn[nReturnPos++] = 'F';\r
237    } else {\r
238       sReturn[nReturnPos++] = '0';\r
239    }\r
240    \r
241    sReturn[nReturnPos] = '\0';\r
242    \r
243    return sReturn;\r
244 }\r
245 \r
246 /**\r
247  * Returns a char[13], representing the Code Word to be send.\r
248  *\r
249  * getCodeWordA(char*, char*)\r
250  *\r
251  */\r
252 char* RCSwitch::getCodeWordA(char* sGroup, char* sDevice, boolean bOn) {\r
253         static char sDipSwitches[13];\r
254     int i = 0;\r
255         int j = 0;\r
256         \r
257         for (i=0; i < 5; i++) {\r
258                 if (sGroup[i] == '0') {\r
259                         sDipSwitches[j++] = 'F';\r
260                 } else {\r
261                         sDipSwitches[j++] = '0';\r
262                 }\r
263         }\r
264 \r
265         for (i=0; i < 5; i++) {\r
266                 if (sDevice[i] == '0') {\r
267                         sDipSwitches[j++] = 'F';\r
268                 } else {\r
269                         sDipSwitches[j++] = '0';\r
270                 }\r
271         }\r
272 \r
273         if ( bOn ) {\r
274                 sDipSwitches[j++] = '0';\r
275                 sDipSwitches[j++] = 'F';\r
276         } else {\r
277                 sDipSwitches[j++] = 'F';\r
278                 sDipSwitches[j++] = '0';\r
279         }\r
280 \r
281         sDipSwitches[j] = '\0';\r
282 \r
283         return sDipSwitches;\r
284 }\r
285 \r
286 /**\r
287  * Like getCodeWord (Type C = Intertechno)\r
288  */\r
289 char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus) {\r
290   static char sReturn[13];\r
291   int nReturnPos = 0;\r
292   \r
293   if ( (byte)sFamily < 97 || (byte)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) {\r
294     return '\0';\r
295   }\r
296   \r
297   char* sDeviceGroupCode =  dec2binWzerofill(  (nDevice-1) + (nGroup-1)*4, 4  );\r
298   char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" };\r
299   for (int i = 0; i<4; i++) {\r
300     sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i];\r
301   }\r
302   for (int i = 0; i<4; i++) {\r
303     sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0');\r
304   }\r
305   sReturn[nReturnPos++] = '0';\r
306   sReturn[nReturnPos++] = 'F';\r
307   sReturn[nReturnPos++] = 'F';\r
308   if (bStatus) {\r
309     sReturn[nReturnPos++] = 'F';\r
310   } else {\r
311     sReturn[nReturnPos++] = '0';\r
312   }\r
313   sReturn[nReturnPos] = '\0';\r
314   return sReturn;\r
315 }\r
316 \r
317 /**\r
318  * Sends a Code Word\r
319  * @param sCodeWord   /^[10FS]*$/  -> see getCodeWord\r
320  */\r
321 void RCSwitch::sendTriState(char* sCodeWord) {\r
322   for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) {\r
323     int i = 0;\r
324     while (sCodeWord[i] != '\0') {\r
325       switch(sCodeWord[i]) {\r
326         case '0':\r
327           this->sendT0();\r
328         break;\r
329         case 'F':\r
330           this->sendTF();\r
331         break;\r
332         case '1':\r
333           this->sendT1();\r
334         break;\r
335       }\r
336       i++;\r
337     }\r
338     this->sendSync();    \r
339   }\r
340 }\r
341 \r
342 void RCSwitch::send(unsigned long Code, unsigned int length) {\r
343   this->send( this->dec2binWzerofill(Code, length) );\r
344 }\r
345 \r
346 void RCSwitch::send(char* sCodeWord) {\r
347   for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) {\r
348     int i = 0;\r
349     while (sCodeWord[i] != '\0') {\r
350       switch(sCodeWord[i]) {\r
351         case '0':\r
352           this->send0();\r
353         break;\r
354         case '1':\r
355           this->send1();\r
356         break;\r
357       }\r
358       i++;\r
359     }\r
360     this->sendSync();\r
361   }\r
362 }\r
363 \r
364 void RCSwitch::transmit(int nHighPulses, int nLowPulses) {\r
365     boolean disabled_Receive = false;\r
366     int nReceiverInterrupt_backup = nReceiverInterrupt;\r
367     if (this->nTransmitterPin != -1) {\r
368         if (this->nReceiverInterrupt != -1) {\r
369             this->disableReceive();\r
370             disabled_Receive = true;\r
371         }\r
372         digitalWrite(this->nTransmitterPin, HIGH);\r
373         delayMicroseconds( this->nPulseLength * nHighPulses);\r
374         digitalWrite(this->nTransmitterPin, LOW);\r
375         delayMicroseconds( this->nPulseLength * nLowPulses);\r
376         if(disabled_Receive){\r
377             this->enableReceive(nReceiverInterrupt_backup);\r
378         }\r
379     }\r
380 }\r
381 /**\r
382  * Sends a "0" Bit\r
383  *                       _    \r
384  * Waveform Protocol 1: | |___\r
385  *                       _  \r
386  * Waveform Protocol 2: | |__\r
387  */\r
388 void RCSwitch::send0() {\r
389         if (this->nProtocol == 1){\r
390                 this->transmit(1,3);\r
391         }\r
392         else if (this->nProtocol == 2) {\r
393                 this->transmit(1,2);\r
394         }\r
395 }\r
396 \r
397 /**\r
398  * Sends a "1" Bit\r
399  *                       ___  \r
400  * Waveform Protocol 1: |   |_\r
401  *                       __  \r
402  * Waveform Protocol 2: |  |_\r
403  */\r
404 void RCSwitch::send1() {\r
405         if (this->nProtocol == 1){\r
406                 this->transmit(3,1);\r
407         }\r
408         else if (this->nProtocol == 2) {\r
409                 this->transmit(2,1);\r
410         }\r
411 }\r
412 \r
413 \r
414 /**\r
415  * Sends a Tri-State "0" Bit\r
416  *            _     _\r
417  * Waveform: | |___| |___\r
418  */\r
419 void RCSwitch::sendT0() {\r
420   this->transmit(1,3);\r
421   this->transmit(1,3);\r
422 }\r
423 \r
424 /**\r
425  * Sends a Tri-State "1" Bit\r
426  *            ___   ___\r
427  * Waveform: |   |_|   |_\r
428  */\r
429 void RCSwitch::sendT1() {\r
430   this->transmit(3,1);\r
431   this->transmit(3,1);\r
432 }\r
433 \r
434 /**\r
435  * Sends a Tri-State "F" Bit\r
436  *            _     ___\r
437  * Waveform: | |___|   |_\r
438  */\r
439 void RCSwitch::sendTF() {\r
440   this->transmit(1,3);\r
441   this->transmit(3,1);\r
442 }\r
443 \r
444 /**\r
445  * Sends a "Sync" Bit\r
446  *                       _\r
447  * Waveform Protocol 1: | |_______________________________\r
448  *                       _\r
449  * Waveform Protocol 2: | |__________\r
450  */\r
451 void RCSwitch::sendSync() {\r
452 \r
453     if (this->nProtocol == 1){\r
454                 this->transmit(1,31);\r
455         }\r
456         else if (this->nProtocol == 2) {\r
457                 this->transmit(1,10);\r
458         }\r
459 }\r
460 \r
461 /**\r
462  * Enable receiving data\r
463  */\r
464 void RCSwitch::enableReceive(int interrupt) {\r
465   this->nReceiverInterrupt = interrupt;\r
466   this->enableReceive();\r
467 }\r
468 \r
469 void RCSwitch::enableReceive() {\r
470   if (this->nReceiverInterrupt != -1) {\r
471     RCSwitch::nReceivedValue = NULL;\r
472     RCSwitch::nReceivedBitlength = NULL;\r
473     attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE);\r
474   }\r
475 }\r
476 \r
477 /**\r
478  * Disable receiving data\r
479  */\r
480 void RCSwitch::disableReceive() {\r
481   detachInterrupt(this->nReceiverInterrupt);\r
482   this->nReceiverInterrupt = -1;\r
483 }\r
484 \r
485 bool RCSwitch::available() {\r
486   return RCSwitch::nReceivedValue != NULL;\r
487 }\r
488 \r
489 void RCSwitch::resetAvailable() {\r
490   RCSwitch::nReceivedValue = NULL;\r
491 }\r
492 \r
493 unsigned long RCSwitch::getReceivedValue() {\r
494     return RCSwitch::nReceivedValue;\r
495 }\r
496 \r
497 unsigned int RCSwitch::getReceivedBitlength() {\r
498   return RCSwitch::nReceivedBitlength;\r
499 }\r
500 \r
501 unsigned int RCSwitch::getReceivedDelay() {\r
502   return RCSwitch::nReceivedDelay;\r
503 }\r
504 \r
505 unsigned int RCSwitch::getReceivedProtocol() {\r
506   return RCSwitch::nReceivedProtocol;\r
507 }\r
508 \r
509 unsigned int* RCSwitch::getReceivedRawdata() {\r
510     return RCSwitch::timings;\r
511 }\r
512 \r
513 /**\r
514  *\r
515  */\r
516 bool RCSwitch::receiveProtocol1(unsigned int changeCount){\r
517     \r
518           unsigned long code = 0;\r
519       unsigned long delay = RCSwitch::timings[0] / 31;\r
520       unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01;    \r
521 \r
522       for (int i = 1; i<changeCount ; i=i+2) {\r
523       \r
524           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) {\r
525             code = code << 1;\r
526           } 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) {\r
527             code+=1;\r
528             code = code << 1;\r
529           } else {\r
530             // Failed\r
531             i = changeCount;\r
532             code = 0;\r
533           }\r
534       }      \r
535       code = code >> 1;\r
536     if (changeCount > 6) {    // ignore < 4bit values as there are no devices sending 4bit values => noise\r
537       RCSwitch::nReceivedValue = code;\r
538       RCSwitch::nReceivedBitlength = changeCount / 2;\r
539       RCSwitch::nReceivedDelay = delay;\r
540           RCSwitch::nReceivedProtocol = 1;\r
541     }\r
542 \r
543         if (code == 0){\r
544                 return false;\r
545         }else if (code != 0){\r
546                 return true;\r
547         }\r
548         \r
549 \r
550 }\r
551 \r
552 bool RCSwitch::receiveProtocol2(unsigned int changeCount){\r
553     \r
554           unsigned long code = 0;\r
555       unsigned long delay = RCSwitch::timings[0] / 10;\r
556       unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01;    \r
557 \r
558       for (int i = 1; i<changeCount ; i=i+2) {\r
559       \r
560           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) {\r
561             code = code << 1;\r
562           } 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) {\r
563             code+=1;\r
564             code = code << 1;\r
565           } else {\r
566             // Failed\r
567             i = changeCount;\r
568             code = 0;\r
569           }\r
570       }      \r
571       code = code >> 1;\r
572     if (changeCount > 6) {    // ignore < 4bit values as there are no devices sending 4bit values => noise\r
573       RCSwitch::nReceivedValue = code;\r
574       RCSwitch::nReceivedBitlength = changeCount / 2;\r
575       RCSwitch::nReceivedDelay = delay;\r
576           RCSwitch::nReceivedProtocol = 2;\r
577     }\r
578 \r
579         if (code == 0){\r
580                 return false;\r
581         }else if (code != 0){\r
582                 return true;\r
583         }\r
584 \r
585 }\r
586 void RCSwitch::handleInterrupt() {\r
587 \r
588   static unsigned int duration;\r
589   static unsigned int changeCount;\r
590   static unsigned long lastTime;\r
591   static unsigned int repeatCount;\r
592   \r
593 \r
594   long time = micros();\r
595   duration = time - lastTime;\r
596  \r
597   if (duration > 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) {\r
598     repeatCount++;\r
599     changeCount--;\r
600     if (repeatCount == 2) {\r
601                 if (receiveProtocol1(changeCount) == false){\r
602                         if (receiveProtocol2(changeCount) == false){\r
603                                 //failed\r
604                         }\r
605                 }\r
606       repeatCount = 0;\r
607     }\r
608     changeCount = 0;\r
609   } else if (duration > 5000) {\r
610     changeCount = 0;\r
611   }\r
612  \r
613   if (changeCount >= RCSWITCH_MAX_CHANGES) {\r
614     changeCount = 0;\r
615     repeatCount = 0;\r
616   }\r
617   RCSwitch::timings[changeCount++] = duration;\r
618   lastTime = time;  \r
619 }\r
620 \r
621 /**\r
622   * Turns a decimal value to its binary representation\r
623   */\r
624 char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){\r
625   static char bin[64];\r
626   unsigned int i=0;\r
627 \r
628   while (Dec > 0) {\r
629     bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0';\r
630     Dec = Dec >> 1;\r
631   }\r
632 \r
633   for (unsigned int j = 0; j< bitLength; j++) {\r
634     if (j >= bitLength - i) {\r
635       bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];\r
636     }else {\r
637       bin[j] = '0';\r
638     }\r
639   }\r
640   bin[bitLength] = '\0';\r
641   \r
642   return bin;\r
643 }\r
644 \r