Improved rc-switch library to be more flexible.

Wed, 07 May 2014 23:01:18 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 07 May 2014 23:01:18 +0200
changeset 29
ac763b87ee25
parent 28
32ed1ea4d0b6
child 30
9c7119ac0455

Improved rc-switch library to be more flexible.

coolers/coolers.c file | annotate | diff | comparison | revisions
lib/mbselib.h file | annotate | diff | comparison | revisions
lib/rc-switch.c file | annotate | diff | comparison | revisions
rc433/recv.c file | annotate | diff | comparison | revisions
rc433/send.c file | annotate | diff | comparison | revisions
--- a/coolers/coolers.c	Tue May 06 21:37:06 2014 +0200
+++ b/coolers/coolers.c	Wed May 07 23:01:18 2014 +0200
@@ -28,7 +28,7 @@
 #ifdef HAVE_WIRINGPI_H
 
 
-int			tempA = 240;
+int			tempA = 170;
 int			tempB = 250;
 int			coolerA = 0;
 int			coolerB = 0;
--- a/lib/mbselib.h	Tue May 06 21:37:06 2014 +0200
+++ b/lib/mbselib.h	Wed May 07 23:01:18 2014 +0200
@@ -104,20 +104,6 @@
 
 
 /* rc-switch.c */
-#define CHANGE 1
-
-//typedef uint8_t boolean;
-//typedef uint8_t byte;
-
-// Number of maximum High/Low changes per packet.
-// We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
-#define RCSWITCH_MAX_CHANGES 67
-
-#define PROTOCOL3_SYNC_FACTOR   71
-#define PROTOCOL3_0_HIGH_CYCLES  4
-#define PROTOCOL3_0_LOW_CYCLES  11
-#define PROTOCOL3_1_HIGH_CYCLES  9
-#define PROTOCOL3_1_LOW_CYCLES   6
 
 int  toggleSwitch(char *);
 int  toggleTypeA(char *, char *, bool);
@@ -139,10 +125,8 @@
 
 void enableTransmit(int);
 void disableTransmit(void);
-void setPulseLength(int);
-void setRepeatTransmit(int);
-void setReceiveTolerance(int);
-void setProtocol(int);
+
+char *dec2binWzerofill(unsigned long, unsigned int);
 
 #endif
 
--- a/lib/rc-switch.c	Tue May 06 21:37:06 2014 +0200
+++ b/lib/rc-switch.c	Wed May 07 23:01:18 2014 +0200
@@ -28,6 +28,64 @@
 
 #ifdef HAVE_WIRINGPI_H
 
+
+#define	TYPE_UNDEF	0
+#define	TYPE_MINIMUM	0
+#define	TYPE_A		1
+#define	TYPE_B		2
+#define	TYPE_C		3
+#define	TYPE_D		4
+#define	TYPE_E		3  // TODO: Which Protocol does REV use?
+#define	TYPE_MAXIMUM	4
+
+// Number of maximum High/Low changes per packet.
+// We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
+#define RCSWITCH_MAX_CHANGES 67
+
+// i.e. ProtocolCount + 1 (for TYPE_UNDEF)
+#define MAX_PROTOCOLS                   5
+
+#define PROTOCOL_A_SYNC_FACTOR         31
+#define PROTOCOL_A_ZERO_FIRST_CYCLES    1
+#define PROTOCOL_A_ZERO_SECOND_CYCLES   3
+#define PROTOCOL_A_ONE_FIRST_CYCLES     3
+#define PROTOCOL_A_ONE_SECOND_CYCLES    1
+#define PROTOCOL_A_HIGH_FIRST        true
+
+#define PROTOCOL_B_SYNC_FACTOR         10
+#define PROTOCOL_B_ZERO_FIRST_CYCLES    1
+#define PROTOCOL_B_ZERO_SECOND_CYCLES   2
+#define PROTOCOL_B_ONE_FIRST_CYCLES     2
+#define PROTOCOL_B_ONE_SECOND_CYCLES    1
+#define PROTOCOL_B_HIGH_FIRST        true
+
+#define PROTOCOL_C_SYNC_FACTOR         71
+#define PROTOCOL_C_ZERO_FIRST_CYCLES    4
+#define PROTOCOL_C_ZERO_SECOND_CYCLES  11
+#define PROTOCOL_C_ONE_FIRST_CYCLES     9
+#define PROTOCOL_C_ONE_SECOND_CYCLES    6
+#define PROTOCOL_C_HIGH_FIRST        true
+
+// I think, this will work for receive, however, I haven't tested, as I don't own a receiver...
+// As Type D doesn't sync acc. to https://github.com/d-a-n/433-codes/blob/master/database.md#quigg
+// the sync factor is totally undetermined.
+// Malte Diers, 22.11.2013
+#define PROTOCOL_D_SYNC_FACTOR          1
+#define PROTOCOL_D_ZERO_FIRST_CYCLES    1
+#define PROTOCOL_D_ZERO_SECOND_CYCLES   2
+#define PROTOCOL_D_ONE_FIRST_CYCLES     2
+#define PROTOCOL_D_ONE_SECOND_CYCLES    1
+#define PROTOCOL_D_HIGH_FIRST       false
+
+
+#define PROTOCOL3_SYNC_FACTOR   71
+#define PROTOCOL3_0_HIGH_CYCLES  4
+#define PROTOCOL3_0_LOW_CYCLES  11
+#define PROTOCOL3_1_HIGH_CYCLES  9
+#define PROTOCOL3_1_LOW_CYCLES   6
+
+
+
 unsigned long	rcReceivedValue = 0;
 unsigned int	rcReceivedBitlength = 0;
 unsigned int	rcReceivedDelay = 0;
