CO2 monitoring with SCD30 sensor and HA integration

I agree, the two plots are almost identical, it merely look like a calibration difference.
Please show us the results once you have them, it would be interesting to see how efficient the self calibration is.
I’m quite satisfied after more than a year of use.
The only modification I made was to move the sensor out of the enclosure to not be affected by the heat generated from the Wemos D1 board, and I did the same with all the sensors at home of the same kind.

The SCD30 keeps showing 200 ppm lower than the Sense Air S8 when using ESPHome after 2 weeks.

I tried to flash the SCD30 followed the guides shown in this link CO2 Gadget: Advanced CO2 Meter - eMariete, then the CO2 value seems ok. Now, it is about 60ppm higher than Sense Air S8.

Could anybody tell me the reason? Thank you.

SCD30’s measurement response highly depends on the sampling interval


(higher the interval, the longer response time). Please note, that you get to perform a calibration after every sampling interval change.

The proper instructions on how to calibrate SCD30 are here. I recommend using the FRC (force re-calibration) if possible. If you calibrate and use the sensor according the official guidelines, you should get accuracy of ± 30 ppm.


This document describes the correct way the sensor should be handled.

Sense Air S8 seems to have accuracy of ± 70 ppm which makes the 60ppm deviation (that you’re reporting) in-tolerance. I’ll also link to a Sense Air S8 sensor handling manual, for the record.
Also note, that the 200ppm difference might be caused by the ABC being executed in various times or intervals, so each sensor might apply correction from a different base.

1 Like

How to do that with ESPHome (or better is that even possible)?
I just bought a second SCD-30 and the values between both sensors differ a lot. (630 vs 750 ppm).

2 Likes

I have no experience with ESPHome but a quick googling led me to this

so it looks like it hasn’t been implemented yet.

mhm. looks like I need to explore how to perform a FRC…

put both sensors outside the window and that’s the result:

Screenshot 2021-12-28 at 19-15-01 Übersicht - Home Assistant

well, you can always dedicate 1 es8266 board to sensor calibration - flash it with tasmota, set it all up and simply connect the sensor to it; perform FRC, then disconnect it and connect it back to the esphome board.
or find a way to perform low-level i2c commands from esphome.

1 Like

Thanks you!

flashed latest tasmota-sensors on a spare esp32 and calibrated both sensors. Next to each other the value is pretty much the same (+/- 20ppm).

for those who do not know about tasmota:

download and flash tasmota-sensors.bin
connect to the ap spun up by the esp
enter your wifi credentials and connect afterwards to the device
Under Configuration → Module set the correct Pins for SDA and SCL
Go to Console and use the command scd30cal XXX with your preferred value (I’ve set both sensors to 400 ppm after a few minutes outside)

1 Like

Glad you figured it out. Btw, I tend to calibrate it to 410ppm. it’s probably much closer to reality these days than 400ppm (especially in urban area). But it doesn’t matter much.

1 Like

With sampling internal of SCD30 of 3s, its readings are basically the same as those of SenseAir.

Wish the SCD30 could be calibrated in ESPHome after changing the sampling interval.

If I understant well, there are no way to force recalibration with ESPHome ? I thought it was an essential feature to have correct measurements ?

@void thanks for sharing the calibration process.
Is calibration going to “stay” with SCD30 sensor after you disconnect it from one esp board to another ? I mean if the calibration will be effective after the sensor is disconnected from power for some time… ?

Yes. this is being saved on a SCD30 eeprom.

1 Like

as @rplevka said, it is saved. I turned the self calibration off and will manually trigger the calibration twice a year

1 Like

Thanks!
I did calibration using spare ESP32 based on @void inspiration and I was actually surprised how easy it goes. Took me less then 10 minutes to load tasmota.sensors to ESP32, setup WiFi and I2C pins. Then took my breadboard (with esp32 and scd30) outside, waited 10 minutes and did calibration. Took te sensor back to esphome and it read correct Co2 levels !

One more clarification as @LeNT mentioned few post before:

Does this mean that if I do calibration with Tasmota and then change the sampling interval in esphome I need to go back and calibrate again ?

yes. Mind that the sampling interval is also a setting done to a sensor itself, not the platform. so yes, every change to the sampling interval settings requires re-calibration as the official sensor documentation states.

1 Like

Actually it seems that in my (maybe specific) case it does not need to be calibrated.
I have calibrated using Tasmota, remove CO2 sensor and connected to ESPHome, changed the sampling interval from 30s to 10s and move the sensor outside where it was calibrated 30 minutes ago to 410ppm.
And it shows after few minutes 409-411 ppm.
So I will bring it inside for few days and will see how it goes and if suspected issue will check/calibrate again.
Thank you all for help.

And if anything I can do to help moving this PR into live version let me know. :slight_smile:

Hello,
im kinda new into ESPHome.
I tried to test the Sensor with an ESP8266.
My yaml looks like this

esphome:
  name: co2

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "4e20b77e471dc368d29dba9ae2194c6d"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Co2 Fallback Hotspot"
    password: "d0ylra9bVdak"

captive_portal:


i2c:
  sda: 2
  scl: 1
  scan: True
  id: bus_a
  
sensor:
  - platform: scd30
    co2:
      name: "ESPsensor CO2"
      accuracy_decimals: 1
    temperature:
      name: "ESPsensor Temperature"
      accuracy_decimals: 2
    humidity:
      name: "ESPsensor Humidity"
      accuracy_decimals: 1
    #temperature_offset: 1.5 °C
    address: 0x61
    #update_interval: 60s

