esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
288 stars 34 forks source link

dht22 negative temperatures calculated incorrectly #5322

Closed rippe77 closed 4 months ago

rippe77 commented 5 months ago

The problem

It seems the negative temperatures are calcalated incorrectly. The problem seems to be with dht.cpp lines 220-221: if (this->model_ != DHT_MODEL_DHT22_TYPE2 && (raw_temperature & 0x8000) != 0) raw_temperature = ~(raw_temperature & 0x7FFF);

Correct implementation seems to be: if (this->model_ != DHT_MODEL_DHT22_TYPE2 && (raw_temperature & 0x0800) != 0) raw_temperature = raw_temperature | 0xF000;

Which version of ESPHome has the issue?

2023.12.5

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2023.12.4

What platform are you using?

ESP32

Board

ESP-32 30PIN

Component causing the issue

dht22

Example YAML snippet

sensor:
  - platform: dht
    pin: GPIO2
    temperature:
      name: "dht22_temp"
    humidity:
      name: "dht22_hum"
      accuracy_decimals: 1
    update_interval: 30s
    model: DHT22

Anything in the logs that might be useful for us?

Added following debug line to the read_sensor() -function.

    ESP_LOGI(TAG, "data[2] 0x%02X, data[3] 0x%02X, raw_temperature 0x%04X", data[2], data[3], raw_temperature);

With it the following data is recorded in to the log (Above/below 0 C)
[19:34:09][I][dht:220]: data[2] 0x0F, data[3] 0xF8, raw_temperature 0x0FF8
[19:34:09][D][dht:048]: Got Temperature=408.8°C Humidity=97.7%
[19:34:09][D][sensor:094]: 'dht22_temp': Sending state 408.80002 °C with 1 decimals of accuracy
[19:34:09][D][sensor:094]: 'dht22_hum': Sending state 97.70000 % with 1 decimals of accuracy
[19:34:14][I][dht:220]: data[2] 0x0F, data[3] 0xFE, raw_temperature 0x0FFE
[19:34:14][D][dht:048]: Got Temperature=409.4°C Humidity=98.6%
[19:34:14][D][sensor:094]: 'dht22_temp': Sending state 409.39999 °C with 1 decimals of accuracy
[19:34:14][D][sensor:094]: 'dht22_hum': Sending state 98.60000 % with 1 decimals of accuracy

[19:34:19][I][dht:220]: data[2] 0x00, data[3] 0x06, raw_temperature 0x0006
[19:34:19][D][dht:048]: Got Temperature=0.6°C Humidity=99.4%
[19:34:19][D][sensor:094]: 'dht22_temp': Sending state 0.60000 °C with 1 decimals of accuracy
[19:34:19][D][sensor:094]: 'dht22_hum': Sending state 99.40000 % with 1 decimals of accuracy
[19:34:24][I][dht:220]: data[2] 0x00, data[3] 0x0C, raw_temperature 0x000C
[19:34:24][D][dht:048]: Got Temperature=1.2°C Humidity=99.9%
[19:34:24][D][sensor:094]: 'dht22_temp': Sending state 1.20000 °C with 1 decimals of accuracy
[19:34:24][D][sensor:094]: 'dht22_hum': Sending state 99.90000 % with 1 decimals of accuracy
[19:34:29][I][dht:220]: data[2] 0x00, data[3] 0x12, raw_temperature 0x0012
[19:34:29][D][dht:048]: Got Temperature=1.8°C Humidity=99.9%
[19:35:04][I][dht:220]: data[2] 0x00, data[3] 0x08, raw_temperature 0x0008
[19:35:04][D][dht:048]: Got Temperature=0.8°C Humidity=80.6%
[19:35:04][D][sensor:094]: 'dht22_temp': Sending state 0.80000 °C with 1 decimals of accuracy
[19:35:04][D][sensor:094]: 'dht22_hum': Sending state 80.60000 % with 1 decimals of accuracy
[19:35:09][I][dht:220]: data[2] 0x00, data[3] 0x01, raw_temperature 0x0001
[19:35:09][D][dht:048]: Got Temperature=0.1°C Humidity=73.6%
[19:35:09][D][sensor:094]: 'dht22_temp': Sending state 0.10000 °C with 1 decimals of accuracy
[19:35:09][D][sensor:094]: 'dht22_hum': Sending state 73.60000 % with 1 decimals of accuracy