@@ -37,16 +95,30 @@
 
 unsigned int	timings[RCSWITCH_MAX_CHANGES];
 int		rcTransmitterPin = -1;
-int		rcPulseLength = 350;
+int		rcPulseLength = 350;	// thermometers 2.4 msec = 2400
 int		rcRepeatTransmit = 10;
 int		rcProtocol = 1;
 
+int		backupProtocol;
+int		backupPulseLength;
+int		backupRepeatTransmit;
+
+
 //const char TYPE_A_CODE[ 6][6]  = { "00000", "10000", "01000", "00100", "00010", "00001"};
 const char TYPE_B_CODE[ 5][5]  = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" };
 const char TYPE_C_CODE[16][5]  = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0",
 				   "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" };
 const char TYPE_D_CODE[5][2][9] = { { "11100001", "11110000" }, { "00000000", "00010001" }, { "10000010", "10010011" },
 				    { "11000011", "11010010" }, { "01000001", "01010000" } };
+					/* Type A            Type D */
+const int  PULSE_LENGTH[MAX_PROTOCOLS] 		= { 0, 350, 650, 100, 666, };
+const int  REPEAT_TRANSMIT[MAX_PROTOCOLS] 	= { 0, 10, 10, 10, 4, };
+const int  SYNC_FACTOR[MAX_PROTOCOLS]		= { 0, PROTOCOL_A_SYNC_FACTOR, PROTOCOL_B_SYNC_FACTOR, PROTOCOL_C_SYNC_FACTOR, PROTOCOL_D_SYNC_FACTOR, };
+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, };
+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, };
+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, };
+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, };
+const bool HIGH_FIRST[MAX_PROTOCOLS]        = { 0, PROTOCOL_A_HIGH_FIRST, PROTOCOL_B_HIGH_FIRST, PROTOCOL_C_HIGH_FIRST, PROTOCOL_D_HIGH_FIRST, };
 
 
 char *getCodeWordA(char*, char*, bool);
@@ -55,7 +127,7 @@
 
 char *getCodeWordE(char, int, bool);
 void sendTriState(char*);
-void transmit(int, int);
+void transmit(int, int, bool);
 void send0(void);
 void send1(void);
 void sendT0(void);
@@ -66,9 +138,13 @@
 bool receiveProtocol2(unsigned int);
 bool receiveProtocol3(unsigned int);
 void handleInterrupt(void);
-char *dec2binWzerofill(unsigned long, unsigned int);
 char *dec2binWcharfill(unsigned long, unsigned int, char);
 
+void setReceiveTolerance(int);
+void setProtocol(int);
+
+void saveProtocol(int);
+void loadProtocol(void);
 
 
 
@@ -76,44 +152,14 @@
  * Sets the protocol to send.
  */
 void setProtocol(int nProtocol) {
-  rcProtocol = nProtocol;
-  if (nProtocol == 1){
-	  setPulseLength(350);
-  }
-  else if (nProtocol == 2) {
-	  setPulseLength(650);
-  }
-  else if (nProtocol == 3) {
-    setPulseLength(100);
-  }
-}
-
-
 
