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