In January 2025 I built an air quality monitor to use for the Energy Devroom at FOSDEM. It was inspired by Chris Adams who raised the topic of air quality in FOSDEM Devrooms. Air quality is a good indicator for the level of ventilation and thus risk of transmitting airborn diseases.
Ready-made air quality monitors exist, but it is more fun to do it yourself.
There are different sensors available to measure CO₂ levels. This page by airgradient.com gives a good overview of different sensor types.
Sensirion SCD40 and SCD41
The Senserion SCD40 and SCD41 sensors are popular choices that are widely available. The SMD component is very small. SCD41 is the variant of SC40 intended for industrial applications, that can read higher CO₂ levels and is even more precise. The SC40 should suffice for this application of having a good estimation of CO₂ level and thus level of ventilation.
I got the GY-SCD40 module that has a Molex Picoblade connector.
Automatic calibration
Be aware that this sensor automatically self-calibrates by assuming the lowest CO₂ reading last week was an outdoor situation of 400ppm. Leaving the sensor too long in a room that is not ventilated enough to go down to outdoor levels will result in an offset in the values. This automatic calibration can be disabled and factory calibration can be restored.
Sensirion SCD30
The Senserion SCD30 is the predecessor of the SCD40 is also well tested. The sensor module is larger than the SCD40.
An even smaller sensor than SCD40 but doesn't measure CO₂ directly. Because of this, it can be thrown off by other gasses, including from deodorizers. But it is the cheaper option.
The availability of sensor profiles and other convenient features in ESPHome made it a requirement to be able to run ESPHome. ESPHome supports five different microcontroller platforms, covering many development boards.
Wemos LOLIN D1 mini
The Wemos LOLIN D1 mini was mentioned a couple of times because of its low cost. I2C is available on pin 4 and 5 (for use with shields like the SGP30 shield for the D1 Mini) or on the JST-SH I2C connector. Unfortunately Wemos chose a different pin order than the commonly used pin order of Qwiic, also known as STEMMA QT.
I did start this project on a Wemos LOLIN D1 mini with a 8x8 RGB LED shield to use LED color as indicators. It became clear that it was uncertain if exposing the ESPHome web interface at FOSDEM would work reliably. Thus I needed a solution where the values could be read even if no internet or laptop was available. That brought me to the next board, the LilyGo T3 S3.
LilyGo T3 S3
Being interested in Meshtastic, this board seemed a good entry into the ecosystem. The LilyGo T3 S3 comes with a small OLED screen connected to I2C. The ESP32-S3FH4R2 microcontroller can drive a second I2C bus, for which any GPIO pins can be chosen. I chose the pins 43 and 44, connected to the middle JST-SH connector. This pinout is compatible with Qwiic, also known as STEMMA QT.
The screen and external connector make it a good solution for this project.
The configuration board was only recently merged in PlatformIO. It cannot be used until PlatformIO has published a new release and it is included in ESPHome. Until then, explicit parameters in ESPHome need to be used to use this board.
I decided to focus on the OLED screen for values and also for warnings.
Three levels of indicators are used:
Good: value is fine, no additional indicators.
Warning: value is out of normal range and intervention is needed. Icon is used to signal this.
Critical: value is far out of normal range and intervention is needed immediately. A blinking icon is used to signal this.
If a blinking critical indicator is on, the signal is strengthened by blinking a border at the edge of the screen.
I didn't see a reason to distinguish between too low or too high values.
Fonts and icons
ESPHome has a font renderer component with many features. It is easy to use Google Fonts directly, reducing the need for manual configuration. I chose to use Roboto Condensed as the base font, supplemented with Material icons.
Cable sleeve
The incompatibility of connectors between the board and the module resulted in two adapter cables via header connectors. I could have put heat shrink or even around the wire mess to clean it up, but that would be difficult to remove when adapting to a new project. I got the idea to create a miniature version of a spiral cable wrap, often used behind a computer or TV to bundle cables, by cutting a plastic straw at an angle. This worked rather well as the combination is still flexible and easy to put on and remove. Too bad I only found out about this great use of plastic straws after the environmental ban in Europe.
Code
Sensor is programmed in ESPHome meta-programming framework.