lib/rc-switch.c

changeset 51
a03b6dac5398
parent 50
8b5e8f1e172d
child 52
4387a6b11eb3
equal deleted inserted replaced
50:8b5e8f1e172d 51:a03b6dac5398
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
32 #define TYPE_UNDEF 0
33 #define TYPE_MINIMUM 0
34 #define TYPE_A 1
35 #define TYPE_B 2
36 #define TYPE_C 3
37 #define TYPE_D 4
38 #define TYPE_E 3 // TODO: Which Protocol does REV use?
39 #define TYPE_MAXIMUM 4
40
41 // Number of maximum High/Low changes per packet.
42 // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
43 #define RCSWITCH_MAX_CHANGES 67
44
45 // i.e. ProtocolCount + 1 (for TYPE_UNDEF)
46 #define MAX_PROTOCOLS 5
47
48 #define PROTOCOL_A_SYNC_FACTOR 31
49 #define PROTOCOL_A_ZERO_FIRST_CYCLES 1
50 #define PROTOCOL_A_ZERO_SECOND_CYCLES 3
51 #define PROTOCOL_A_ONE_FIRST_CYCLES 3
52 #define PROTOCOL_A_ONE_SECOND_CYCLES 1
53 #define PROTOCOL_A_HIGH_FIRST true
54
55 #define PROTOCOL_B_SYNC_FACTOR 10
56 #define PROTOCOL_B_ZERO_FIRST_CYCLES 1
57 #define PROTOCOL_B_ZERO_SECOND_CYCLES 2
58 #define PROTOCOL_B_ONE_FIRST_CYCLES 2
59 #define PROTOCOL_B_ONE_SECOND_CYCLES 1
60 #define PROTOCOL_B_HIGH_FIRST true
61
62 #define PROTOCOL_C_SYNC_FACTOR 71
63 #define PROTOCOL_C_ZERO_FIRST_CYCLES 4
64 #define PROTOCOL_C_ZERO_SECOND_CYCLES 11
65 #define PROTOCOL_C_ONE_FIRST_CYCLES 9
66 #define PROTOCOL_C_ONE_SECOND_CYCLES 6
67 #define PROTOCOL_C_HIGH_FIRST true
68
69 // I think, this will work for receive, however, I haven't tested, as I don't own a receiver...
70 // As Type D doesn't sync acc. to https://github.com/d-a-n/433-codes/blob/master/database.md#quigg
71 // the sync factor is totally undetermined.
72 // Malte Diers, 22.11.2013
73 #define PROTOCOL_D_SYNC_FACTOR 1
74 #define PROTOCOL_D_ZERO_FIRST_CYCLES 1
75 #define PROTOCOL_D_ZERO_SECOND_CYCLES 2
76 #define PROTOCOL_D_ONE_FIRST_CYCLES 2
77 #define PROTOCOL_D_ONE_SECOND_CYCLES 1
78 #define PROTOCOL_D_HIGH_FIRST false
79
80
81 #define PROTOCOL3_SYNC_FACTOR 71
82 #define PROTOCOL3_0_HIGH_CYCLES 4
83 #define PROTOCOL3_0_LOW_CYCLES 11
84 #define PROTOCOL3_1_HIGH_CYCLES 9
85 #define PROTOCOL3_1_LOW_CYCLES 6
86
87
88
89 unsigned long rcReceivedValue = 0;
90 unsigned int rcReceivedBitlength = 0;
91 unsigned int rcReceivedDelay = 0;
92 unsigned int rcReceivedProtocol = 0;
93 int rcReceiveTolerance = 60;
94 int rcReceiverInterruptPin = -1;
95
96 unsigned int timings[RCSWITCH_MAX_CHANGES];
97 int rcTransmitterPin = -1;
98 int rcPulseLength = 350; // thermometers 2.4 msec = 2400
99 int rcRepeatTransmit = 10;
100 int rcProtocol = 1;
101
102 int backupProtocol;
103 int backupPulseLength;
104 int backupRepeatTransmit;
105
106
107 //const char TYPE_A_CODE[ 6][6] = { "00000", "10000", "01000", "00100", "00010", "00001"};
108 const char TYPE_B_CODE[ 5][5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" };
109 const char TYPE_C_CODE[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0",
110 "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" };
111 const char TYPE_D_CODE[5][2][9] = { { "11100001", "11110000" }, { "00000000", "00010001" }, { "10000010", "10010011" },
112 { "11000011", "11010010" }, { "01000001", "01010000" } };
113 /* Type A Type D */
114 const int PULSE_LENGTH[MAX_PROTOCOLS] = { 0, 350, 650, 100, 666, };
115 const int REPEAT_TRANSMIT[MAX_PROTOCOLS] = { 0, 10, 10, 10, 4, };
116 const int SYNC_FACTOR[MAX_PROTOCOLS] = { 0, PROTOCOL_A_SYNC_FACTOR, PROTOCOL_B_SYNC_FACTOR, PROTOCOL_C_SYNC_FACTOR, PROTOCOL_D_SYNC_FACTOR, };
117 const int ZERO_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_FIRST_CYCLES, PROTOCOL_B_ZERO_FIRST_CYCLES, PROTOCOL_C_ZERO_FIRST_CYCLES, PROTOCOL_D_ZERO_FIRST_CYCLES, };
118 const int ZERO_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_SECOND_CYCLES, PROTOCOL_B_ZERO_SECOND_CYCLES, PROTOCOL_C_ZERO_SECOND_CYCLES, PROTOCOL_D_ZERO_SECOND_CYCLES, };
119 const int ONE_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_FIRST_CYCLES, PROTOCOL_B_ONE_FIRST_CYCLES, PROTOCOL_C_ONE_FIRST_CYCLES, PROTOCOL_D_ONE_FIRST_CYCLES, };
120 const int ONE_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_SECOND_CYCLES, PROTOCOL_B_ONE_SECOND_CYCLES, PROTOCOL_C_ONE_SECOND_CYCLES, PROTOCOL_D_ONE_SECOND_CYCLES, };
121 const bool HIGH_FIRST[MAX_PROTOCOLS] = { 0, PROTOCOL_A_HIGH_FIRST, PROTOCOL_B_HIGH_FIRST, PROTOCOL_C_HIGH_FIRST, PROTOCOL_D_HIGH_FIRST, };
122
123
124 char *getCodeWordA(char*, char*, bool);
125 char *getCodeWordB(int, int, bool);
126 char *getCodeWordC(char, int, int, bool);
127
128 char *getCodeWordE(char, int, bool);
129 void sendTriState(char*);
130 void transmit(int, int, bool);
131 void send0(void);
132 void send1(void);
133 void sendT0(void);
134 void sendT1(void);
135 void sendTF(void);
136 void sendSync(void);
137 bool receiveProtocol(int, unsigned int);
138 void handleInterrupt(void);
139 char *dec2binWcharfill(unsigned long, unsigned int, char);
140
141 void setReceiveTolerance(int);
142 void setProtocol(int);
143
144 void saveProtocol(int);
145 void loadProtocol(void);
146
147
148
149 /*
150 * Sets the protocol to send.
151 */
152 void setProtocol(int nProtocol) {
153
154 if ((nProtocol < TYPE_MINIMUM) || (nProtocol > TYPE_MAXIMUM)) {
155 return;
156 }
157
158 rcProtocol = nProtocol;
159 rcPulseLength = PULSE_LENGTH[nProtocol];
160 rcRepeatTransmit = REPEAT_TRANSMIT[nProtocol];
161 }
162
163
164
165 /*
166 * Set Receiving Tolerance
167 */
168 void setReceiveTolerance(int nPercent) {
169 rcReceiveTolerance = nPercent;
170 }
171
172
173
174 /*
175 * Enable transmissions
176 *
177 * @param nTransmitterPin Pin to which the sender is connected to
178 */
179 void enableTransmit(int nTransmitterPin) {
180 rcTransmitterPin = nTransmitterPin;
181 pinMode(rcTransmitterPin, OUTPUT);
182 }
183
184
185
186 /*
187 * Disable transmissions
188 */
189 void disableTransmit(void) {
190 rcTransmitterPin = -1;
191 }
192
193
194
195 /*
196 * Toggle switch, a command looks like B,3,2,1 which means switch type B,
197 * group 3, device 2, status on.
198 */
199 int toggleSwitch(char *command)
200 {
201 static char *cmd = NULL;
202 char *s, cType;
203 int rc, iGroup, iDevice, iState;
204
205 cmd = xstrcpy(command);
206 s = strtok(cmd, ",\0");
207 cType = s[0];
208
209 if (cType == 'A') {
210
211 } else if (cType == 'B') {
212 s = strtok(NULL, ",\0");
213 rc = sscanf(s, "%d", &iGroup);
214 if (rc != 1)
215 return 1;
216 s = strtok(NULL, ",\0");
217 rc = sscanf(s, "%d", &iDevice);
218 if (rc != 1)
219 return 1;
220 s = strtok(NULL, ",\0");
221 rc = sscanf(s, "%d", &iState);
222 if (rc != 1)
223 return 1;
224 free(cmd);
225 return toggleTypeB(iGroup, iDevice, iState);
226 }
227
228 free(cmd);
229 return 1;
230 }
231
232
233
234 /*
235 * Switch a remote switch on (Type E REV)
236 *
237 * @param sGroup Code of the switch group (A,B,C,D)
238 * @param nDevice Number of the switch itself (1..3)
239 * @param bStatus Status to toggle to
240 */
241 int toggleTypeE(char sGroup, int nDevice, bool bStatus) {
242 sendTriState( getCodeWordE(sGroup, nDevice, bStatus) );
243 return 0;
244 }
245
246
247
248 /*
249 * Switch a remote switch on (Type C Intertechno)
250 *
251 * @param sFamily Familycode (a..f)
252 * @param nGroup Number of group (1..4)
253 * @param nDevice Number of device (1..4)
254 * @param bStatus Status to toggle to
255 */
256 int toggleTypeC(char sFamily, int nGroup, int nDevice, bool bStatus) {
257 char *str = xstrcpy(getCodeWordC(sFamily, nGroup, nDevice, bStatus));
258
259 if (strlen(str) == 0)
260 return 1;
261
262 saveProtocol(TYPE_A); // ???
263 sendTriState( str );
264 loadProtocol();
265 free(str);
266 return 0;
267 }
268
269
270
271 /*
272 * Switch a remote switch on/off (Type B with two rotary/sliding switches)
273 *
274 * @param iGroup Number of the switch group (1..4)
275 * @param iDevice Number of the switch itself (1..4)
276 * @param bStatus Status to toggle to
277 */
278 int toggleTypeB(int iGroup, int iDevice, bool bStatus)
279 {
280 char *str = xstrcpy(getCodeWordB(iGroup, iDevice, bStatus));
281
282 if (strlen(str) == 0)
283 return 1;
284
285 saveProtocol(TYPE_A); // They do better with protocol A timings.
286 sendTriState( str );
287 loadProtocol();
288 free(str);
289 return 0;
290 }
291
292
293
294 /*
295 * Switch a remote switch on (Type A with 10 pole DIP switches)
296 *
297 * @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")
298 * @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")
299 * @param bStatus Status to toggle to
300 */
301 int toggleTypeA(char* sGroup, char* sDevice, bool bStatus) {
302 char *str = xstrcpy(getCodeWordA(sGroup, sDevice, bStatus));
303
304 if (strlen(str) == 0)
305 return 1;
306
307 saveProtocol(TYPE_A);
308 sendTriState( str );
309 loadProtocol();
310 free(str);
311 return 0;
312 }
313
314
315
316 /*
317 * Returns a char[13], representing the Code Word to be send.
318 * 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.
319 * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit)
320 *
321 * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+
322 * | 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 |
323 * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S |
324 * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+
325 *
326 * @param nAddressCode Number of the switch group (1..4)
327 * @param nChannelCode Number of the switch itself (1..4)
328 * @param bStatus Wether to switch on (true) or off (false)
329 *
330 * @return char[13]
331 */
332 char *getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus)
333 {
334 int i, nReturnPos = 0;
335 static char sReturn[13];
336
337 if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) {
338 return '\0';
339 }
340 for (i = 0; i<4; i++) {
341 sReturn[nReturnPos++] = TYPE_B_CODE[nAddressCode][i];
342 }
343
344 for (i = 0; i<4; i++) {
345 sReturn[nReturnPos++] = TYPE_B_CODE[nChannelCode][i];
346 }
347
348 sReturn[nReturnPos++] = 'F';
349 sReturn[nReturnPos++] = 'F';
350 sReturn[nReturnPos++] = 'F';
351 sReturn[nReturnPos++] = bStatus ? 'F' : '0';
352 sReturn[nReturnPos] = '\0';
353
354 return sReturn;
355 }
356
357
358
359 /*
360 * Returns a char[13], representing the Code Word to be send.
361 *
362 * getCodeWordA(char*, char*)
363 *
364 */
365 char *getCodeWordA(char* sGroup, char* sDevice, bool bOn)
366 {
367 static char sDipSwitches[13];
368 int i, j = 0;
369
370 for (i=0; i < 5; i++) {
371 sDipSwitches[j++] = (sGroup[i] == '0') ? 'F' : '0';
372 }
373
374 for (i=0; i < 5; i++) {
375 sDipSwitches[j++] = (sDevice[i] == '0') ? 'F' : '0';
376 }
377
378 if ( bOn ) {
379 sDipSwitches[j++] = '0';
380 sDipSwitches[j++] = 'F';
381 } else {
382 sDipSwitches[j++] = 'F';
383 sDipSwitches[j++] = '0';
384 }
385
386 sDipSwitches[j] = '\0';
387 return sDipSwitches;
388 }
389
390
391
392 /*
393 * Like getCodeWord (Type C = Intertechno)
394 */
395 char *getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus)
396 {
397 static char sReturn[13];
398 int i, nReturnPos = 0;
399
400 if (sFamily < 'a') {
401 // To also enable capital 'A' to 'F'
402 sFamily += 32;
403 }
404
405 if ( sFamily < 'a' || sFamily > 'f' || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) {
406 return '\0';
407 }
408
409 for (i = 0; i<4; i++) {
410 sReturn[nReturnPos++] = TYPE_C_CODE[ sFamily - 'a' ][i];
411 }
412
413 char *sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 );
414 for (i = 0; i<4; i++) {
415 sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0');
416 }
417
418 sReturn[nReturnPos++] = '0';
419 sReturn[nReturnPos++] = 'F';
420 sReturn[nReturnPos++] = 'F';
421 sReturn[nReturnPos++] = bStatus ? 'F' : '0';
422 sReturn[nReturnPos] = '\0';
423
424 return sReturn;
425 }
426
427
428
429 /*
430 * Decoding for the Quigg Switch Type
431 *
432 * Returns a char[22], representing the States to be send.
433 * A Code Word consists of 1 start bit, 12 address bits and 8 command data bits.
434 * A Code Bit can have 2 different states: "0" (low), "1" (high)
435 *
436 * +--------------+--------------------------------+------------------------------+
437 * | 1 bits start | 12 bits address (device group) | 8 bits (command/switch data) |
438 * | 1 | 110011001100 | 00010001 |
439 * +--------------+--------------------------------+------------------------------+
440 *
441 * Source: https://github.com/d-a-n/433-codes/blob/master/database.md#quigg
442 *
443 * @param sGroup 12-bit Binary ID of the Device Group
444 * @param nDevice Number of the switch itself (1..4, or 0 to switch the entire Group)
445 * @param bStatus Wether to switch on (true) or off (false)
446 *
447 * @return char[22]
448 */
449 char *getCodeWordD(char *sGroup, int nDevice, bool bStatus)
450 {
451 static char sReturn[22];
452 int i, nReturnPos = 0;
453
454 /* Startbit */
455 sReturn[nReturnPos++] = '1';
456
457 /* 12 bit Group */
458 for (i = 0; i < 12; ++i) {
459 sReturn[nReturnPos++] = sGroup[i];
460 }
461
462 /* 8 Bit Device Identifier + Status (undividable!) */
463 for (i = 0; i < 8; ++i) {
464 sReturn[nReturnPos++] = TYPE_D_CODE[nDevice][bStatus][i];
465 }
466 sReturn[nReturnPos] = 0;
467
468 return sReturn;
469 }
470
471
472
473 /*
474 * Decoding for the REV Switch Type
475 *
476 * Returns a char[13], representing the Tristate to be send.
477 * A Code Word consists of 7 address bits and 5 command data bits.
478 * A Code Bit can have 3 different states: "F" (floating), "0" (low), "1" (high)
479 *
480 * +-------------------------------+--------------------------------+-----------------------+
481 * | 4 bits address (switch group) | 3 bits address (device number) | 5 bits (command data) |
482 * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | on=00010 off=00001 |
483 * +-------------------------------+--------------------------------+-----------------------+
484 *
485 * Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/
486 *
487 * @param sGroup Name of the switch group (A..D, resp. a..d)
488 * @param nDevice Number of the switch itself (1..3)
489 * @param bStatus Wether to switch on (true) or off (false)
490 *
491 * @return char[13]
492 */
493 char *getCodeWordE(char sGroup, int nDevice, bool bStatus){
494 static char sReturn[13];
495 int i, nReturnPos = 0;
496
497 // Building 4 bits address
498 // (Potential problem if dec2binWcharfill not returning correct string)
499 char *sGroupCode;
500 switch(sGroup){
501 case 'a':
502 case 'A':
503 sGroupCode = dec2binWcharfill(8, 4, 'F'); break;
504 case 'b':
505 case 'B':
506 sGroupCode = dec2binWcharfill(4, 4, 'F'); break;
507 case 'c':
508 case 'C':
509 sGroupCode = dec2binWcharfill(2, 4, 'F'); break;
510 case 'd':
511 case 'D':
512 sGroupCode = dec2binWcharfill(1, 4, 'F'); break;
513 default:
514 return '\0';
515 }
516
517 for (i = 0; i<4; i++) {
518 sReturn[nReturnPos++] = sGroupCode[i];
519 }
520
521
522 // Building 3 bits address
523 // (Potential problem if dec2binWcharfill not returning correct string)
524 char *sDevice;
525 switch(nDevice) {
526 case 1:
527 sDevice = dec2binWcharfill(4, 3, 'F'); break;
528 case 2:
529 sDevice = dec2binWcharfill(2, 3, 'F'); break;
530 case 3:
531 sDevice = dec2binWcharfill(1, 3, 'F'); break;
532 default:
533 return '\0';
534 }
535
536 for (i = 0; i<3; i++)
537 sReturn[nReturnPos++] = sDevice[i];
538
539 // fill up rest with zeros
540 for (i = 0; i<5; i++)
541 sReturn[nReturnPos++] = '0';
542
543 // encode on or off
544 if (bStatus)
545 sReturn[10] = '1';
546 else
547 sReturn[11] = '1';
548
549 // last position terminate string
550 sReturn[12] = '\0';
551 return sReturn;
552
553 }
554
555
556
557 /*
558 * @param sCodeWord /^[10FS]*$/ -> see getCodeWord
559 */
560 void sendTriState(char* sCodeWord) {
561 int nRepeat;
562
563 for (nRepeat = 0; nRepeat < rcRepeatTransmit; nRepeat++) {
564 int i = 0;
565 while (sCodeWord[i] != '\0') {
566 switch(sCodeWord[i]) {
567 case '0':
568 sendT0();
569 break;
570 case 'F':
571 sendTF();
572 break;
573 case '1':
574 sendT1();
575 break;
576 }
577 i++;
578 }
579 sendSync();
580 }
581 }
582
583
584
585 /*
586 void RCSwitch::send(unsigned long Code, unsigned int length) {
587 this->send( this->dec2binWzerofill(Code, length) );
588 }
589
590 void RCSwitch::send(char* sCodeWord) {
591 for (int nRepeat=0; nRepeat<nRepeatTransmit; nRepeat++) {
592 int i = 0;
593 while (sCodeWord[i] != '\0') {
594 switch(sCodeWord[i]) {
595 case '0':
596 this->send0();
597 break;
598 case '1':
599 this->send1();
600 break;
601 }
602 i++;
603 }
604 this->sendSync();
605 }
606 }
607 */
608
609
610 void transmit(int nFirstPulses, int nSecondPulses, bool bHighFirst)
611 {
612 bool disabled_Receive = false;
613 int nReceiverInterrupt_backup = rcReceiverInterruptPin;
614
615 if (rcTransmitterPin != -1) {
616 if (rcReceiverInterruptPin != -1) {
617 disableReceive();
618 disabled_Receive = true;
619 }
620 digitalWrite(rcTransmitterPin, bHighFirst ? HIGH : LOW);
621 delayMicroseconds( rcPulseLength * nFirstPulses);
622 digitalWrite(rcTransmitterPin, bHighFirst ? LOW : HIGH);
623 delayMicroseconds( rcPulseLength * nSecondPulses);
624
625 if (disabled_Receive) {
626 enableReceiveIRQ(nReceiverInterrupt_backup);
627 }
628 }
629 }
630
631
632
633 /*
634 * Sends a "0" Bit
635 * _
636 * Waveform Protocol 1: | |___
637 * _
638 * Waveform Protocol 2: | |__
639 * ____
640 * Waveform Protocol 3: | |___________
641 */
642 //void send0(void) {
643 // if (rcProtocol == 1){
644 // transmit(1,3);
645 // }
646 // else if (rcProtocol == 2) {
647 // transmit(1,2);
648 // }
649 // else if (rcProtocol == 3) {
650 // transmit(4,11);
651 // }
652 //}
653
654
655
656 /*
657 * Sends a "1" Bit
658 * ___
659 * Waveform Protocol 1: | |_
660 * __
661 * Waveform Protocol 2: | |_
662 * _________
663 * Waveform Protocol 3: | |______
664 */
665 //void send1(void) {
666 // if (rcProtocol == 1){
667 // transmit(3,1);
668 // }
669 // else if (rcProtocol == 2) {
670 // transmit(2,1);
671 // }
672 // else if (rcProtocol == 3) {
673 // transmit(9,6);
674 // }
675 //}
676
677
678
679 /*
680 * Sends a Tri-State "0" Bit
681 * _ _
682 * Waveform: | |___| |___
683 */
684 void sendT0(void) {
685 transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
686 transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
687 // transmit(1,3,true);
688 // transmit(1,3,true);
689 }
690
691
692
693 /*
694 * Sends a Tri-State "1" Bit
695 * ___ ___
696 * Waveform: | |_| |_
697 */
698 void sendT1(void) {
699 transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
700 transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
701 // transmit(3,1,true);
702 // transmit(3,1,true);
703 }
704
705
706
707 /*
708 * Sends a Tri-State "F" Bit
709 * _ ___
710 * Waveform: | |___| |_
711 */
712 void sendTF(void) {
713 transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
714 transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
715 // transmit(1,3,true);
716 // transmit(3,1,true);
717 }
718
719
720
721 /*
722 * Sends a "Sync" Bit
723 * _
724 * Waveform Protocol 1: | |_______________________________
725 * _
726 * Waveform Protocol 2: | |__________
727 * ____
728 * Waveform Protocol 3: | |_______________________________________________________________________
729 *
730 * Waveform Protocol D: (none, just pause 80 msecs)
731 */
732 void sendSync(void) {
733
734 if (rcProtocol == TYPE_A) {
735 transmit(1,31,true);
736 } else if (rcProtocol == TYPE_B) {
737 transmit(1,10,true);
738 } else if (rcProtocol == TYPE_C) {
739 transmit(4,71,true);
740 } else if (rcProtocol == TYPE_D) {
741 transmit(0,1,false);
742 delayMicroseconds(80000);
743 }
744 }
745
746
747
748 /*
749 * Enable receiving data
750 */
751 void enableReceiveIRQ(int Pin) {
752 rcReceiverInterruptPin = Pin;
753 enableReceive();
754 }
755
756 void enableReceive(void) {
757 if (rcReceiverInterruptPin != -1) {
758 rcReceivedValue = 0;
759 rcReceivedBitlength = 0;
760 wiringPiISR(rcReceiverInterruptPin, INT_EDGE_BOTH, &handleInterrupt);
761 }
762 }
763
764
765
766 /*
767 * Disable receiving data
768 */
769 void disableReceive() {
770 // wiringPi disable interrupts ???
771 rcReceiverInterruptPin = -1;
772 }
773
774
775
776 bool available(void) {
777 return rcReceivedValue != 0;
778 }
779
780
781
782 void resetAvailable(void) {
783 rcReceivedValue = 0;
784 }
785
786
787
788 unsigned long getReceivedValue(void) {
789 return rcReceivedValue;
790 }
791
792
793
794 unsigned int getReceivedBitlength(void) {
795 return rcReceivedBitlength;
796 }
797
798
799
800 unsigned int getReceivedDelay(void) {
801 return rcReceivedDelay;
802 }
803
804
805
806 unsigned int getReceivedProtocol(void) {
807 return rcReceivedProtocol;
808 }
809
810
811
812 unsigned int* getReceivedRawdata(void) {
813 return timings;
814 }
815
816
817
818 /*
819 * ASK protool 1
820 */
821 bool receiveProtocol(int prot, unsigned int changeCount)
822 {
823 unsigned long code = 0;
824 unsigned long ldelay = timings[0] / SYNC_FACTOR[prot];
825 unsigned long delayTolerance = ldelay * rcReceiveTolerance * 0.01;
826 int i;
827
828 if (prot < TYPE_MINIMUM || prot > TYPE_MAXIMUM) {
829 return false;
830 }
831
832 for (i = 1; i<changeCount ; i=i+2) {
833
834 if (timings[i] > ldelay * ZERO_FIRST_CYCLES[prot] - delayTolerance &&
835 timings[i] < ldelay * ZERO_FIRST_CYCLES[prot] + delayTolerance &&
836 timings[i+1] > ldelay * ZERO_SECOND_CYCLES[prot] - delayTolerance &&
837 timings[i+1] < ldelay * ZERO_SECOND_CYCLES[prot] + delayTolerance) {
838 code = code << 1;
839 } else if (timings[i] > ldelay * ONE_FIRST_CYCLES[prot] - delayTolerance &&
840 timings[i] < ldelay * ONE_FIRST_CYCLES[prot] + delayTolerance &&
841 timings[i+1] > ldelay * ONE_SECOND_CYCLES[prot] - delayTolerance &&
842 timings[i+1] < ldelay * ONE_SECOND_CYCLES[prot] + delayTolerance) {
843 code+=1;
844 code = code << 1;
845 } else {
846 // Failed
847 i = changeCount;
848 code = 0;
849 }
850 }
851 code = code >> 1;
852 if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise
853 rcReceivedValue = code;
854 rcReceivedBitlength = changeCount / 2;
855 rcReceivedDelay = ldelay;
856 rcReceivedProtocol = prot;
857 }
858
859 return (code != 0);
860 }
861
862
863
864 void handleInterrupt() {
865
866 static unsigned int duration;
867 static unsigned int changeCount;
868 static unsigned long lastTime;
869 static unsigned int repeatCount;
870
871
872 long thistime = micros();
873 duration = thistime - lastTime;
874
875 if (duration > 5000 && duration > timings[0] - 200 && duration < timings[0] + 200) {
876 repeatCount++;
877 changeCount--;
878 if (repeatCount == 2) {
879 if (receiveProtocol(TYPE_A, changeCount) == false) {
880 if (receiveProtocol(TYPE_B, changeCount) == false) {
881 if (receiveProtocol(TYPE_C, changeCount) == false) {
882 if (receiveProtocol(TYPE_D, changeCount) == false) {
883 //failed
884 }
885 }
886 }
887 }
888 repeatCount = 0;
889 }
890 changeCount = 0;
891 } else if (duration > 5000) {
892 changeCount = 0;
893 }
894
895 if (changeCount >= RCSWITCH_MAX_CHANGES) {
896 changeCount = 0;
897 repeatCount = 0;
898 }
899 timings[changeCount++] = duration;
900 lastTime = thistime;
901 }
902
903
904
905 /*
906 * Turns a decimal value to its binary representation
907 */
908 char *dec2binWzerofill(unsigned long Dec, unsigned int bitLength)
909 {
910 return dec2binWcharfill(Dec, bitLength, '0');
911 }
912
913 char *dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill)
914 {
915 static char bin[64];
916 unsigned int i = 0, j;
917
918 while (Dec > 0) {
919 bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill;
920 Dec = Dec >> 1;
921 }
922
923 for (j = 0; j< bitLength; j++) {
924 if (j >= bitLength - i) {
925 bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
926 } else {
927 bin[j] = fill;
928 }
929 }
930 bin[bitLength] = '\0';
931
932 return bin;
933 }
934
935
936 void saveProtocol(int prot)
937 {
938 backupProtocol = rcProtocol;
939 backupPulseLength = rcPulseLength;
940 backupRepeatTransmit = rcRepeatTransmit;
941
942 setProtocol(prot);
943 }
944
945
946
947 void loadProtocol(void)
948 {
949 rcProtocol = backupProtocol;
950 rcPulseLength = backupPulseLength;
951 rcRepeatTransmit = backupRepeatTransmit;
952 }
953
954
955 #endif
956

mercurial