-/**
-  * Sets the protocol to send with pulse length in microseconds.
-  */
-/*void RCSwitch::setProtocol(int nProtocol, int nPulseLength) {
-  this->nProtocol = nProtocol;
-  this->setPulseLength(nPulseLength);
-}*/
-
-
+    if ((nProtocol < TYPE_MINIMUM) || (nProtocol > TYPE_MAXIMUM)) {
+	return;
+    }
 
-/*
- * Sets pulse length in microseconds
- */
-void setPulseLength(int nPulseLength) {
-    rcPulseLength = nPulseLength;
-}
-
-
-
-/*
- * Sets Repeat Transmits
- */
-void setRepeatTransmit(int nRepeatTransmit) {
-    rcRepeatTransmit = nRepeatTransmit;
+    rcProtocol = nProtocol;
+    rcPulseLength = PULSE_LENGTH[nProtocol];
+    rcRepeatTransmit = REPEAT_TRANSMIT[nProtocol];
 }
 
 
@@ -126,6 +172,7 @@
 }
 
 
+
 /*
  * Enable transmissions
  *
@@ -209,7 +256,15 @@
  * @param bStatus  Status to toggle to
  */
 int toggleTypeC(char sFamily, int nGroup, int nDevice, bool bStatus) {
-    sendTriState( getCodeWordC(sFamily, nGroup, nDevice, bStatus) );
+    char *str = xstrcpy(getCodeWordC(sFamily, nGroup, nDevice, bStatus));
+
+    if (strlen(str) == 0)
+	return 1;
+
+    saveProtocol(TYPE_A);	// ???
+    sendTriState( str );
+    loadProtocol();
+    free(str);
     return 0;
 }
 
@@ -229,9 +284,9 @@
     if (strlen(str) == 0)
 	return 1;
 
-//    save(TYPE_B);
+    saveProtocol(TYPE_A);	// They do better with protocol A timings.
     sendTriState( str );
-//    load();
+    loadProtocol();
     free(str);
     return 0;
 }
@@ -246,7 +301,15 @@
  * @param bStatus   Status to toggle to
  */
 int toggleTypeA(char* sGroup, char* sDevice, bool bStatus) {
-    sendTriState( getCodeWordA(sGroup, sDevice, bStatus) );
+    char *str = xstrcpy(getCodeWordA(sGroup, sDevice, bStatus));
+
+    if (strlen(str) == 0)
+	return 1;
+
+    saveProtocol(TYPE_A);
+    sendTriState( str );
+    loadProtocol();
+    free(str);
     return 0;
 }
 
@@ -546,7 +609,7 @@
 */
 
 
-void transmit(int nHighPulses, int nLowPulses)
+void transmit(int nFirstPulses, int nSecondPulses, bool bHighFirst)
 {
     bool	disabled_Receive = false;
     int		nReceiverInterrupt_backup = rcReceiverInterruptPin;
@@ -556,10 +619,10 @@
             disableReceive();
             disabled_Receive = true;
         }
