A Homebuilt CO2 Meter as a Virus Risk Proxy
Despite most of the world deciding that COVID is over, I continue to
be cautious about it. (My one bout of COVID resulted in congestive heart
failure which I'm still dealing with, so I'm fairly anxious not to get it again.)
That means that I'm cautious about indoor gatherings. Some places say they've upgraded their ventilation, but can you believe them? I've long read about people using CO2 meters as a proxy, to tell you how well the air is circulating and how high the virus load might be in a crowd, and I've wanted to get one of my own.
You can buy CO2 meters, of course. But making a custom one sounds so much
more fun! Reading Wired's story about
New Zealand's Kawaiicon cybersecurity convention
that provided CO2 trackers
inspired me to finally order some parts.
My goals were twofold: in addition to wanting a CO2 meter, I also wanted an excuse to play with CircuitPython and some of the nifty new ESP32 microcontrollers I've been seeing from vendors like Adafruit and Sparkfun. I chose Adafruit's ESP32 TFT Reverse Feather because it supports CircuitPython and has a built-in display and buttons, built-in battery charging, plus a connector that makes it easy to connect to the matching connector on the sensor without even needing to solder anything. It also has a built-in SD reader/writer, so I may eventually add data collection to this project. It's really a wonderfully designed board, especially the excellent display, and I plan to order several more of them.
Choosing a CO2 sensor was harder, because there's not much written comparing the various chips, but in the end I decided on the SCD-40 which happens to be the same sensor Kawaiicon used. Installing CircuitPython on the Feather turned out to a little tricky, but eventually I got it running. And that was the trickiest part of the whole project. With CircuitPython installed, I plugged in the sensor, loaded up some example code from the SCD-40 tutorial, and could see CO2 readings right away. (And could verify that blowing on the sensor made the number go up.)
After that, the challenge was all user interface. Since the sensor can
provide temperature and humidity as well as CO2 concentration, I wanted
to display all of them, plus battery level (the Feather lets you check
battery voltage). And I wanted the display to change color, getting
redder as the CO2 level increases. That took some effort; the GUI in
CircuitPython isn't terribly well documented and is very different from
other GUI toolkits I've used, but I found some helpful examples at
Todbot's
Circuitpython Tricks.
I set up the built-in buttons to adjust display brightness, starting it at .15 of maximum since it's meant to be used indoors: this display is quite bright and very readable, and .15 has been fine for most places I've taken it, and keeps the battery usage low.
The code for the project lives at airCO2 on GitHub.
Then of course there was the question of how to carry it around. I used a small cardboard battery box from an R/C plane battery, the smallest box I happened to have handy. It's a little bigger than it needs to be, but still fairly small; maybe eventually I'll cut off one end. 2mm machine screws were a good size to fit through the mounting holes in the Feather and the SCD-40 sensor.
The Feather is meant to run off a single-cell lithium-polymer battery (3.7V), for which Adafruit sells several sizes. I suspected the 400mAh li-po I already had would be marginal, so I included a 1200mAh with my order (I might have gone with 800 or 1000mAh, but those were out of stock). 1200mAh turned out to be plenty to run for quite a few hours with the display at reasonable indoor brightness levels.
Adafruit's batteries come with a JST plug installed, which seemed like a good choice, so I used my newly acquired JST crimping skills to make a cable I could solder to a power switch (the only soldering involved in the project was to the power switch and the non-crimp side of the JST power connector).
I'm quite pleased with the result. I've taken my little CO2 box to a couple of meetings and one party. The meeting, with lots of people crowded into a tiny church room (I would have skipped it had I known we'd been moved to a room so small) actually had good ventilation and the meter mostly stayed under 600ppm, a pleasant surprise. At the party, readings in the dining room hovered in the risky zone around 1300, but were a much more reasonable 550 in an adjacent room.
And no, the cardboard box doesn't look entirely professional,
especially where I carved out a notch to plug in a charging/reprogramming
USB cable (to the left of the buttons). That's okay with me; I think
I'd just as soon have my homemade projects look a little homemade.
On the other hand, I took it to Los Alamos Makers today and we
talked about having a workshop on building these devices, and Prisca
suggested the makerspace could 3D print some cases for them,
which would be excellent. If that happens, I'll share the details.
[ 18:06 Dec 19, 2025 More hardware | permalink to this entry | ]
![[Looking down into a small cardboard project box. There's the underside of a microcontroller, with a cable that runs from it out through a hold in the side of the box. Then there's a power cable, red and black, that runs from a power switch through a JST plug to the microcontroller and a slim li-po battery that's velcroed to the side of the box. All the components are screwed to the sides of the box with black machine screws and nuts.]](https://shallowsky.com/blog/images/hardware/airCO2/PXL_20251211_202237095T.jpg)