1 // Unknown 433Mhz weather sensor decoder. Untested in the real world.
2 // http://arduino.cc/forum/index.php/topic,142871.msg1106336.html#msg1106336
6 // |_________| |______| |___| |
9 // | 9780us | 4420us | 2410us
13 #define DataBits0 4 // Number of data0 bits to expect
14 #define DataBits1 32 // Number of data1 bits to expect
15 #define allDataBits 36 // Number of data sum 0+1 bits to expect
16 // isrFlags bit numbers
17 #define F_HAVE_DATA 1 // 0=Nothing in read buffer, 1=Data in read buffer
18 #define F_GOOD_DATA 2 // 0=Unverified data, 1=Verified (2 consecutive matching reads)
19 #define F_CARRY_BIT 3 // Bit used to carry over bit shift from one long to the other
20 #define F_STATE 7 // 0=Sync mode, 1=Data mode
24 // uno: pin 2 = int.0 or pin 3 = int.1 see
25 // http://arduino.cc/en/Reference/attachInterrupt
30 const unsigned long sync_MIN = 9600; // Minimum Sync time in micro seconds
31 const unsigned long sync_MAX = 9900;
33 const unsigned long bit1_MIN = 4200;
34 const unsigned long bit1_MAX = 4600;
36 const unsigned long bit0_MIN = 2200;
37 const unsigned long bit0_MAX = 2600;
39 const unsigned long glitch_Length = 300; // Anything below this value is a glitch and will be ignored.
41 // Interrupt variables
42 unsigned long fall_Time = 0; // Placeholder for microsecond time when last falling edge occured.
43 unsigned long rise_Time = 0; // Placeholder for microsecond time when last rising edge occured.
44 byte bit_Count = 0; // Bit counter for received bits.
45 unsigned long build_Buffer[] = {0,0}; // Placeholder last data packet being received.
46 volatile unsigned long read_Buffer[] = {0,0}; // Placeholder last full data packet read.
47 volatile byte isrFlags = 0; // Various flag bits
49 void PinChangeISR(){ // Pin 2 (Interrupt 0) service routine
50 unsigned long Time = micros(); // Get current time
51 if (digitalRead(ISR_PIN) == LOW) {
53 if (Time > (rise_Time + glitch_Length)) {
55 Time = micros() - fall_Time; // Subtract last falling edge to get pulse time.
56 if (bitRead(build_Buffer[1],31) == 1)
57 bitSet(isrFlags, F_CARRY_BIT);
59 bitClear(isrFlags, F_CARRY_BIT);
61 if (bitRead(isrFlags, F_STATE) == 1) {
63 if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
65 build_Buffer[1] = build_Buffer[1] << 1;
66 build_Buffer[0] = build_Buffer[0] << 1;
67 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
68 bitSet(build_Buffer[0],0);
71 else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
73 build_Buffer[1] = build_Buffer[1] << 1;
74 bitSet(build_Buffer[1],0);
75 build_Buffer[0] = build_Buffer[0] << 1;
76 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
77 bitSet(build_Buffer[0],0);
81 // Not a 0 or 1 bit so restart data build and check if it's a sync?
85 bitClear(isrFlags, F_GOOD_DATA); // Signal data reads dont' match
86 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
87 if ((Time > sync_MIN) && (Time < sync_MAX)) {
89 bitSet(isrFlags, F_STATE); // Set data mode
92 if (bit_Count >= allDataBits) {
94 bitClear(isrFlags, F_GOOD_DATA); // Assume data reads don't match
95 if (build_Buffer[0] == read_Buffer[0]) {
96 if (build_Buffer[1] == read_Buffer[1])
97 bitSet(isrFlags, F_GOOD_DATA); // Set data reads match
99 read_Buffer[0] = build_Buffer[0];
100 read_Buffer[1] = build_Buffer[1];
101 bitSet(isrFlags, F_HAVE_DATA); // Set data available
102 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
103 digitalWrite(13,HIGH); // Used for debugging
111 if ((Time > sync_MIN) && (Time < sync_MAX)) {
116 bitSet(isrFlags, F_STATE); // Set data mode
117 digitalWrite(13,LOW); // Used for debugging
120 fall_Time = micros(); // Store fall time
125 if (Time > (fall_Time + glitch_Length)) {
127 rise_Time = Time; // Store rise time
134 pinMode(13,OUTPUT); // Used for debugging
136 pinMode(ISR_PIN,INPUT);
137 attachInterrupt(ISR_INT,PinChangeISR,CHANGE);
138 Serial.print("# Pin ");
139 Serial.print(ISR_PIN);
140 Serial.print(" int ");
141 Serial.print(ISR_INT);
142 Serial.println(" ISR attached");
146 if (bitRead(isrFlags,F_GOOD_DATA) == 1) {
152 void serial_dump(void) {
153 unsigned long myData0 = 0;
154 unsigned long myData1 = 0;
156 // We have at least 2 consecutive matching reads
157 myData0 = read_Buffer[0]; // first 4 bits
158 myData1 = read_Buffer[1]; // rest of 32 bits
159 bitClear(isrFlags,F_HAVE_DATA); // Flag we have read the data
162 Serial.print("# 0=");
163 dec2binLong(myData0,DataBits0);
165 dec2binLong(myData1,DataBits1);
169 Serial.print("temp=");
170 int temp = ( myData1 >> 8 ) & 0xFFF;
171 if ( temp & 0x800 ) temp = temp | 0xF000;
172 Serial.print(temp / 10.0, 1);
174 Serial.print(" humidity=");
175 Serial.print( myData1 & 0xFF );
177 byte b1 = ( myData1 >> 20 ); // second byte from received packet
179 Serial.print(" button=");
180 Serial.print( b1 & 0x04);
182 Serial.print(" battery=");
183 Serial.print( b1 & 0x08);
185 Serial.print(" channel=");
186 Serial.print( ( b1 & 0x03 ) + 1 );
188 Serial.print(" rid=");
189 Serial.println( myData1 >> 24 );
191 // remote but so we don't see this packet again
192 bitClear(isrFlags, F_GOOD_DATA);
196 void dec2binLong(unsigned long myNum, byte NumberOfBits) {
197 if (NumberOfBits <= 32){
198 myNum = myNum << (32 - NumberOfBits);
199 for (int i=0; i<NumberOfBits; i++) {
200 if (bitRead(myNum,31) == 1)
205 if ( i % 4 == 3 ) Serial.print(" ");