https://www.jeffgeerling.com/blog/2021/airgradient-diy-air-quality-monitor-co2-pm25 Skip to main content Jeff Geerling Main menu * Blog * Projects * About Monitoring my home's air quality (CO2, PM2.5, Temp/Humidity) with AirGradient's DIY sensor September 8, 2021 A few months ago, I found this Hacker News post about the AirGradient DIY Air Quality Monitor. I had already been considering buying an AirThings Wave Plus sensor to monitor my home's CO2 levels, but the high price and limited 'ownership' of the data coming from it turned me off. AirGradient DIY Air Quality Sensor - Focus Stacked by Jeff Geerling So I built two AirGradient DIY air quality monitor boards (see above), and integrated them into my Prometheus + Grafana home monitoring setup I've been using to monitor other things in my house: AirGradient DIY Grafana Dashboard for CO2 PM2.5 Temperature Humidity monitoring I emailed Achim, the founder of AirGradient, and took him up on his offer for free PCBs if I paid the shipping cost. A couple weeks later I received two fresh PCBs from Thailand. If you don't want to wait for the shipping, or want to make a bunch of sensor boards, you can also download the Gerber files from the AirGradient DIY page and have your own PCBs made. Parts and Cost As suggested on the DIY sensor page, I ordered all the components through AliExpress. The prices there were often half what they were from any US supplier, though shipping was a different matter--even though shipping direct from China was a pittance (free, in fact, for most of the components), it took at least a month for all the various components I ordered to arrive. With most US suppliers, I could get 2-3 day shipping; but, for one example of the price difference: the same SenseAir S8 that cost $30 from AliExpress costs $60 from a US distributor! Here's the list of all the prices I paid, to get an idea of the total cost (all prices in USD): * Shipping for 2 free AirGradient PCBs from Thailand: $9 * SenseAir S8 CO2 Sensor: $28 * WeMos D1 Mini: $3.11 * D1 Mini OLED Shield: $4.30 * SHT30 Temperature and Humidity Sensor: $4.42 * Plantower PM2.5 Sensor: $13.80 Note that when I went to order the Plantower sensor, it was out of stock, so I picked one up from Amazon instead (DEVMO PMS5003 PM2.5 particle sensor) for $35. Steep price difference, but hey, at least I got it! All-in, the components for this project cost between $60-80, depending on where you get your parts. Assembly and Soldering AirGradient's DIY assembly guide is already pretty solid, but if you want even more detail, watch my video on the DIY air quality monitor, where I show each step of the assembly: The hardest part is the stripping and soldering of the tiny stranded wires that come with the PM2.5 sensor, but I made short work of it with a little Adjustable Wrench Stripper that's designed for stripping smaller-gauge wires. 3D Printed Case AirGradient also offers a 3D-printable case and wall mount bracket, which seem to fit together well (if not a bit tight) and hold the board in the best orientation for the various sensors to work well. AirGradient DIY air quality monitor mounted on wall inside 3D Printed case The case is well-ventilated, and my only complaint is the natural convection causes very-slightly-warmed air from the WeMos D1 and CO2 sensor to pass over the temperature and humidity sensor on the top, meaning those readings are always a bit higher than ambient--at least in my office. Flashing the firmware / AirGradient software With the hardware put together, I followed the guide for setting up the software on the WeMos D1 Mini. The guide was decent, but I figured I'd go through every step in detail here, especially since I changed a few things to make it easier for me to get air quality data on my local Prometheus instance instead of on AirGradient's servers. First, the easiest way to flash an ESP8266 is to Install Arduino IDE. On my Mac, since I use Homebrew, it was a simple matter of: brew install --cask arduino Then you have to configure Arduino IDE so it can manage an ESP8266 board like the WeMos D1 Mini: 1. Open Arduino IDE 2. Open the Preferences window 3. Add http://arduino.esp8266.com/stable/ package_esp8266com_index.json to "Additional Boards Manager URL". 4. Open "Boards Manager..." from Tools > Board menu. 5. Search for the "esp8266" board and install it's latest version. 6. Select "LOLIN(WEMOS) D1 R2 Mini" from the Tools > Board > ESP8266 menu. Optionally, you can test your setup by uploading the Blink sketch: 1. Open File > Examples > 01.Basics > Blink. 2. Make sure "LOLIN(WEMOS) D1 R2 Mini" is selected in the Tools > Board menu. 3. Go to Tools > Port and select the USB serial port where the ESP8266 is plugged in (in my case, "/dev/cu.usbserial-210") 4. Click the 'Upload' button (right arrow) to upload the sketch to the board. After a minute or so, the blue onboard LED (which is under the OLED shield) should start blinking continuously. Now it's time to flash the AirGradient software to the WeMos D1 Mini: 1. Go to Tools > Manage Libraries... 2. Search for "AirGradient", and install the latest version. 3. Choose "C02_PM_SHT_OLED_WIFI" from the File > Examples > AirGradient Air Quality Sensor menu. 4. Install the libraries suggested at the top of the file via Tools > Manage Libraries... + WifiManager by tablatronix + ESP8266 and ESP32 OLED driver for SSD1306 by ThingPulse 5. Optionally enable WiFi at this point by setting the connectWIFI variable to true. 6. Upload the sketch to the ESP8266. 7. After a minute or so, the OLED display should read "Init", then after a delay it will start printing PM2.5, CO2, and Temperature/ Humidity numbers, in sequence. I actually forked the C02_PM_SHT_OLED_WIFI example and maintain my own copy, which points the board at my local Prometheus instance. You can see my forked copy here: AirGradient-DIY.ino. Getting data into Prometheus If you just set connectWIFI to true, it would send data to AirGradient's servers (defined in the the APIROOT variable). The payload is simple JSON, so I wrote a script that logs the data from the sensor, and another script running at a /metrics endpoint, which returns the latest data when Prometheus requests it. Those PHP scripts, along with a README file that explains how to run them in a tiny Docker container, are available in my open source AirGradient Prometheus Exporter project on GitHub. To get the AirGradient board to send its data to my Internet Pi--where I chose to run the AirGradient exporter--I changed the APIROOT in the Arduino sketch to http://geerli.net:9926/. I actually have two air quality sensors running now--I set the first one to port 9925, and the second to port 9926, and my Internet Pi has two Docker containers running the individual exporter for each port. I flashed the device using Arduino IDE, then when it showed 'Connect to WiFi' on the screen, I connected directly to the device's 'AIRGRADIENT' WiFi hotspot, then my Mac popped up the connection screen, and I added the credential to connect it to an 802.11 b/g/n access point on my network. After a few seconds, it connected, then every 9 seconds or so, the sensor POSTS something like the following data to the Raspberry Pi: 10.0.100.74 - - [06/Jul/2021 12:54:59] "POST /sensors/airgradient:1995c6/measures HTTP/1.1" 200 - INFO:root:POST request, Path: /sensors/airgradient:1995c6/measures Headers: Host: geerli.net:3939 User-Agent: ESP8266HTTPClient Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0 Connection: keep-alive content-type: application/json Content-Length: 56 Body: {"wifi":-51,"pm02":5,"rco2":1605,"atmp":32.60,"rhum":37} The script running in the Prometheus Exporter then stored the data in a file, and when Prometheus calls the /metrics endpoint on the same port, the metrics are transformed into a format Prometheus can understand. Finally, once I had all that data, I built dashboards in Grafana to display the air quality sensor data over time--one for the board in my basement office, and one for the board upstairs in the main part of my house: AirGradient DIY Air Quality Sensor Graph CO2 PM2.5 Temperature and Humidity in Grafana It's easy enough to identify when I was in the office if you look at the CO2 graph above--and I can imagine if there were more people crammed into that 12 sq ft space, it would spike even higher! The levels top out around 900 ppm when I have my air vent open in the office, but I've observed them going beyond 3000 ppm when I closed the vent and was in the office for more than a couple hours at a time. So... moral of that story is to make sure you have some fresh air circulation! Conclusion The sensor package and board layout aren't perfect; the temperature and humidity sensor, in particular, is always a few degrees (F) higher than other known-working thermometers display. And the SenseAir S8 takes a couple weeks before its self-calibration routine finishes--until that's done, CO2 levels will likely show as being at least 200 ppm higher than they actually are. But after a few weeks, and after adding in a manual temperature adjustment to compensate for that sensor's inaccuracy, the AirGradient has been a very stable and helpful addition to my home environment monitoring. PM2.5 in danger zone from monitoring with AirGradient DIY In fact, after having my basement windows replaced, the PM2.5 sensor indicated particulates were above 50 mg/m3, which is an actionable level--if I hadn't opened a window with a fan circulating extra outside air, that level would've remained high for many hours, exposing my family to whatever tiny bits of dust and chemicals lingered in the air. If you want even more detail about the build process, check out my YouTube video on the AirGradient DIY Air Quality sensor. co2 air quality sensor raspberry pi arduino home diy youtube video pcb electronics * Add new comment Comments Daniel - 4 hours ago How does calibration work? How can you be confident it has accurate results? * Reply Jeff Geerling - 4 hours ago In reply to How does calibration work?... by Daniel If you want lab-grade results, you'd need the right testing equipment (see SenseAir's website), but I'm okay with consumer-grade. So for that, my informal process is to place multiple sensors (ideally from different vendors--e.g. TemTop + my DIY sensor + another if I have it) next to each other a foot or so away in a couple places for a couple days, and compare the results. If they're within a close range, they're accurate, if not, they're not, and they may need adjustment. For the temperature sensor on the DIY board, it is definitely 5-10degF higher than ambient, so I'll need to figure out a better solution for its placement. For the PM2.5 and CO2 sensors, the data between the TemTop and my two DIY boards is very close (usually < 2% difference, e.g. TemTop reads 820 ppm, DIY reads 814 ppm). But note that the SenseAir S8, at least, requires at least a couple weeks to self-calibrate--it does that I think by trying to get a baseline, and that baseline it calibrates to is somewhere around 440 ppm? Not quite sure, but I remember reading about it in a spec sheet and thinking it was a little above my pay grade. There's a way to force-calibrate it, too, if you have a stable environment where you can do that. * Reply koryk - 2 hours ago This is great! I did something similar with the AirThings Wave Plus. I know you were concerned about the ownership of the airwave plus data, but the cloud functionality relies on the phone app to upload to their servers. I use a raspi with a bluetooth dongle to extract the data using their python reader https://github.com/Airthings/ waveplus-reader. This makes it so the data stays within my house. I expose that data as a prometheus endpoint and have a very similar looking dashboard - https://i.imgur.com/OZFyB0M.png . I am using a SDS011 Nova PM Sensor for the particulate. Radon sensor was my highest priority when making this set up, because I wanted to make sure my Radon suppression system was functioning correctly * Reply Marcos Lima - 2 hours ago Do you know if we could swap out the Plantower PM2.5 PMS5003 senor to something else like the PMS9103M? I have not been able to find a clear comparison of the different sensors and what would be best for a house. * Reply BillB - 44 min ago Now sure what your data ownership issues are, but you can read directly from the device, there's even an example graphana dashboard if you want to avoid using a cloud. The data is yours to do with as you wish. * Reply Jeff Geerling - 2 sec ago In reply to Now sure what your data... by BillB It was my understanding you had to use an app to do the initial setup of the AirThings devices, but if you can do it completely standalone, separate from an Internet connection, that would make my opinion a lot more favorable! Though it's still quite pricey. * Reply Daniel Smullen... - 39 min ago It seems to me that perhaps if you rotated the entire sensor assembly 90 degrees counterclockwise, the convection airflow passing over the temperature sensor would be mitigated at least somewhat. Seems like an easy fix, you'd just have to rotate the output on the OLED display in your Arduino sketch. I think that's possible by simply adjusting the parameters during initialization of the OLED library. Does this make sense? By the way, it would be awesome if you combined this sensor data with a controller on your furnace fan (separate from the heating and cooling) or another actuator (perhaps controlling a window opener or a fan to the outside, or both) to automatically keep the particulate and CO2 levels low. If your furnace has a HEPA filter, it'll handle the particulates, and the air flow should handle the CO2 buildup. The way I see it, you could manually calibrate a PID controller based on taking readings periodically. It may be possible to do this automatically over a certain period of time since you're collecting time-series data on your rpi. It would neat to use some basic time-series predictive modelling to give proactive notifications about participate and CO2 levels going high. This link has a super simple tutorial for Python that you could walk through and apply on the data coming straight out of your grafana instance: https://www.bounteous.com/insights/2020/09/15/ forecasting-time-series-m... Walking through this stuff would make for a great YouTube video, with a fairly minimal amount of burden I think. * Reply Search [ ] [Search] Geerling Family Crest All content copyright Jeff Geerling. Top of page.