modified timings for my sensor
[Arduino] / outdoor_temperature_sensor / outdoor_temperature_sensor.ino
1 // Unknown 433Mhz weather sensor decoder. Untested in the real world.
2 // http://arduino.cc/forum/index.php/topic,142871.msg1106336.html#msg1106336
3
4 // __           ___       ___    ___
5 //   |         |  |      |  |   |  |
6 //   |_________|  |______|  |___|  |
7 //
8 //   |  Sync      |    1    |  0   |
9 //   |  9780us    | 4420us  | 2410us
10 //      9810        4410      2490
11
12 // Defines
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
21
22
23
24 // Constants
25 const unsigned long sync_MIN = 9600;                      // Minimum Sync time in micro seconds
26 const unsigned long sync_MAX = 9900;
27
28 const unsigned long bit1_MIN = 4200;
29 const unsigned long bit1_MAX = 4600;
30
31 const unsigned long bit0_MIN = 2200;
32 const unsigned long bit0_MAX = 2600;
33
34 const unsigned long glitch_Length = 300;                  // Anything below this value is a glitch and will be ignored.
35
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
43
44 void PinChangeISR0(){                                     // Pin 2 (Interrupt 0) service routine
45   unsigned long Time = micros();                          // Get current time
46   if (digitalRead(2) == LOW) {
47 // Falling edge
48     if (Time > (rise_Time + glitch_Length)) {
49 // Not a glitch
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);
53       else
54         bitClear(isrFlags, F_CARRY_BIT);
55
56       if (bitRead(isrFlags, F_STATE) == 1) {
57 // Looking for Data
58         if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
59 // 0 bit
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);
64           bit_Count++;
65         }
66         else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
67 // 1 bit
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);
73           bit_Count++;
74         }
75         else {
76 // Not a 0 or 1 bit so restart data build and check if it's a sync?
77           bit_Count = 0;
78           build_Buffer[0] = 0;
79           build_Buffer[1] = 0;
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)) {
83             // Sync length okay
84             bitSet(isrFlags, F_STATE);                    // Set data mode
85           }
86         }
87         if (bit_Count >= allDataBits) {
88 // All bits arrived
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
93           }
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
99           build_Buffer[0] = 0;
100           build_Buffer[1] = 0;
101           bit_Count = 0;
102         }
103       }
104       else {
105 // Looking for sync
106         if ((Time > sync_MIN) && (Time < sync_MAX)) {
107 // Sync length okay
108           build_Buffer[0] = 0;
109           build_Buffer[1] = 0;
110           bit_Count = 0;
111           bitSet(isrFlags, F_STATE);                      // Set data mode
112 digitalWrite(13,LOW); // Used for debugging
113         }
114       }
115       fall_Time = micros();                               // Store fall time
116     }
117   }
118   else {
119 // Rising edge
120     if (Time > (fall_Time + glitch_Length)) {
121       // Not a glitch
122       rise_Time = Time;                                   // Store rise time
123     }
124   }
125 }
126
127
128 void setup() {
129 pinMode(13,OUTPUT); // Used for debugging
130   Serial.begin(9600);
131   pinMode(2,INPUT);
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."));
135 }
136
137 void loop() {
138   unsigned long myData0 = 0;
139   unsigned long myData1 = 0;
140   if (bitRead(isrFlags,F_GOOD_DATA) == 1) 
141 {
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);
148
149     Serial.print(" - Battery=");
150     byte H = (myData1 >> 26) & 0x3;   // Get Battery
151     Serial.print(H);
152     
153     Serial.print(" Channel=");
154     H = ((myData1 >> 24) & 0x3) + 1;        // Get Channel
155     Serial.print(H);
156     
157     Serial.print(" Temperature=");
158     byte ML = (myData1 >> 12) & 0xF0; // Get MMMM
159 //     Serial.print(" (M=");
160 //     Serial.print(ML);
161     H = (myData1 >> 12) & 0xF;        // Get LLLL
162 //     Serial.print(" L=");
163 //     Serial.print(H);
164     ML = ML | H;                      // OR MMMM & LLLL nibbles together
165     H = (myData1 >> 20) & 0xF;        // Get HHHH
166 //     Serial.print(" H=");
167 //     Serial.print(H);
168 //     Serial.print(" T= ");
169     byte HH = 0;
170     if((myData1 >> 23) & 0x1 == 1) //23 bit
171          HH = 0xF;
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=");
180 //     Serial.print(H);
181     ML = (myData1 >> 0) & 0xF;       // Get LLLL
182 //     Serial.print(" L=");
183 //     Serial.print(ML);
184 //     Serial.print(") ");
185     ML = ML | H;                      // OR HHHH & LLLL nibbles together
186     Serial.print(ML);
187     Serial.println("%");
188
189     // remote but so we don't see this packet again
190     bitClear(isrFlags, F_GOOD_DATA);
191   }
192   delay(100);
193 }
194
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) 
200       Serial.print("1");
201       else 
202       Serial.print("0");
203       myNum = myNum << 1;
204     }
205   }
206 }