merbanan / rtl_433

Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
GNU General Public License v2.0
6k stars 1.3k forks source link

Aureol HG04641A - Temperature Station from Lidl (IAN: 307350) #2014

Open mantielero opened 2 years ago

mantielero commented 2 years ago

I bought this sensor around 2018. Manual

I am trying to access the data it provides. I live in a very busy area (I detect plenty of sensors from the neighbourhood) so I hope I am doing things right.

Using:

$ rtl_433 -f 433.92M -S unknown
...
$ rtl_433 -A g022_433.92M_250k.cu8 
...

I am getting something like the following:

-22.6ºC

[02] {36} 12 f4 10 e2 70 : 00010010 11110100 00010000 11100010 0111
                                                               ^^^^ CRC? Checksum?

This sensor can connect to also to a radiofrequency time server. The manual states:

Radio signal (DCF):
The DCF-radio signal (time signal transmitter) is made up of time
pulses transmitted from one of the highest precision clocks in the
world close to Frankfurt / Main in Germany – it varies by 1 second
in 1 million years.
In ideal conditions, your temperature station can pick up this signal
over a distance of up to approx. 1,500 km around Frankfurt /
Main.

Here in Spain we don't have that signal, so probably the begining of the signal. So maybe somebody from Germany can complete the missing bits.

Today I first notice rtl_433, so I don't know what to do next.

  1. How can I know if the last bits are CRC or Checksum?
  2. In order to get this covered by rtl_433, what should I do next?
zuckschwerdt commented 2 years ago

Looks good already. Get more codes to be sure and put them in a BitBench like this.

The temp is likely 12 bits. But we need to known if negative values are flagged, 2's complement, or something else. The DCF would be in the head unit, like they say "temperature station" not "sensor". The checksum looks like a simple addition, but too few codes to verify.

When the details are clear then you can write a decoder. Look at the last commits, e.g. 63514de Write a decoder, add to include/rtl_433_devices.h, stage in git then run ./maintainer_update.py and stage the changed files. If you like that is, otherwise just describe the protocol and request help ;)

zuckschwerdt commented 2 years ago

Oh, also reset the battery and watch what changes. I guess the first byte is a fixed protocol identifier and the second byte random with every battery change. If there is a channel switch, try that too. And use near dead batteries or a variable voltage supply to find the battery_low bit.

mantielero commented 2 years ago

In the freezer I am getting -14.1ºC, so it looks like it is 2's complement:

[02] {36} 12 f4 1f 73 00 : 00010010 11110100 00011111 01110011 0000
                                                 ^^^^ ^^^^^^^^ Temperature 2's complement

After removing the batteries I get:

[02] {36} 12 f4 1f 95 40 : 00010010 11110100 00011111 10010101 0100

I have tried also with old batteries and I get:

[02] {36} 12 f4 10 c4 70 : 00010010 11110100 00010000 11000100 0111

So far it looks like:

ID?8h 8h FLAGS?4h TEMP?12d CHK?4h

I also replace the batteries by some old ones and got:

[02] {36} 12 f4 90 ec 90 : 00010010 11110100 10010000 11101100 1001
                                             ^ low battery                                                                    

Another neightbour seems to have a similar device, because my station connects to it from time to time. I think is this one:

[02] {36} 36 d4 90 8b 60 : 00110110 11010100 10010000 10001011 0110

(it also reports low battery)

mantielero commented 2 years ago

OFFTOPIC (I know this is the wrong place to ask, but probably there is plenty of people who can point me in the right direction)

I am trying to read from the sensor above with Arduino. I have a 433Mhz cheap sensor that I bought long ago (2016) -never used-.

I tried with Radiohead and RC-switch but I don't get any text from very basic examples. I was expecting to get the a string similar to the ones above: 12 f4 90 ec 90.

Does anyone experience doing this? Any good tutorial that I can follow to do it? Maybe the sensor is too bad? Is not feasible to do this with arduino?

zuckschwerdt commented 2 years ago

Those "1-bit SDRs" are not great. Maybe get a CC1101 or something similar.

mantielero commented 2 years ago

I have another question:

00010010 11110100 00011111 01110011 0000
                                    ^^^^
00010010 11110100 00011111 10010101 0100
                                    ^^^^
00010010 11110100 00010000 11000100 0111
                                    ^^^^

In BitBench, it shows something like: CHK?4h. What is the calculation being done to calculate those 4 bits?

merbanan commented 2 years ago

Some kind of checksum.

mantielero commented 2 years ago

OFFTOPIC

Just for the record, in case somebody hits this issue searching for the sensor and arduino. I raised this issue in the arduino forum. Rather than using Radiohead or RC-switch, you just measure the time between pulses. Here it is the code:

const int intPin = 2;  // Only PINS 2 and 3 can handle interrupts in arduino nano.

volatile bool NewData = false;
volatile byte DataLength = 0;  // Received data length in bits
volatile uint8_t myArray[64]; // 256 bits in 4-bit 'nybbles'

uint8_t Received[64]; // 256 bits in 4-bit 'nybbles'
const uint8_t SensorID[4] = {0x1, 0x2, 0xF, 0x4}; // 16 bits in 4-bit 'nybbles'

void setup()
{
  Serial.begin(115200);
  delay(200);

  pinMode(intPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(intPin), SignalISR, FALLING);
}

void SignalISR()
{
  static unsigned long lastISRTime = 0;
  static byte bitIndex = 0;

  unsigned long time = micros();
  unsigned long elapsed = time - lastISRTime;
  lastISRTime = time;

  // Don't start accepting new data until the old data was processed
  if (NewData)
    return;

  if (elapsed > 1400 && elapsed < 1580)
  {
    // Zero Bit
    bitIndex++;
  }
  else if (elapsed > 2400 && elapsed < 2580)
  {
    // One Bit
    size_t nybbleIndex = bitIndex / 4;
    myArray[nybbleIndex] |= (0x8 >> (bitIndex % 4));
    bitIndex++;
  }
  else
  {
    // Not a valid bit width
    if (bitIndex > 0)
    {
      NewData = true;
      DataLength = bitIndex;
      bitIndex = 0;
    }
  }
}

void loop()
{
  if (NewData)
  {
    unsigned length;

    // Copy the volatile data
    noInterrupts();
    length = DataLength;
    for (byte i = 0; i < (length + 4) / 4; i++)
    {
      Received[i] = myArray[i];
      myArray[i] = 0; // Clear for next time
    }
    NewData = false;
    interrupts();

    Serial.print(length);
    Serial.print(": ");

    if (length == 1)
    {
      Serial.println("~~glitch~~");
      return;
    }

    for (byte i = 0; i < (length + 3) / 4; i++)
    {
      Serial.print(Received[i], HEX);
    }
    Serial.print(' ');

    if (length % 4 != 0)
    {
      Serial.println("Invalid Length: Not multiple of 4");
      return;
    }

    uint8_t checksum = 0;
    for (size_t i = 0; i < (length / 4) - 1; i++)
    {
      checksum += Received[i];
    }
    if ((checksum & 0x0F) != Received[length / 4 - 1])
    {
      Serial.print("Wrong checksum: ");
      Serial.println((checksum & 0x0F), HEX);
      return;
    }

    int16_t temperature = 0;
    if (length == 36
        && Received[0] == SensorID[0] && Received[1] == SensorID[1]
        && Received[2] == SensorID[2] && Received[3] == SensorID[3])
    {
      temperature = (Received[5] << 12) | (Received[6] << 8) | (Received[7] << 4);
      temperature >>= 4;  // sign-extend
      Serial.print("Temperature = ");
      Serial.print(float(temperature) / 10.0);
      Serial.println("°C");

      // Show battery status
      if (Received[4] & 8) {
        Serial.print("Battery Low");
      } else {
        Serial.print("Battery OK");
      }

    }
    Serial.println();
  }
}

As @merbanan -mentions it is a checksum. It is implemented in the code above by johnwasser.

gdt commented 11 months ago

@mantielero Are you still working on this? Plans for a PR?

mantielero commented 11 months ago

I am sorry I am no longer working on it.