thermferm/rc-switch.c

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

mercurial