esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 36 forks source link

Setting SCD30 temperature offset causes the sensor to report bogus values #3063

Closed Plawasan closed 1 year ago

Plawasan commented 2 years ago

The problem

I've had the SCD30 sensor running for a while without any issues at all, it was just consistently reporting a temperature 1.4C higher than a BME280 sitting right next to it. I've added temperature offset to the config to correct that however since that point the sensor is reporting completely random values for temperature and humidity (co2 seems unaffected).

I have removed the offset from the config, have restarted both the ESP and the sensor completely, nothing seems to help:

image

Which version of ESPHome has the issue?

2022.2.1

What type of installation are you using?

pip

Which version of Home Assistant has the issue?

2022.2.8

What platform are you using?

ESP32

Board

esp32doit-devkit-v1

Component causing the issue

scd30

Example YAML snippet

  - platform: scd30
    co2:
      name: "SCD30 CO2"
      accuracy_decimals: 0
      filters:
      - calibrate_linear:
        - 530 -> 400
        - 5000 -> 5000
      - lambda: |-
          if (x < 400) return 400;
          return x;
    temperature:
      name: "SCD30 Temperature"
      accuracy_decimals: 1
    humidity:
      name: "SCD30 Humidity"
      accuracy_decimals: 0
    automatic_self_calibration: false
    temperature_offset: -1C
    address: 0x61
    update_interval: 60s  

Anything in the logs that might be useful for us?

[D][scd30:187]: Got CO2=1515.86ppm temperature=-29.21°C humidity=2513.13%
[D][sensor:125]: 'SCD30 CO2': Sending state 1414.53564 ppm with 0 decimals of accuracy
[D][sensor:125]: 'SCD30 Temperature': Sending state -29.21182 °C with 1 decimals of accuracy
[D][sensor:125]: 'SCD30 Humidity': Sending state 2513.13477 % with 0 decimals of accuracy

[12:53:15][C][scd30:121]: scd30:
[12:53:15][C][scd30:122]:   Address: 0x61
[12:53:15][C][scd30:140]:   Altitude compensation: OFF
[12:53:15][C][scd30:144]:   Automatic self calibration: OFF
[12:53:15][C][scd30:145]:   Ambient pressure compensation: 0mBar
[12:53:15][C][scd30:146]:   Temperature offset: -1.00 °C
[12:53:15][C][scd30:147]:   Update interval: 60s
[12:53:15][C][scd30:148]:   CO2 'SCD30 CO2'
[12:53:15][C][scd30:148]:     State Class: 'measurement'
[12:53:15][C][scd30:148]:     Unit of Measurement: 'ppm'
[12:53:15][C][scd30:148]:     Accuracy Decimals: 0
[12:53:15][C][scd30:148]:     Icon: 'mdi:molecule-co2'
[12:53:15][C][scd30:149]:   Temperature 'SCD30 Temperature'
[12:53:15][C][scd30:149]:     Device Class: 'temperature'
[12:53:15][C][scd30:149]:     State Class: 'measurement'
[12:53:15][C][scd30:149]:     Unit of Measurement: '°C'
[12:53:15][C][scd30:149]:     Accuracy Decimals: 1
[12:53:15][C][scd30:150]:   Humidity 'SCD30 Humidity'
[12:53:15][C][scd30:150]:     Device Class: 'humidity'
[12:53:15][C][scd30:150]:     State Class: 'measurement'
[12:53:15][C][scd30:150]:     Unit of Measurement: '%'
[12:53:15][C][scd30:150]:     Accuracy Decimals: 0

Additional information

After each reboot of the sensor the temperature reading starts at ~19C and then quickly start dropping to way below freezing...

jcastro commented 2 years ago

@Plawasan mind asking you if your sensor also reports below 400ppm sometimes? mine does but looking at the datasheet it should be between 400-10000ppm

Plawasan commented 2 years ago

@jcastro It actually never drops below ~530ppm, even when I left it outside my window for a while, that's why I have the linear calibration in my yaml. There is a PR open to add base level calibration to esphome - https://github.com/esphome/esphome/pull/1237

As for the issue, I've left the sensor without power for ~2h, it seems to be back to normal, I've replaced the temperature offset with a generic esphome filter so I'm getting the right values now however the issue with temperature_calibration still exists.

EDIT: I've used tasmota to calibrate the sensor to 400ppm outdoors and now that I've flashed the same ESP32 with ESPHome the reported baseline in ~300ppm... so same issue @jcastro is seeing.

VS-X commented 2 years ago

Same issue here, I added the temp offset of a few degrees, but now scd30 reports a temperature of -617.64°C, and humidity of 0. Removing the temp offset, restarting and all that did not seem to help. CO2 reading seems unaffected.

RobertoSchneiders commented 2 years ago

I had the same issue after attempting to set a negative temperature offset. It's reporting temperatures of -616.19ºC . I left it without power for several hours but that didn't help.

@Plawasan did you get yours working again? if so, can you share more details of how you did it?

Plawasan commented 2 years ago

I had the same issue after attempting to set a negative temperature offset. It's reporting temperatures of -616.19ºC . I left it without power for several hours but that didn't help.

@Plawasan did you get yours working again? if so, can you share more details of how you did it?

I literally just let it sit for maybe 24h, then it started working again...

RobertoSchneiders commented 2 years ago

