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
25 const unsigned long sync_MIN = 9600; // Minimum Sync time in micro seconds
26 const unsigned long sync_MAX = 9900;
28 const unsigned long bit1_MIN = 4200;
29 const unsigned long bit1_MAX = 4600;
31 const unsigned long bit0_MIN = 2200;
32 const unsigned long bit0_MAX = 2600;
34 const unsigned long glitch_Length = 300; // Anything below this value is a glitch and will be ignored.
36 // Interrupt variables
37 unsigned long fall_Time = 0; // Placeholder for microsecond time when last falling edge occured.
38 unsigned long rise_Time = 0; // Placeholder for microsecond time when last rising edge occured.
39 byte bit_Count = 0; // Bit counter for received bits.
40 unsigned long build_Buffer[] = {0,0}; // Placeholder last data packet being received.
41 volatile unsigned long read_Buffer[] = {0,0}; // Placeholder last full data packet read.
42 volatile byte isrFlags = 0; // Various flag bits
44 void PinChangeISR0(){ // Pin 2 (Interrupt 0) service routine
45 unsigned long Time = micros(); // Get current time
46 if (digitalRead(2) == LOW) {
48 if (Time > (rise_Time + glitch_Length)) {
50 Time = micros() - fall_Time; // Subtract last falling edge to get pulse time.
51 if (bitRead(build_Buffer[1],31) == 1)
52 bitSet(isrFlags, F_CARRY_BIT);
54 bitClear(isrFlags, F_CARRY_BIT);
56 if (bitRead(isrFlags, F_STATE) == 1) {
58 if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
60 build_Buffer[1] = build_Buffer[1] << 1;
61 build_Buffer[0] = build_Buffer[0] << 1;
62 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
63 bitSet(build_Buffer[0],0);
66 else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
68 build_Buffer[1] = build_Buffer[1] << 1;
69 bitSet(build_Buffer[1],0);
70 build_Buffer[0] = build_Buffer[0] << 1;
71 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
72 bitSet(build_Buffer[0],0);
76 // Not a 0 or 1 bit so restart data build and check if it's a sync?
80 bitClear(isrFlags, F_GOOD_DATA); // Signal data reads dont' match
81 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
82 if ((Time > sync_MIN) && (Time < sync_MAX)) {
84 bitSet(isrFlags, F_STATE); // Set data mode
87 if (bit_Count >= allDataBits) {
89 bitClear(isrFlags, F_GOOD_DATA); // Assume data reads don't match
90 if (build_Buffer[0] == read_Buffer[0]) {
91 if (build_Buffer[1] == read_Buffer[1])
92 bitSet(isrFlags, F_GOOD_DATA); // Set data reads match
94 read_Buffer[0] = build_Buffer[0];
95 read_Buffer[1] = build_Buffer[1];
96 bitSet(isrFlags, F_HAVE_DATA); // Set data available
97 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
98 digitalWrite(13,HIGH); // Used for debugging
106 if ((Time > sync_MIN) && (Time < sync_MAX)) {
111 bitSet(isrFlags, F_STATE); // Set data mode
112 digitalWrite(13,LOW); // Used for debugging
115 fall_Time = micros(); // Store fall time
120 if (Time > (fall_Time + glitch_Length)) {
122 rise_Time = Time; // Store rise time
129 pinMode(13,OUTPUT); // Used for debugging
132 Serial.println(F("ISR Pin 2 Configured For Input."));
133 attachInterrupt(0,PinChangeISR0,CHANGE);
134 Serial.println(F("Pin 2 ISR Function Attached. Here we go."));
138 unsigned long myData0 = 0;
139 unsigned long myData1 = 0;
140 if (bitRead(isrFlags,F_GOOD_DATA) == 1)
142 // We have at least 2 consecutive matching reads
143 myData0 = read_Buffer[0]; // Read the data spread over 2x 32 variables
144 myData1 = read_Buffer[1];
145 bitClear(isrFlags,F_HAVE_DATA); // Flag we have read the data
146 dec2binLong(myData0,DataBits0);
147 dec2binLong(myData1,DataBits1);
149 Serial.print(" - Battery=");
150 byte H = (myData1 >> 26) & 0x3; // Get Battery
153 Serial.print(" Channel=");
154 H = ((myData1 >> 24) & 0x3) + 1; // Get Channel
157 Serial.print(" Temperature=");
158 byte ML = (myData1 >> 12) & 0xF0; // Get MMMM
159 // Serial.print(" (M=");
161 H = (myData1 >> 12) & 0xF; // Get LLLL
162 // Serial.print(" L=");
164 ML = ML | H; // OR MMMM & LLLL nibbles together
165 H = (myData1 >> 20) & 0xF; // Get HHHH
166 // Serial.print(" H=");
168 // Serial.print(" T= ");
170 if((myData1 >> 23) & 0x1 == 1) //23 bit
172 int Temperature = (H << 8)|(HH << 12) | ML; // Combine HHHH MMMMLLLL
173 // Serial.print( Temperature);
174 // Serial.print(") ");
175 // Temperature = Temperature*3; //F // Remove Constant offset
176 Serial.print(Temperature/10.0,1);
177 Serial.print("C Humidity=");
178 H = (myData1 >> 0) & 0xF0; // Get HHHH
179 // Serial.print(" (H=");
181 ML = (myData1 >> 0) & 0xF; // Get LLLL
182 // Serial.print(" L=");
184 // Serial.print(") ");
185 ML = ML | H; // OR HHHH & LLLL nibbles together
189 // remote but so we don't see this packet again
190 bitClear(isrFlags, F_GOOD_DATA);
195 void dec2binLong(unsigned long myNum, byte NumberOfBits) {
196 if (NumberOfBits <= 32){
197 myNum = myNum << (32 - NumberOfBits);
198 for (int i=0; i<NumberOfBits; i++) {
199 if (bitRead(myNum,31) == 1)