esphome / issues

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

Senseair S8 readings overflow #1899

Closed nmaggioni closed 3 years ago

nmaggioni commented 3 years ago

Operating environment/Installation (Hass.io/Docker/pip/etc.): Docker

ESP (ESP32/ESP8266, Board/Sonoff): Wemos D1 Mini (ESP8266)

ESPHome version (latest production, beta, dev branch) v1.16.2 (808ce6e)

Affected component: Senseair CO2

Description of problem: At seemingly random intervals the sensor's readings increase rapidly to ~65535 in a matter of a reading or two, linger around that value for a while, and then eventually overflow/reset back to 0. Some hours/minutes later, the sensor eventually goes back to working fine until the event repeats.

I started using this sensor about two months ago, but only in the past weeks I've started to notice this behavior. The CO2 levels in the bedroom the sensor is in are expected to be between 500 and 2500ppm most of the time.

Here's the data that was logged for the past week, pulled directly from Home Assistant (ESPHome -> HA -> NodeRED -> InfluxDB -> Grafana) and matching the values seen in both HA's interface and ESPHome logs:

Schermata da 2021-03-11 11-21-15

A single prolonged erroneous spike can be seen under the cursor around 03/06 00:00, and multiple shorter ones around 03/09 00:00, 03/10 00:00, 03/10 12:00, 03/11 00:00, and at the right (current) edge of the graph. Coincidentally, these spikes seem to tend to happen (but are not limited to) at night when the CO2 levels are higher due to people sleeping in the room.

Problem-relevant YAML-configuration entries:

sensor:
  - platform: senseair
    co2:
      name: "${room}_CO2"
      filters:
        - delta: 1000
    update_interval: 60s

Logs (if applicable):

[10:31:41][I][app:105]: ESPHome version 1.16.2 compiled on Mar 11 2021, 10:31:20
...
[10:31:41][C][senseair:085]: SenseAir:
[10:31:41][C][senseair:086]:   CO2 'camera_nicco_co2_CO2'
[10:31:41][C][senseair:086]:     Unit of Measurement: 'ppm'
[10:31:41][C][senseair:086]:     Accuracy Decimals: 0
[10:31:41][C][senseair:086]:     Icon: 'mdi:molecule-co2'
...
[10:32:06][D][senseair:050]: SenseAir Received CO₂=65506ppm Status=0x00
[10:32:06][D][sensor:092]: 'camera_nicco_co2_CO2': Sending state 65506.00000 ppm with 0 decimals of accuracy
...
[10:33:06][D][senseair:050]: SenseAir Received CO₂=65503ppm Status=0x00
[10:33:06][D][sensor:092]: 'camera_nicco_co2_CO2': Sending state 65503.00000 ppm with 0 decimals of accuracy
...
[10:34:06][D][senseair:050]: SenseAir Received CO₂=65503ppm Status=0x00
[10:34:06][D][sensor:092]: 'camera_nicco_co2_CO2': Sending state 65503.00000 ppm with 0 decimals of accuracy
...
[10:35:06][D][senseair:050]: SenseAir Received CO₂=65503ppm Status=0x00
[10:35:06][D][sensor:092]: 'camera_nicco_co2_CO2': Sending state 65503.00000 ppm with 0 decimals of accuracy
...
[10:36:06][D][senseair:050]: SenseAir Received CO₂=65501ppm Status=0x00
[10:36:06][D][sensor:092]: 'camera_nicco_co2_CO2': Sending state 65501.00000 ppm with 0 decimals of accuracy

Additional information and things you've tried:

As seen in the config above, I've tried adding a delta filter with a value of 1000 to ignore the erroneous spikes but it hasn't had any effect since they continued to appear, even if they seem to now have a much shorter peak duration.

Restarting or reflashing the ESP seems to have no effect: the logs above are taken right after a reflash.

nmaggioni commented 3 years ago

After some more testing it seems that something is wrong with ABC calibration: here I've opened the room's window at night when pollution is generally lower.

The sensor's readings slowly dropped to zero as the fresh air came in, underflowed to 65535 and dropped some more; as I closed the window and CO2 levels started rising again, the value overflowed back to 0 and rose back to the expected levels (~450 ppm).

senseair_s8_underflow_2

Since ESPHome doesn't interact with calibration at any point, in absence of others' opinions I think this issue could be closed and reported upstream to SenseAir.

nmaggioni commented 3 years ago

Quoting SenseAir's reply to my enquiry:

There are different things which can be wrong at your setup.

  1. CO2 readings can be negative if calibration was wrong for longer time.

With wrong variable declaration negative values will be shown with high readings.

It should be the format of 2 bytes signed integer.

  1. If sensor didn't see CO2 concentration greater than 400ppm for longer time, than its possible that you get negative readings.

You can start manually a zero calibration which will the most accurate way to recalibrate the sensor.

As a second way you can perform a background calibration at 400ppm environment. Fresh air early in the morning should be working.

  1. Overwrite the offset register for calibration and wait some ABC periods that sensor correct it himself again.

For private application it will be also sufficient to increase the ABC period maybe to a longer intervall, that it will be guaranteed that sensor see concentration around 400ppm.

4 Commands to write zero to the ZeroTrim register:

Write 0 to ZeroTrim:

68 address / 41 write to RAM / 0078 address / 02 Num of bytes / 00 00 Data / 44B7 CRC

6841007802000044B7 Transfer RAM to EEPROM

68 address / 41 write to RAM / 0060 address / 01 Num of bytes / 02 Data / B4B3 CRC

684100600102B4B3

As an option, reset the sensor:

68 address / 41 write to RAM / 0060 address / 01 Num of bytes / FF Data / 7532 CRC

6841006001FF7532

That should be possible ways to reset or recalibrate the sensor.

  1. SenseAir recommends an int16, but currently an uint16 is used to store the readings. Given that we're not interested in negative values, I'd say that under/overflows are behaving as expected.
  2. Background calibration doesn't seem to be effective in my case as this issue is persisting even after a couple of weeks, even though the room's CO2 levels supposedly drop to the ~400ppm mark every morning. See below.
  3. Maybe implementing a manual reset for the calibration offset could help in cases like mine? The same goes for changing the ABC interval.