I had the same issue after attempting to set a negative temperature offset. It's reporting temperatures of -616.19ºC . I left it without power for several hours but that didn't help. @Plawasan did you get yours working again? if so, can you share more details of how you did it?

I literally just let it sit for maybe 24h, then it started working again...

thank you, gonna try that.

RobertoSchneiders commented 2 years ago

Unfortunately, that didn't work for me, still reporting negative temperatures.

RobertoSchneiders commented 2 years ago

I checked the sensor temperature offset using getTemperatureOffset from the Adafruit_SCD30 library and it was around -600 ºC (I set -2.5 ºC in the ESPHome config).

the way I see it, we have two different issues here:

  1. the offset is being set incorrectly
  2. when the offset is removed from the configuration it's not being updated in the sensor (so it will just stay as the last non-zero value).

I have no idea what is causing the first issue but for the second one, maybe we should call write_command(SCD30_CMD_TEMPERATURE_OFFSET, (uint16_t)(0) somewhere around here to set the offset to zero when temperature_offset_ == 0.

maybe something like (pseudo code)

uint16_t offset_temp;
if (this->temperature_offset_ != 0) {
  offset_temp =  (temperature_offset_ * 100.0);
} else {
  offset_temp =  0;
}

if (!this->write_command(SCD30_CMD_TEMPERATURE_OFFSET, offset_temp)) {
  ESP_LOGE(TAG, "Sensor SCD30 error setting temperature offset.");
  this->error_code_ = MEASUREMENT_INIT_FAILED;
  this->mark_failed();
  return;
}
bekriebel commented 2 years ago

I ran into this issue as well. It turns out that the offset value is an unsigned 16 bit integer. So, setting any kind of negative value actually creates a really large offset as that gets converted into a uint16. It looks more like constant dropping because the component also seems to take some time to apply the offset (about 10 minutes, it seems). So it drops until it reaches the low converted value. Relative humidity is also affected because the humidity value is relative to the temperature.

The offset will always reduce the value. Apparently since the device generates heat, they made the assumption that there would never be a positive offset. If you want to offset by -1.5C, you have to just put in 1.5 as the value.

Ideally the code would catch this and convert all values to positive integers before converting to the uint16. There's also the issue described of a zero value never being set, which means there's no way of fixing this except setting a very small positive value or doing the zero-value set with another codebase.

Personally, I don't like the time it takes to set the offset, so I just set mine back to zero an arduino and am using an offset filter on the value in esphome.

dequis commented 1 year ago

To set the value to zero I flashed micropython on the esp and did the following:

$ mpremote u0 mip install github:agners/micropython-scd30/scd30.py
$ mpremote u0
Connected to MicroPython at /dev/ttyUSB0
Use Ctrl-] to exit this shell
>>> from machine import I2C, Pin
>>> from scd30 import SCD30
>>> i2cbus = I2C(0, scl=Pin(22), sda=Pin(21))
>>> i2cbus.scan()
[97]
>>> scd30 = SCD30(i2cbus, 0x61)
>>> scd30.get_status_ready()
1
>>> scd30.read_measurement()
(439.2668, -214.2289, inf)
>>> scd30.get_temperature_offset()
651.36
>>> scd30.set_temperature_offset(0)
>>> scd30.soft_reset()
>>> scd30.get_status_ready()
0
[...]
>>> scd30.get_status_ready()
1
>>> scd30.read_measurement()
(437.2616, 18.69535, 27.69928)

Hope it helps someone.

(after that I added a bme280 to the board since i don't feel like messing with temperature offsets at all)

Patrick010 commented 1 year ago

Issue still not resolved, or so it seems anyway.

To calibrate co2 values I flashed an ESP32 with Tasmota, set the value an restarted. Did this with all 3 of my sensors and co2 values were the same again. Also, temperatures were all (more or less) the same. All happy I flashed my previous HA yaml again and to my surprise, the temp value was off a few degrees compared to the 2 others still running Tasmota. So I added a - 2.5 degree offset and now it returns an outside temp of -442C. Changed the offset back to 0.0, but still insane results. Something is very wrong with the measurements, or underlaying HA code, because the Tasmota gives real world measurements.

tangix commented 1 year ago

Instructions for recovering a Wemos D1 device - https://community.home-assistant.io/t/did-temperature-compensation-break-my-scd30/581401

ardichoke commented 1 year ago

Issue still not resolved, or so it seems anyway.

To calibrate co2 values I flashed an ESP32 with Tasmota, set the value an restarted. Did this with all 3 of my sensors and co2 values were the same again. Also, temperatures were all (more or less) the same. All happy I flashed my previous HA yaml again and to my surprise, the temp value was off a few degrees compared to the 2 others still running Tasmota. So I added a - 2.5 degree offset and now it returns an outside temp of -442C. Changed the offset back to 0.0, but still insane results. Something is very wrong with the measurements, or underlaying HA code, because the Tasmota gives real world measurements.

My pull request has not been merged, so there really is no expectation that it WOULD be fixed at this point. Also, do not set the offset to a negative number. As has been discussed before, the offset is converted to an unsigned int, if you convert a negative number to an unsigned int, it becomes a very large number which is what causes this behavior. This device only does negative temperature offsets apparently, so setting the offset to 2.5 would adjust it down by 2.5 degrees.