lib/rc-switch.c

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

mercurial