-        digitalWrite(rcTransmitterPin, HIGH);
-	delayMicroseconds( rcPulseLength * nHighPulses);
-        digitalWrite(rcTransmitterPin, LOW);
-	delayMicroseconds( rcPulseLength * nLowPulses);
+        digitalWrite(rcTransmitterPin, bHighFirst ? HIGH : LOW);
+	delayMicroseconds( rcPulseLength * nFirstPulses);
+        digitalWrite(rcTransmitterPin, bHighFirst ? LOW : HIGH);
+	delayMicroseconds( rcPulseLength * nSecondPulses);
         
         if (disabled_Receive) {
             enableReceiveIRQ(nReceiverInterrupt_backup);
@@ -578,17 +641,17 @@
  *                       ____
  * Waveform Protocol 3: |    |___________
  */
-void send0(void) {
-	if (rcProtocol == 1){
-		transmit(1,3);
-	}
-	else if (rcProtocol == 2) {
-		transmit(1,2);
-	}
-    else if (rcProtocol == 3) {
-        transmit(4,11);
-    }
-}
+//void send0(void) {
+//	if (rcProtocol == 1){
+//		transmit(1,3);
+//	}
+//	else if (rcProtocol == 2) {
+//		transmit(1,2);
+//	}
+//    else if (rcProtocol == 3) {
+//        transmit(4,11);
+//    }
+//}
 
 
 
@@ -601,17 +664,17 @@
  *                       _________
  * Waveform Protocol 3: |         |______
  */
-void send1(void) {
-  	if (rcProtocol == 1){
-		transmit(3,1);
-	}
-	else if (rcProtocol == 2) {
-		transmit(2,1);
-	}
-    else if (rcProtocol == 3) {
-        transmit(9,6);
-    }
-}
+//void send1(void) {
+//  	if (rcProtocol == 1){
+//		transmit(3,1);
+//	}
+//	else if (rcProtocol == 2) {
+//		transmit(2,1);
+//	}
+//    else if (rcProtocol == 3) {
+//        transmit(9,6);
+//    }
+//}
 
 
 
@@ -621,8 +684,10 @@
  * Waveform: | |___| |___
  */
 void sendT0(void) {
-    transmit(1,3);
-    transmit(1,3);
+    transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
+    transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
+//    transmit(1,3,true);
+//    transmit(1,3,true);
 }
 
 
@@ -633,8 +698,10 @@
  * Waveform: |   |_|   |_
  */
 void sendT1(void) {
-    transmit(3,1);
-    transmit(3,1);
+    transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
+    transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
+//    transmit(3,1,true);
+//    transmit(3,1,true);
 }
 
 
@@ -645,8 +712,10 @@
  * Waveform: | |___|   |_
  */
 void sendTF(void) {
-    transmit(1,3);
-    transmit(3,1);
+    transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);   
+    transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]);
+//    transmit(1,3,true);
+//    transmit(3,1,true);
 }
 
 
@@ -657,19 +726,22 @@
  * Waveform Protocol 1: | |_______________________________
  *                       _
  * Waveform Protocol 2: | |__________
