An ESPHome component for a CO2 sensor
SCD41 on a quiet wall, one sample a minute, and the calibration mistake that made the living room look like a brewery.
The living room needed a carbon dioxide number I could trust while people were actually in it. A desk toy that updates every five seconds is a different instrument. I wanted a wall node: ESP32, Sensirion SCD41, and ESPHome, because the rest of the flat already speaks that.
What the component does
ESPHome already has an scd4x platform. I did not write a new C++ component. I wrote the node definition the way I want the entity to behave in Home Assistant: one sample a minute, temperature and humidity from the same die, and no automatic baseline while the room is occupied all evening.
i2c:
sda: GPIO6
scl: GPIO7
frequency: 50kHz
sensor:
- platform: scd4x
co2:
name: "Living room CO2"
accuracy_decimals: 0
temperature:
name: "Living room temperature"
humidity:
name: "Living room humidity"
update_interval: 60s
automatic_self_calibration: false
Fifty kilohertz on I2C is slower than the default and dull. The run to the sensor is short, but the ESP32-C3 I used shares the bus with nothing else and I would rather have a boring clock than a flaky ACK.
Where it sits
Height is about 1.5 m, on an inside wall, not above a radiator and not in the path from the kitchen. The first mount was on the bookcase next to a candle. The trace looked like a party. Candles and cooking are real CO2; they are also not the number I open a window for. The sensor moved to the wall opposite the hob.
Automatic self calibration assumes the room hits outdoor air often enough. This flat does not, in January. I turn ASC off and force a calibration when I have had the windows open for half an hour and the reading has sat still.
The brewery reading
The first week the baseline sat near 750 ppm with the windows open. That is not outdoor air here. I had powered the board on the bench, inside a closed room, and let the sensor's first hours become its idea of fresh. Forced recalibration after a real airing brought the empty room back to the low 400s. Occupied evenings now land between 800 and 1400, which matches how the room feels.
I do not alarm on a single sample. The automation waits for two consecutive readings above 1200 ppm before it asks for a window. One spike is someone breathing on the box.
What I would change
The enclosure is a printed box with a slot, not a sealed project case. A sealed case lags by several minutes and then lies. If I rebuild it I will add a small pressure equalization hole and keep the SCD41's own cap clear of the plastic. The ESPHome side can stay as it is.