[19:35:14][I][dht:220]: data[2] 0x0F, data[3] 0xFC, raw_temperature 0x0FFC
[19:35:14][D][dht:048]: Got Temperature=409.2°C Humidity=67.8%
[19:35:14][D][sensor:094]: 'dht22_temp': Sending state 409.20001 °C with 1 decimals of accuracy
[19:35:14][D][sensor:094]: 'dht22_hum': Sending state 67.80000 % with 1 decimals of accuracy
[19:35:19][I][dht:220]: data[2] 0x0F, data[3] 0xF6, raw_temperature 0x0FF6
[19:35:19][D][dht:048]: Got Temperature=408.6°C Humidity=62.9%
[19:35:19][D][sensor:094]: 'dht22_temp': Sending state 408.60001 °C with 1 decimals of accuracy
[19:35:19][D][sensor:094]: 'dht22_hum': Sending state 62.90000 % with 1 decimals of accuracy
[19:35:24][I][dht:220]: data[2] 0x0F, data[3] 0xEF, raw_temperature 0x0FEF
[19:35:24][D][dht:048]: Got Temperature=407.9°C Humidity=58.7%
[19:35:24][D][sensor:094]: 'dht22_temp': Sending state 407.89999 °C with 1 decimals of accuracy
[19:35:24][D][sensor:094]: 'dht22_hum': Sending state 58.70000 % with 1 decimals of accuracy
[19:35:29][I][dht:220]: data[2] 0x0F, data[3] 0xE8, raw_temperature 0x0FE8

Additional information

No response

rippe77 commented 5 months ago

With the fixed implementation f.e. following data is logged. [20:03:09][I][dht:220]: data[2] 0x0F, data[3] 0xED, raw_temperature 0x0FED [20:03:09][D][dht:048]: Got Temperature=-1.9°C Humidity=48.0% [20:03:09][D][sensor:094]: 'dht22_temp': Sending state -1.90000 °C with 1 decimals of accuracy [20:03:09][D][sensor:094]: 'dht22_hum': Sending state 48.00000 % with 1 decimals of accuracy

ssieb commented 5 months ago

That doesn't match the datasheet for the sensor and no one has mentioned this before. Are you sure that's the sensor you have?

rippe77 commented 5 months ago

The sensors are freshly ordered from china and should be DHT22/AM2302. True the data format does not match the datasheet as it seems to be 12-bit 2-complement format. And the DHT_MODEL_DHT22_TYPE2 assumes 16-bit 2-complement format. I searched the internet, and did not find any DHT22 "variants" with this 12-bit 2-compelement format specified in the datasheet.

Maybe the correct fix would anyway be on to the "TYPE2" branch...

rippe77 commented 5 months ago

Revised fix is to add following lines:

//Some DHT22 models seem to be returning 12-bit 2-complement numbers, this fixes them to 16-bit, but this also works with models with 16-bit 2-complement data.
if (this->model_ == DHT_MODEL_DHT22_TYPE2 && (raw_temperature & 0x0800) != 0)
  raw_temperature = raw_temperature | 0xF000;

And then use model: DHT22_TYPE2 in the configuration Yaml.

Carbur8tr commented 5 months ago

I've noticed this issue as well. Is there any plan to commit a change?

ssieb commented 4 months ago

Can you find any reference to why the sensor is providing values like that? The commit for the TYPE2 variant is very specific about that negative calculation. Maybe this needs to be a TYPE3.

rippe77 commented 4 months ago

I have not yet found any datasheet that explains the sensor behaviour.

This could also be TYPE3, but I think the code I provided in comment https://github.com/esphome/issues/issues/5322#issuecomment-1873844830 would work with both the original TYPE2 sensors and these sensors behaving wierdly (as the datarange is only -40 -- 80 C deg).

However I can not test this with normal TYPE2 sensors as I do not have any.

koenie10 commented 4 months ago

I noticed the same behavior. Temperatures dropped below zero for the first time since I started playing with ESPhome a couple of months ago. Values around 408 returned. ESPhome version 2023.12.5.

ssieb commented 4 months ago

Please test the PR with any DHT22 sensors you have.

rippe77 commented 4 months ago

Tested the PR against ESPHome 2023.12.7. Works fine.