- *                       _
- * Waveform Protocol 3: | |_______________________________________________________________________
+ *                       ____
+ * Waveform Protocol 3: |    |_______________________________________________________________________
+ *
+ * Waveform Protocol D: (none, just pause 80 msecs)
  */
 void sendSync(void) {
 
-    if (rcProtocol == 1){
-		transmit(1,31);
-	}
-	else if (rcProtocol == 2) {
-		transmit(1,10);
-	}
-    else if (rcProtocol == 3) {
-        transmit(1,71);
+    if (rcProtocol == TYPE_A) {
+	transmit(1,31,true);
+    } else if (rcProtocol == TYPE_B) {
+	transmit(1,10,true);
+    } else if (rcProtocol == TYPE_C) {
+        transmit(4,71,true);
+    } else if (rcProtocol == TYPE_D) {
+	transmit(0,1,false);
+	delayMicroseconds(80000);
     }
 }
 
@@ -748,24 +820,28 @@
 /*
  * ASK protool 1
  */
-bool receiveProtocol1(unsigned int changeCount)
+bool receiveProtocol(int prot, unsigned int changeCount)
 {
     unsigned long	code = 0;
-    unsigned long	ldelay = timings[0] / 31;
+    unsigned long	ldelay = timings[0] / SYNC_FACTOR[prot];
     unsigned long	delayTolerance = ldelay * rcReceiveTolerance * 0.01;    
     int			i;
 
+    if (prot < TYPE_MINIMUM || prot > TYPE_MAXIMUM) {
+	return false;
+    }
+
     for (i = 1; i<changeCount ; i=i+2) {
       
-	if (timings[i] > ldelay-delayTolerance && 
-	    timings[i] < ldelay+delayTolerance && 
-	    timings[i+1] > ldelay*3-delayTolerance && 
-	    timings[i+1] < ldelay*3+delayTolerance) {
+	if (timings[i]   > ldelay * ZERO_FIRST_CYCLES[prot]  - delayTolerance && 
+	    timings[i]   < ldelay * ZERO_FIRST_CYCLES[prot]  + delayTolerance && 
+	    timings[i+1] > ldelay * ZERO_SECOND_CYCLES[prot] - delayTolerance && 
+	    timings[i+1] < ldelay * ZERO_SECOND_CYCLES[prot] + delayTolerance) {
       	    code = code << 1;
-    	}  else if (timings[i] > ldelay*3-delayTolerance &&
-		    timings[i] < ldelay*3+delayTolerance &&
-		    timings[i+1] > ldelay-delayTolerance &&
-		    timings[i+1] < ldelay+delayTolerance) {
+    	}  else if (timings[i]   > ldelay * ONE_FIRST_CYCLES[prot]  - delayTolerance &&
+		    timings[i]   < ldelay * ONE_FIRST_CYCLES[prot]  + delayTolerance &&
+		    timings[i+1] > ldelay * ONE_SECOND_CYCLES[prot] - delayTolerance &&
+		    timings[i+1] < ldelay * ONE_SECOND_CYCLES[prot] + delayTolerance) {
 	    code+=1;
 	    code = code << 1;
 	} else {
@@ -779,13 +855,10 @@
     	rcReceivedValue = code;
     	rcReceivedBitlength = changeCount / 2;
     	rcReceivedDelay = ldelay;
-    	rcReceivedProtocol = 1;
+    	rcReceivedProtocol = prot;
     }
 
-    if (code == 0) {
-    	return false;
-    }
-    return true;
+    return (code != 0);
 }
 
 
@@ -892,9 +965,9 @@
     repeatCount++;
     changeCount--;
     if (repeatCount == 2) {
-      if (receiveProtocol1(changeCount) == false){
-        if (receiveProtocol2(changeCount) == false){
-	  if (receiveProtocol3(changeCount) == false){
+      if (receiveProtocol(TYPE_A, changeCount) == false){
+        if (receiveProtocol(TYPE_B, changeCount) == false){
+	  if (receiveProtocol(TYPE_C, changeCount) == false){
             //failed
 	  }
         }
@@ -947,5 +1020,24 @@
 }
 
 
+void saveProtocol(int prot)
+{
+    backupProtocol = rcProtocol;
+    backupPulseLength = rcPulseLength;
+    backupRepeatTransmit = rcRepeatTransmit;
+
+    setProtocol(prot);
+}
+
+
+
+void loadProtocol(void)
+{
+    rcProtocol = backupProtocol;
+    rcPulseLength = backupPulseLength;
+    rcRepeatTransmit = backupRepeatTransmit;
+}
+
+
 #endif
 
--- a/rc433/recv.c	Tue May 06 21:37:06 2014 +0200
+++ b/rc433/recv.c	Wed May 07 23:01:18 2014 +0200
@@ -43,12 +43,26 @@
     while (1) {
 	if (available()) {
 		         
-	    int value = getReceivedValue();
+	    unsigned long int value = getReceivedValue();
+	    int bitlen = getReceivedBitlength();
 			     
 	    if (value == 0) {
 		printf("Unknown encoding\n");
 	    } else {
-		printf("Received %ld/%d bit Protocol: %d\n", getReceivedValue(), getReceivedBitlength(), getReceivedProtocol() );
+		if (bitlen == 24) {
+		    printf("Received 0x%06lx/24 bit %s Protocol: %d", value, dec2binWzerofill(value, bitlen), getReceivedProtocol() );
+		    if ((value & 0x00000000000003f0) == 0x0000000000000150) {
+			printf(" Type A ");
+			printf("%c%c%c%c%c ", (value & 0xc00000) ? '0' : '1', (value & 0x300000) ? '0' : '1', (value & 0x0c0000) ? '0' : '1', (value & 0x030000) ? '0' : '1', (value & 0x00c000) ? '0' : '1');
+			printf("%c%c%c%c%c ", (value & 0x003000) ? '0' : '1', (value & 0x000c00) ? '0' : '1', (value & 0x000300) ? '0' : '1', (value & 0x0000c0) ? '0' : '1', (value & 0x000030) ? '0' : '1');
+		    }
+		    if ((value & 0x000000000000001c) == 0x0000000000000000) {
+			printf(" Type E");
+		    }
+		    printf("\n");
+		} else {
+		    printf("Received 0x%lx/%d bit %s Protocol: %d\n", value, bitlen, dec2binWzerofill(value, bitlen), getReceivedProtocol() );
+		}
 	    }
 
 	    resetAvailable();
--- a/rc433/send.c	Tue May 06 21:37:06 2014 +0200
+++ b/rc433/send.c	Wed May 07 23:01:18 2014 +0200
@@ -99,7 +99,7 @@
 	    case 'g':	snprintf(buf, 127, "%s", optarg);
 			if (cType == 'A') {
 			    sGroup = xstrcpy(buf);
-			} else if (cType == 'D') {
+			} else if (cType == 'E') {
 			    cGroup = toupper(buf[0]);
 			} else {
 			    iGroup = strtol(buf, &endptr, 10);

mercurial