I've recorded a few different signals from the rx module through the line in on my sound card with a voltage divider using Audacity. I've been poking around at it but haven't been able to decode the data and was hoping to get some help. The sensor has a switch to select "channel" A, B or C. I can see the beginning of the capture change based on the position of this switch. From what I can tell the sensor is transmitting the "channel", battery Ok/Low, temperature and humidity. Below are a few captures:
The sensor sends that string of data 3 times in a row every ~20 seconds. I'm assuming it's sending it 3 times to ensure that it is received correctly. I've been trying to make sense of it by hand. It always has those 4 long pulses in the beginning. I've just assumed they just marked the beginning of the transmission. So ignoring the 4 longer pulses in the beginning I tried counting the other long pulses as 1 and the short pulses as 0 (and vise versa) but that doesn't make any sense no matter how I look at it.
I was hoping someone with more experience could take a look and point me in the right direction.
From a quick glance, look closely at the six pulses around 0.0240. Interpret a short downward spike as 1 and a long downward spike as 0. I can see 100011, 011111, 011111 and 101000 which are binary for 35,31,31 and 40 which corresponds with the humidity percentage. It could be coincidence, you'd need to do more samples to check.
I went through this last year with an Acurite rain sensor (model 00899). It was very interesting and not too terribly difficult. I will try to find my notes later, but....
The four rather longer pulses at the beginning and three "repeats" sounds about the same as what I saw. And the longer/shorter pulses indeed were simply 1's and 0's, with no other decoding necessary (e.g. "Manchester" or such).
If I were you I would begin by capturing the data as you have by hand. Transcribe the pulses as bits where long-low/short-high is 0 and short-low/long-high is 1 (it could turn out to be opposite but that's how it was in my case). And of course record all the current readings from the base unit that go along with it. Wait for something to change, and repeat.
Something like this
Thanks for the tips. I've made a bit of progress. stimmer was right, i did some more captures and the humidity is in there in straight binary. I can't believe I missed that. I was focusing too much on BCD when initially looking at it. Now temperature seems to be a bit trickier. Here are a few data sets. I'm not sure if I should be looking at the temperature in Celsius or Fahrenheit so I noted down some with both:
The beginning is always the same, probably a type of identifier string of bits. I know if i change the sensor to channel B the I get "10111" instead of "11111" for the first 5 bits. I'm guessing the beginning also contains the battery low indicator bit(s). But I haven't been able to verify that yet. The section that's spaced out in the middle is the humidity, which leaves the temperature at the end. I've tried looking at the temperature as BCD and as straight binary numbers in both C and F but I can't make any sense of it.
I think it the below is getting pretty close, "T" marking the temperature bits, and "p" is a parity bit. This is very similar to what I remember on my rain gauge.
I have put the decimal equivalents, which may be in arbitrary temperature units easily converted by "y=mx+b".
johncc, I'm getting close. I don't think the temperature values are linear though:
After getting some colder samples I believe that both 8-bit columns after the humidity are 7bits temperature plus 1 parity bit in the beginning, so 14 bits for the temperature value:
-----------pCCCCCCC pIIIIIII pBBBBBBB pHHHHHHH pTTTTTTT pTTTTTTT CHECKSUM?-- TEMP IN BIN DEC
A:-10C 70% 11111011 01101011 01000100 11000110 10000111 00000110 11111101 -- 00001110000110 902
A:+00C 68% 11111011 01101011 01000100 01000100 10000111 11100111 01011100 -- 00001111100111 999
A:+06C 65% 11111011 01101011 01000100 01000001 10001000 00100010 10010101 -- 00010000100010 1058
A:+12C 61% 11111011 01101011 01000100 10111101 10001000 11100001 11010000 -- 00010001100001 1121
A:+14C 59% 11111011 01101011 01000100 10111011 10001000 01110111 01100100 -- 00010001110111 1143
A:+16C 56% 11111011 01101011 01000100 10111000 00001001 10001000 11110011 -- 00010010001000 1160
A:+18C 55% 11111011 01101011 01000100 10110111 00001001 00010111 10000001 -- 00010010010111 1175
A:+20C 53% 11111011 01101011 01000100 00110101 00001001 10101100 10010100 -- 00010010101100 1196
p=Parity Bit
C=Channel (A, B or C)
I=Identification string ???
B=Battery OK/Low ???
H=Humidity
T=Arbitrary Temperature value
I'm guessing the last column is a CRC or Checksum but haven't investigated it yet.
But using the y=mx+b linear equation doesn't add up, or I'm doing it wrong For example using the first and last data bits:
(x,y)
(20,1196)
(-10,902)
20-(-10)=30
1196-902=294
294/30=9
m=9
1196=9(20)+b
1196=180+b
b=1016
So then if i take the +6C sample:
1058=9(x)+1016
42=9x
x=42/9
x=4 (should be 6)
I've also tried it with the Fahrenheit data and i get the same behavior.
Riva Thank-you! Now that I look at the decimal numbers I can obviously see it. Sometimes you get so focused on one thing that it helps to get a second set of eyes to have a fresh look
Got a sketch working. Its not the most elegant and needs some work. I need to inspect more than the first 10 bits to determine the channel. But here it is anyways:
byte pin = 13; // from receiver
byte ar[116];
byte pos=0;
unsigned long dur; //array, position in array, pulse duration
void setup() {
pinMode(pin, INPUT);
Serial.begin(9600);
Serial.flush();
}
void loop() {
b: pos=0;
//if the first ten bits are:
// 11111011011 = Channel A
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>225)&&(dur<350)) {ar[pos] = 0; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>225)&&(dur<350)) {ar[pos] = 0; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>380)&&(dur<545)) {ar[pos] = 1; pos++;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
}else goto b;
//first ten bits = 11111011011 if we made it this far it must be valid data so lets continue
for (int i=1; i <= 46; i++){
dur = pulseIn(pin, HIGH);
if ((dur>225)&&(dur<350)){ar[pos] = 0; pos++; }
if ((dur>380)&&(dur<545)){ar[pos] = 1; pos++; }
}
Serial.println();
Serial.print("Data Received: ");
for (int pos=0; pos <= 56; pos++){
Serial.print(ar[pos]);
}
Serial.println();
int hum=0; for (int i=0; i <= 6; i++) {hum=hum << 1; hum=hum+ar[25+i]; Serial.print(ar[25+i]); }
Serial.print(" ");Serial.print("Humidity: "); Serial.print(hum);Serial.println("%");
int temp=0; for (int i=0; i <= 14; i++) {if (i==7){i++;}temp=temp << 1; temp=temp+ar[33+i]; Serial.print(ar[33+i]); }
float realtemp = float(temp - 1000) / float(10);
Serial.print(" ");Serial.print("Temperature: "); Serial.print(realtemp,1);Serial.println("C");
pos=0;
}
Output is:
Data Received: 111110110110101101000100001011100000100111010001101100100
0101110 Humidity: 46%
00010011010001 Temperature: 23.3C
I've found that once the sensor is at a bit of a distance I occasionally get incorrect data. Which I can understand since I'm not performing and type of validation. I have zero experience with CRCs and checksums. Can anyone point me to how to verify it by hand?
I believe that the last column is the CRC or checksum
-----------CCCCCCCCCCCCCCCC BBBBBBBB pHHHHHHH pTTTTTTT pTTTTTTT
A -18C-63% 1111101101101011 01000100 00011110 00001001 01000001 00010010
A -17C 56% 1111101101101011 01000100 10111000 00000110 10111011 00100011
A -10C 70% 1111101101101011 01000100 11000110 10000111 00000110 11111101
A 0C 68% 1111101101101011 01000100 01000100 10000111 11100111 01011100
A 6C 65% 1111101101101011 01000100 01000001 10001000 00100010 10010101
A 12C 61% 1111101101101011 01000100 10111101 10001000 11100001 11010000
A 14C 59% 1111101101101011 01000100 10111011 10001000 01110111 01100100
A 16C 56% 1111101101101011 01000100 10111000 00001001 10001000 11110011
A 18C 55% 1111101101101011 01000100 10110111 00001001 00010111 10000001
A 20C 53% 1111101101101011 01000100 00110101 00001001 10101100 10010100
What I did is read all three copies of the "message" and then compare using strncmp() or memcmp(). If I got any two of three that agreed, I considered it valid...
The last column appears to be literally a checksum - it's the sum of the first 6 bytes after splitting the channel ID into two bytes, ignoring overflow.
Guys, could you please take a look at our try to do the same - decode the 433 sensor data?
Whole thread is here, but the most important parts are on the last page: http://arduino.cc/forum/index.php/topic,142871.30.html
Whole code gathered and some decoded is here:
We need a fresh look on it... Especially the CRC part and battery/the first patterns.