User Tools

Site Tools


record_temperature_from_lexibook_asm30_sensor

This is an old revision of the document!


Record temperature from Lexibook ASM30 sensor with Arduino

Needed hardware

  • Arduino Uno R3 board (available on Amazon) with USB cable
  • 433Mhz RF transmitter and receiver (available on eBay)
  • Lexibook ASM30 temperature sensor: I had one since many years and I noticed it communicates with 433RF signals with the base

Assembly

It is very simple. Just connect the RF 433 receiver like this:

  • GND to Arduino pin GND
  • VCC to Arduino pin 5V
  • DATA to Arduino DIGITAL pin 2

Then I suppose you have the Arduino connected with a USB cable to a PC running the Arduino development environment.

Reverse engineering Lexibook ASM30 temperature sensor

I tried RFControl sniffer to see if some signals can be discovered. RFControl outputs pulse timing if the same code is received twice.

The ASM30 sensor sends data every 30 seconds, corresponding to the time when the LED is flashing. And RFControl detects some data exactly at the same time!

Analysing the timings show several things :

  • There is a short timing (<500) every other pulse
  • Some pulse have medium duration (around 1900)
  • Some pulse have long duration (around 4500)
  • The full frame is sent 3 times with a timing >9500 between frames

My asumption was a short pulse was a separator, a medium pulse was a “0” bit and a long pulse a “1” bit. So I tried to decode bytes knowing the expected temperature which is displayed on the sensor itself: so easy, the 3rd byte is the temperature x10.

So now, this is what I found:

  • First byte can vary but I don't know yet what is it. Maybe contains the sensor ID
  • Second byte is always the same: “11110000” (240). Probably not an ID (or I am really lucky!), maybe a separator
  • Third byte is the temperature in °C x10
  • 2 next bits are the channel you can choose on the sensor itself: 1, 2 or 3. This is to be able to know the source of the temperature when you have several sensors.
  • Last 2 bits are always “00”, probably stop bits

The arduino sketch

The following sketch reads the temperature and output to the serial line in JSON format. In this sketch, I use RFControl library as is, so it is not very optimized for my needs. However, for now it works and it is enough!

#include <RFControl.h>
 
// Save current temperature and channel
int temperature = 0;
int channel = 0;
 
void setup() {
 
  // Initialize serial line
  Serial.begin(115200);
 
  // Start receiving RF signals
  RFControl::startReceiving(0);
}
 
// The function prints current data to the serial line
void printData() {
    Serial.print("{ ");
    Serial.print("\"temp\": ");
    Serial.print(temperature);
    Serial.print(", \"channel\": ");
    Serial.print(channel);
    Serial.print(" }\r\n");
}
 
void loop() {
 
  // Decode data when received
  if(RFControl::hasData()) {
    unsigned int *timings;
    unsigned int timings_size;
    unsigned int pulse_length_divider = RFControl::getPulseLengthDivider();
    RFControl::getRaw(&timings, &timings_size);
 
    int iTemperatureTmp = 0;
    int iChannelTmp = 0;
 
    for(int i=0; i < timings_size; i++) {
      unsigned long timing = timings[i] * pulse_length_divider;
 
      // Temperature is at bit 16*2 coded in decimal x 10 on 8 bits
      if( (i >= 16*2) && (i < (16*2 + 8*2)) ) {
        if(i == 16*2) iTemperatureTmp = 0;
 
        if(timing < 1000) {
          // bit separator, do nothing
        }
        else if(timing < 2000) {
          iTemperatureTmp = iTemperatureTmp<<1;
        }
        else if(timing < 5000) {
          iTemperatureTmp = iTemperatureTmp<<1;
          iTemperatureTmp++;
        }
      }
      // Sensor Channel is after byte 3, on 2 bits, decimal encoded
      else if((i >= 24*2) && i <= 26*2) {
        if(i == 24*2) channel = 0;
        if(timing < 1000) {
          // bit separator, do nothing
        }
        else if(timing < 2000) {
          iChannelTmp = iChannelTmp<<1;
        }
        else if(timing < 5000) {
          iChannelTmp = iChannelTmp<<1;
          iChannelTmp++;
        }
      }
      // Other data
      else {
        // Do nothing for now
      }
    }
 
    temperature = iTemperatureTmp;
    channel = iChannelTmp;
 
    RFControl::continueReceiving();
  }
 
  printData(); 
}

Next Step

Next step is to be able to get the temperature using a raspberry pi connected to the arduino and display it in domoticz.

References

  • RFControl RF 433MHz sniffer library for Arduino: RFControl

Share this page:

record_temperature_from_lexibook_asm30_sensor.1459589002.txt.gz · Last modified: 2016/04/02 11:23 by sgripon