Hi,
I've done this job a year ago and I used arduino for decoding
First you have to prepare the hardware:
- open your sensor
- find the modulator input
- feed it into arduino with proper level change (I assume 0-3v => 0-5v)
The code I used was something like:
#define samples 700 //max 700
byte ms[samples];
boolean values[samples];
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT);
Serial.begin(2400);
}
long lastChange, maxTime = 0;
bool previousValue;
void loop() {
for (int i = 0; i < samples; i++)
{
values[i] = false;
ms[i] = 0;
}
long start = micros();
for (int i = 0; i <= samples; i++)
{
if (i == samples) i = 0;
digitalWrite(13, (values[i] = digitalRead(2)));
ms[i] = (byte)((micros() - start)/10);
start = micros();
while (values[i] == digitalRead(2))
{}
if((micros()-start) > 50000)
{
for (int k = i + 1; k < samples; k++)
{
Serial.print(k);
Serial.print(":");
Serial.print((int)ms[k]);
Serial.print(":");
Serial.println((values[k]?"true":"false"));
}
for (int k = 0; k <= i; k++)
{
Serial.print(k);
Serial.print(":");
Serial.print((int)ms[k]);
Serial.print(":");
Serial.println((values[k]?"true":"false"));
}
break;
}
}
digitalWrite(13, LOW);
delay(1000);
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(10000);
}
After you manage to isolate one packet, take 2 consecutive readings with just one unit (in the least significant digit) difference in temperature or humidity. If your streams have one difference you don't have CRC, if you have 2 or mode differences you might have something like 011+1=100 or CRC or both. Here you need some luck.
After some hours of reverse engineering I come with the following code:
#define nobits 36
#define initialstring "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define syncmin 6400
#define syncmax 9600
#define separatormin 256
#define separatormax 384
#define lowmin 768
#define lowmax 1152
#define highmin 1536
#define highmax 2304
#define baudspeed 115200
#define receiverpin 2
#define ledpin 13
#define sensorid "10001000"
#define rflisteninterval 50
float temperature = 0;
int humidity = 0;
unsigned long lastReadMills = 0;
boolean lowBatt = false;
boolean requestedTransmission = false;
boolean invalidTransmission = false;
String lastReceivedCode = "";
void setup() {
pinMode(ledpin, OUTPUT);
pinMode(receiverpin, INPUT);
digitalWrite(receiverpin, HIGH);
Serial.begin(baudspeed);
}
void loop()
{
if(RFListened())
{
//other processing
}
}
boolean RFListened()
{
if(((millis()-lastReadMills)/1000>rflisteninterval)||(millis()<lastReadMills))
{
GetWeatherData();
if((millis()==lastReadMills)&&(lastReadMills!=0))
{
if (lowBatt) Serial.print("Battery low; ");
if (requestedTransmission) Serial.print("Requested transmission; ");
if (invalidTransmission)
{
Serial.println("Non temperature/humidity data; ");
return false;
}
else
{
Serial.print(lastReadMills/1000);
Serial.print("s; ");
Serial.print(temperature);
Serial.print("C; ");
Serial.print(humidity);
Serial.println("%");
return true;
}
}
return false;
}
else
{
return true;
}
}
void GetWeatherData()
{
String receivedCode = ReceiveCode();
if (receivedCode!="")
{
if (receivedCode==lastReceivedCode)
{
lowBatt = (receivedCode.charAt(8)=='1');
requestedTransmission = (receivedCode.charAt(11)=='1');
invalidTransmission = !((receivedCode.charAt(9)=='0')||(receivedCode.charAt(10)=='0'));
if (!invalidTransmission)
{
temperature = (receivedCode.charAt(24)=='1'?1:0)*2048 +
(receivedCode.charAt(25)=='1'?1:0)*1024 +
(receivedCode.charAt(26)=='1'?1:0)*512 +
(receivedCode.charAt(27)=='1'?1:0)*256 +
(receivedCode.charAt(28)=='1'?1:0)*128 +
(receivedCode.charAt(29)=='1'?1:0)*64 +
(receivedCode.charAt(30)=='1'?1:0)*32 +
(receivedCode.charAt(31)=='1'?1:0)*16 +
(receivedCode.charAt(32)=='1'?1:0)*8 +
(receivedCode.charAt(33)=='1'?1:0)*4 +
(receivedCode.charAt(34)=='1'?1:0)*2 +
(receivedCode.charAt(35)=='1'?1:0);
temperature = temperature /10;
humidity = (receivedCode.charAt(16)=='1'?1:0)*128 +
(receivedCode.charAt(17)=='1'?1:0)*64 +
(receivedCode.charAt(18)=='1'?1:0)*32 +
(receivedCode.charAt(19)=='1'?1:0)*16 +
(receivedCode.charAt(20)=='1'?1:0)*8 +
(receivedCode.charAt(21)=='1'?1:0)*4 +
(receivedCode.charAt(22)=='1'?1:0)*2 +
(receivedCode.charAt(23)=='1'?1:0);
lastReadMills = millis();
}
}
else
lastReceivedCode = receivedCode;
}
}
String ReceiveCode()
{
String receivedCode = initialstring;
long startMicros = micros(), endMicros;
if (digitalRead(receiverpin)) return "";
while(!digitalRead(receiverpin))
{
if ((micros()-startMicros)>syncmax)
return "";
}
if ((micros()-startMicros)<syncmin)
return "";
startMicros = micros();
while(digitalRead(receiverpin))
{
if ((micros()-startMicros)>separatormax)
return "";
}
if ((micros()-startMicros)<separatormin)
return "";
for(int i = 0; i < nobits; i++)
{
startMicros = micros();
while(!digitalRead(receiverpin))
{
if ((micros()-startMicros)>highmax)
return receivedCode;
}
endMicros = micros();
if(((endMicros-startMicros)>lowmin)&&((endMicros-startMicros)<lowmax))
receivedCode.setCharAt(i,'0');
else
if(((endMicros-startMicros)>highmin)&&((endMicros-startMicros)<highmax))
receivedCode.setCharAt(i,'1');
else
return "";
startMicros = micros();
while(digitalRead(receiverpin))
{
if ((micros()-startMicros)>separatormax)
return "";
}
if ((micros()-startMicros)<separatormin)
return "";
}
//Serial.println(receivedCode);
if (receivedCode.substring(0,8)==sensorid)
return receivedCode;
else
return "";
}
This will not fit your sensor since, as I see in the image it has a configurable channel. Mine has a random signature generated at power on.