rc433/rc-switch.c

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

mercurial