Go Down

Topic: 433 MHz RF - Temperature and humidity sensor (Read 39 times) previous topic - next topic

andriej

I've found a China producer of the sensor, maybe they will send me some info.
Anyway, at the moment - please, someone help me with code that detects "high" pulse starting with "1010", so I dont recieve all the zeroe's on the input.
I can't manage to do that... I'd really like to share some more info about this device for everyone, as the producer is in China so there will be probably more people interested in getting it working.

Riva

Quote
Is there a code for a nicer output? So I could collect binary and readings from LCD about temp and hum.?

I think in the original post the OP was capturing the signal using PC audio software like Audacity and hand decoding the results.

andriej

Yeah, the problem is I'm afraid of connecting 'data' pin to my soundcard without circuit for it.
And I couldn't fine any circuit except oscilloscope one (which I don't have all parts for).

Do you have any of these available? I have some old laptop with linux that I could play with.

adis

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:
Code: [Select]
#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:
Code: [Select]
#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.

andriej

Thank you very much for your post!
Just tell me please - where is the 'modulator input' on this picture?
Do you mean output for the 433 transciever?


Go Up