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 // | 8320us | 4500us | 2530us
12 #define allDataBits 42 // Number of data bits to expect
13 // isrFlags bit numbers
14 #define F_HAVE_DATA 1 // 0=Nothing in read buffer, 1=Data in read buffer
15 #define F_GOOD_DATA 2 // 0=Unverified data, 1=Verified (2 consecutive matching reads)
16 #define F_CARRY_BIT 3 // Bit used to carry over bit shift from one long to the other
17 #define F_STATE 7 // 0=Sync mode, 1=Data mode
20 const unsigned long sync_MIN = 8120; // Minimum Sync time in micro seconds
21 const unsigned long sync_MAX = 8520;
22 const unsigned long bit1_MIN = 4300;
23 const unsigned long bit1_MAX = 4700;
24 const unsigned long bit0_MIN = 2330;
25 const unsigned long bit0_MAX = 2730;
26 const unsigned long glitch_Length = 300; // Anything below this value is a glitch and will be ignored.
28 // Interrupt variables
29 unsigned long fall_Time = 0; // Placeholder for microsecond time when last falling edge occured.
30 unsigned long rise_Time = 0; // Placeholder for microsecond time when last rising edge occured.
31 byte bit_Count = 0; // Bit counter for received bits.
32 unsigned long build_Buffer[] = {0,0}; // Placeholder last data packet being received.
33 volatile unsigned long read_Buffer[] = {0,0}; // Placeholder last full data packet read.
34 volatile byte isrFlags = 0; // Various flag bits
36 void PinChangeISR0(){ // Pin 2 (Interrupt 0) service routine
37 unsigned long Time = micros(); // Get current time
38 if (digitalRead(2) == LOW) {
40 if (Time > (rise_Time + glitch_Length)) {
42 Time = micros() - fall_Time; // Subtract last falling edge to get pulse time.
43 if (bitRead(build_Buffer[1],31) == 1)
44 bitSet(isrFlags, F_CARRY_BIT);
46 bitClear(isrFlags, F_CARRY_BIT);
48 if (bitRead(isrFlags, F_STATE) == 1) {
50 if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
52 build_Buffer[1] = build_Buffer[1] << 1;
53 build_Buffer[0] = build_Buffer[0] << 1;
54 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
55 bitSet(build_Buffer[0],0);
58 else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
60 build_Buffer[1] = build_Buffer[1] << 1;
61 bitSet(build_Buffer[1],0);
62 build_Buffer[0] = build_Buffer[0] << 1;
63 if (bitRead(isrFlags,F_CARRY_BIT) == 1)
64 bitSet(build_Buffer[0],0);
68 // Not a 0 or 1 bit so restart data build and check if it's a sync?
72 bitClear(isrFlags, F_GOOD_DATA); // Signal data reads dont' match
73 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
74 if ((Time > sync_MIN) && (Time < sync_MAX)) {
76 bitSet(isrFlags, F_STATE); // Set data mode
79 if (bit_Count >= allDataBits) {
81 bitClear(isrFlags, F_GOOD_DATA); // Assume data reads don't match
82 if (build_Buffer[0] == read_Buffer[0]) {
83 if (build_Buffer[1] == read_Buffer[1])
84 bitSet(isrFlags, F_GOOD_DATA); // Set data reads match
86 read_Buffer[0] = build_Buffer[0];
87 read_Buffer[1] = build_Buffer[1];
88 bitSet(isrFlags, F_HAVE_DATA); // Set data available
89 bitClear(isrFlags, F_STATE); // Set looking for Sync mode
90 digitalWrite(13,HIGH); // Used for debugging
98 if ((Time > sync_MIN) && (Time < sync_MAX)) {
103 bitSet(isrFlags, F_STATE); // Set data mode
104 digitalWrite(13,LOW); // Used for debugging
107 fall_Time = micros(); // Store fall time
112 if (Time > (fall_Time + glitch_Length)) {
114 rise_Time = Time; // Store rise time
121 pinMode(13,OUTPUT); // Used for debugging
124 Serial.println(F("ISR Pin 2 Configured For Input."));
125 attachInterrupt(0,PinChangeISR0,CHANGE);
126 Serial.println(F("Pin 2 ISR Function Attached. Here we go."));
130 unsigned long myData0 = 0;
131 unsigned long myData1 = 0;
132 if (bitRead(isrFlags,F_GOOD_DATA) == 1) {
133 // We have at least 2 consecutive matching reads
134 myData0 = read_Buffer[0]; // Read the data spread over 2x 32 variables
135 myData1 = read_Buffer[1];
136 bitClear(isrFlags,F_HAVE_DATA); // Flag we have read the data
137 dec2binLong(myData0,10);
138 dec2binLong(myData1,32);
140 Serial.print(" - Battery=");
141 byte H = (myData1 >> 30) & 0x3; // Get Battery
143 Serial.print(" Channel=");
144 H = (myData1 >> 28) & 0x3; // Get Channel
146 Serial.print(" Temperature=");
147 byte ML = (myData1 >> 16) & 0xF0; // Get MMMM
148 H = (myData1 >> 24) & 0xF; // Get LLLL
149 ML = ML | H; // OR MMMM & LLLL nibbles together
150 H = (myData1 >> 16) & 0xF; // Get HHHH
151 int Temperature = (H << 8) | ML; // Combine HHHH MMMMLLLL
152 Temperature = Temperature -900; // Remove Constant offset
153 Serial.print(Temperature/10.0,1);
154 Serial.print("F Humidity=");
155 H = (myData1 >> 4) & 0xF0; // Get HHHH
156 ML = (myData1 >> 12) & 0xF; // Get LLLL
157 ML = ML | H; // OR HHHH & LLLL nibbles together
164 void dec2binLong(unsigned long myNum, byte NumberOfBits) {
165 if (NumberOfBits <= 32){
166 myNum = myNum << (32 - NumberOfBits);
167 for (int i=0; i<NumberOfBits; i++) {
168 if (bitRead(myNum,31) == 1)