Building a DIY CO2 and PM2.5 sensor to measure the air quality in my office and improve my home-maker life.
As I spend most of my day in my office 🤓, I thought it would be a good idea to measure the CO2 levels of the room. CO2 isn't as dangerous as CO, but it can still pose some issues if the levels are too high. And after being in a room that hasn't any ventilation for +10h straight, the CO2 level is definitely high.
This study, found that the level of CO2 has a very negative effect on performance, particularly on thinking in general:Which is sadly something that I noticed before after a long day 😕.
I also wanted to measure the PM2.5 concentration, as it could prove useful for automations down the road.
My office does have a window and, in summer, it's pretty easy, as I leave it open all the time. In winter, however, the room gets cold quickly. Which is why I wanted a sensor that can tell me if I need to open the window.
So, what's available out there? Well, first of, I want something that won't send everything to some cloud that I don't control. That reduce the options quite a bit.
IMO, the Aranet4 from Aranet is the best sensor if I wanted something pre-made. Looks very well-made and is compatible with HomeAssistant. However, it's pretty pricey.
As I also wanted to measure the quantity of particulates floating in the air and I couldn't find a sensor that measured both that was at low enought price.
It meant DIY 🧐!
First, what do I actually need. I already have temperature and humidity from a Mi-Thermometer, I don't care much about the light level. What I do care about is:
After reading a few blog posts and watching a few videos, I choose to use the MH-Z19, it can measure the CO2 concentration in ppm from 0 to 5000ppm and the temperature and output it to either serial or PWM. Seems perfect for my needs.
For the particulate matter sensor, I choose a PMS5003 which gives me PM2.5, PM1.0 and PM10
I first hoped into SolidWorks and my something that reassembles a case.
The PMS5003 has an intake fan in it and by default the air is ejected on the same side:That doesn't really work for me, as I also want the MHZ19 to use the same air. And while technically, you could find a position which would work, I wanted to avoid spending a lot of time on this. So, I simply opened it up, figured out the air pattern and drill holes on the other side.
So, here is what I came up with:
The air comes in from the side, ejected on the other side and then passes over the MHZ19.
On the front, I added a recess for a washer that I'll use a button using the esp32 touch library, a recess for the OLED and a hole for LEDs:
On one side I added an intake hole for the fan, an output, and a hole for the USB wire.
Assembly was a little finicky. I started by inserting the OLED:
Then poured hot glue in the LED hole to act as a diffuser and then put the LED strip in:
Unfortunately, my 3D print wasn't perfect and the PM5003 didn't fit by less than a millimeter. So, I used some hot air to ease it in 😏:
Then with a lot of patience, I manage to solder everything to the ESP32 and hot glued it in place:
A bonus of the 3D print being slightly out of size, is that I can use the flat side of the PMS5003 to stick it to the wall with some double side tape.
Usually, I would write my own firmware for the ESP32 that would publish the sensor data to my MQTT server and I would create the entities myself in HomeAssistant.
However, this time I chose to use ESPHome because it's way easier to use and integrates perfectly with HomeAssistant.
So let's get started. First thing to do is to set up esphome:
Next is the interface setup, I need the two UARTs for the pms5003 and mhz19, the I2C for the OLED, the touch interface for the button and the fonts for the OLED
Then I need to add the sensors, fortunately ESPHome has platforms for the pms5003 and the mhz19. As I use an ESP32, I can also use the esp32_touch platform for the user button.
Next are the outputs, I used a small OLED with 3 pages with the only thing changing being the PM2.5 / PM1.0 / PM10, CO2 is always displayed. And the light with the
internal key to hide it from HomeAssistant.
Thankfully, esphome automatically updates the OLED content. Which is not the case of the LEDs, so I used the SNTP platform to execute a script every 1 second.
The script does the following:
Flashed the compiled esphome firmware and was greeted by some wonderful logs:
[20:43:27][D][pmsx003:236]: Got PM1.0 Concentration: 3 µg/m^3, PM2.5 Concentration 4 µg/m^3, PM10.0 Concentration: 4 µg/m^3
[20:43:28][D][mhz19:057]: MHZ19 Received CO₂=693ppm Temperature=24°C Status=0x00
The LEDs and OLED lighted up with the correct info:
I added the entities in HomeAssistant, left it for a while and got these wonderful graphs:Guess when I started soldering for another project 😅.
Overall, I'm pleased with this project, I didn't take very long to make, it's not too big, it's not really distracting unless the level is too high. It's going to be a really useful tool for long programming or soldering sessions.
Want to chat about this article? Just post a message down here. Chat is powered by giscus and all discussions can be found here: TheStaticTurtle/blog-comments