Merge branch 'master' of mjesec.ffzg.hr:/git/Arduino
[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 #define DEBUG 0
23
24 // uno: pin 2 = int.0 or pin 3 = int.1 see
25 // http://arduino.cc/en/Reference/attachInterrupt
26 #define ISR_PIN 2
27 #define ISR_INT 0
28
29 // Constants
30 const unsigned long sync_MIN = 9600;                      // Minimum Sync time in micro seconds
31 const unsigned long sync_MAX = 9900;
32
33 const unsigned long bit1_MIN = 4200;
34 const unsigned long bit1_MAX = 4600;
35
36 const unsigned long bit0_MIN = 2200;
37 const unsigned long bit0_MAX = 2600;
38
39 const unsigned long glitch_Length = 300;                  // Anything below this value is a glitch and will be ignored.
40
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
48
49 void PinChangeISR(){                                     // Pin 2 (Interrupt 0) service routine
50   unsigned long Time = micros();                          // Get current time
51   if (digitalRead(ISR_PIN) == LOW) {
52 // Falling edge
53     if (Time > (rise_Time + glitch_Length)) {
54 // Not a glitch
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);
58       else
59         bitClear(isrFlags, F_CARRY_BIT);
60
61       if (bitRead(isrFlags, F_STATE) == 1) {
62 // Looking for Data
63         if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
64 // 0 bit
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);
69           bit_Count++;
70         }
71         else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
72 // 1 bit
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);
78           bit_Count++;
79         }
80         else {
81 // Not a 0 or 1 bit so restart data build and check if it's a sync?
82           bit_Count = 0;
83           build_Buffer[0] = 0;
84           build_Buffer[1] = 0;
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)) {
88             // Sync length okay
89             bitSet(isrFlags, F_STATE);                    // Set data mode
90           }
91         }
92         if (bit_Count >= allDataBits) {
93 // All bits arrived
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
98           }
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
104           build_Buffer[0] = 0;
105           build_Buffer[1] = 0;
106           bit_Count = 0;
107         }
108       }
109       else {
110 // Looking for sync
111         if ((Time > sync_MIN) && (Time < sync_MAX)) {
112 // Sync length okay
113           build_Buffer[0] = 0;
114           build_Buffer[1] = 0;
115           bit_Count = 0;
116           bitSet(isrFlags, F_STATE);                      // Set data mode
117 digitalWrite(13,LOW); // Used for debugging
118         }
119       }
120       fall_Time = micros();                               // Store fall time
121     }
122   }
123   else {
124 // Rising edge
125     if (Time > (fall_Time + glitch_Length)) {
126       // Not a glitch
127       rise_Time = Time;                                   // Store rise time
128     }
129   }
130 }
131
132
133 void setup() {
134   pinMode(13,OUTPUT); // Used for debugging
135   Serial.begin(9600);
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");
143 }
144
145 void loop() {
146   if (bitRead(isrFlags,F_GOOD_DATA) == 1) {
147     serial_dump();
148     delay(100);
149   }
150 }
151
152 void serial_dump(void) {
153     unsigned long myData0 = 0;
154     unsigned long myData1 = 0;
155
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
160
161 if (DEBUG) {
162     Serial.print("# 0=");
163     dec2binLong(myData0,DataBits0);
164     Serial.print(" 1=");
165     dec2binLong(myData1,DataBits1);
166     Serial.println();
167 }
168
169     Serial.print("temp=");
170     int temp = ( myData1 >> 8 ) & 0xFFF;
171     if ( temp & 0x800 ) temp = temp | 0xF000;
172     Serial.print(temp / 10.0, 1);
173
174     Serial.print(" humidity=");
175     Serial.print( myData1 & 0xFF );
176
177     byte b1 = ( myData1 >> 20 ); // second byte from received packet
178
179     Serial.print(" button=");
180     Serial.print( b1 & 0x04);
181
182     Serial.print(" battery=");
183     Serial.print( b1 & 0x08);
184
185     Serial.print(" channel=");
186     Serial.print( ( b1 & 0x03 ) + 1 );
187
188     Serial.print(" rid=");
189     Serial.println( myData1 >> 24 );
190
191     // remote but so we don't see this packet again
192     bitClear(isrFlags, F_GOOD_DATA);
193
194 }
195
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) 
201       Serial.print("1");
202       else 
203       Serial.print("0");
204       myNum = myNum << 1;
205       if ( i % 4 == 3 ) Serial.print(" ");
206     }
207   }
208 }