and i get these in my log files

INFO Reading configuration /config/esphome/co2.yaml...
INFO Starting log output from co2.local using esphome API
INFO Successfully connected to co2.local
[22:46:17][I][app:102]: ESPHome version 2022.2.6 compiled on Mar  8 2022, 21:46:09
[22:46:17][C][wifi:491]: WiFi:
[22:46:17][C][wifi:353]:   Local MAC: 40:91:51:52:10:9E
[22:46:17][C][wifi:354]:   SSID: [redacted]
[22:46:17][C][wifi:355]:   IP Address: 192.168.178.103
[22:46:17][C][wifi:356]:   BSSID: [redacted]
[22:46:17][C][wifi:358]:   Hostname: 'co2'
[22:46:17][C][wifi:360]:   Signal strength: -69 dB ▂▄▆█
[22:46:17][C][wifi:364]:   Channel: 3
[22:46:17][C][wifi:365]:   Subnet: 255.255.255.0
[22:46:17][C][wifi:366]:   Gateway: 192.168.178.1
[22:46:17][C][wifi:367]:   DNS1: 192.168.178.1
[22:46:17][C][wifi:368]:   DNS2: 0.0.0.0
[22:46:17][C][logger:233]: Logger:
[22:46:17][C][logger:234]:   Level: DEBUG
[22:46:17][C][logger:235]:   Log Baud Rate: 115200
[22:46:17][C][logger:236]:   Hardware UART: UART0
[22:46:17][C][i2c.arduino:038]: I2C Bus:
[22:46:17][C][i2c.arduino:039]:   SDA Pin: GPIO2
[22:46:17][C][i2c.arduino:040]:   SCL Pin: GPIO1
[22:46:17][C][i2c.arduino:041]:   Frequency: 50000 Hz
[22:46:17][C][i2c.arduino:044]:   Recovery: bus successfully recovered
[22:46:17][I][i2c.arduino:054]: Results from i2c bus scan:
[22:46:17][I][i2c.arduino:056]: Found no i2c devices!
[22:46:18][C][scd30:121]: scd30:
[22:46:18][C][scd30:122]:   Address: 0x61
[22:46:18][W][scd30:126]: Communication failed! Is the sensor connected?
[22:46:18][C][scd30:140]:   Altitude compensation: OFF
[22:46:18][C][scd30:144]:   Automatic self calibration: ON
[22:46:18][C][scd30:145]:   Ambient pressure compensation: 0mBar
[22:46:18][C][scd30:146]:   Temperature offset: 0.00 °C
[22:46:18][C][scd30:147]:   Update interval: 60s
[22:46:18][C][scd30:148]:   CO2 'ESPsensor CO2'
[22:46:18][C][scd30:148]:     State Class: 'measurement'
[22:46:18][C][scd30:148]:     Unit of Measurement: 'ppm'
[22:46:18][C][scd30:148]:     Accuracy Decimals: 1
[22:46:18][C][scd30:148]:     Icon: 'mdi:molecule-co2'
[22:46:18][C][scd30:149]:   Temperature 'ESPsensor Temperature'
[22:46:18][C][scd30:149]:     Device Class: 'temperature'
[22:46:18][C][scd30:149]:     State Class: 'measurement'
[22:46:18][C][scd30:149]:     Unit of Measurement: '°C'
[22:46:18][C][scd30:149]:     Accuracy Decimals: 2
[22:46:18][C][scd30:150]:   Humidity 'ESPsensor Humidity'
[22:46:18][C][scd30:150]:     Device Class: 'humidity'
[22:46:18][C][scd30:150]:     State Class: 'measurement'
[22:46:18][C][scd30:150]:     Unit of Measurement: '%'
[22:46:18][C][scd30:150]:     Accuracy Decimals: 1
[22:46:18][C][captive_portal:144]: Captive Portal:
[22:46:18][C][mdns:084]: mDNS:
[22:46:18][C][mdns:085]:   Hostname: co2
[22:46:18][C][ota:085]: Over-The-Air Updates:
[22:46:18][C][ota:086]:   Address: co2.local:8266
[22:46:18][C][ota:089]:   Using Password.
[22:46:18][C][api:138]: API Server:
[22:46:18][C][api:139]:   Address: co2.local:6053
[22:46:18][C][api:143]:   Using noise encryption: NO

I wired
3v3 to VNN
GND to GND
D1 to SCL
D2 to SDA

I also soldered a Pin header onto the sensor, cause i read not soldered connections can cause faulties.

I hope somebody can help me.
:smiley:

@Maco65 - I believe the sensor retains the needs to be re-calibrated after 7 days with no power. Best thing to do is leave it powered on 24/7.

What esp do you use? Maybe replace “1” and “2” with “D1” and “D2” in the i2c section and see if that works.

[22:46:17][I][i2c.arduino:054]: Results from i2c bus scan:
[22:46:17][I][i2c.arduino:056]: Found no i2c devices!
[22:46:18][C][scd30:121]: scd30:
[22:46:18][C][scd30:122]:   Address: 0x61
[22:46:18][W][scd30:126]: Communication failed! Is the sensor connected?

Maybe use other ports for SDA/SCL or/and double-check if the module is connected