Bill of material:

  1. Adafruit Feather RP2040 (
  2. PMS5003 PM2.5 Air Quality Sensor (
  3. Lithium Battery (
  4. Adafruit Powerboost 1000 Charger (
  5. 0.96" OLED Display (
  6. On/Off Switch
  7. Power Rail (snapped an end of a breadboard)
  8. Jumper Wires
  9. M2 Screws


  • PM2.5 TX to RP2040 RX
  • PM2.5 5V/Gnd to Power Rail
  • OLED SPI to RP2040 SPI
  • OLED 5V/Gnd to Power Rail
  • RP2040 Gnd to Power Rail Gnd
  • RP2040 USB to Power Rail 5V
  • PowerBoost 5V/Gnd to Power Rail
  • PowerBoost En/Gnd to Switch

To start the project, I ordered a few parts, such as the PM2.5 sensor, battery and RP2040, while reusing a bunch of other parts I had laying around from other projects.  I initially wired everything using a Raspberry Pi Zero W, as the PM2.5 sensor requires 5V input and my pile of microcontrollers only supply 3.3V.  I just received my first 3D printer (an FLSun SR), and quickly learned some basic Fusion 360 and designed a case for it. However, the start-up time for the PiZero is too long and quickly became frustrating.  

The insides of the PiZero version.  There are no mounting holes on the PM2.5 daughterboard, so I have it loose.

Front view.  Very clean air at my office!

After a few days, I did decide to abandon the Zero and switch to a microcontroller.  To solve the lack of 5V output from them, I resorted to using an Adafruit Powerboost 1000C, which outputs 5V. I did not plan on having the device connect to the internet, so I used the Feather RP2040, as opposed to an ESP32-S2.  I prefer Circuitpython over Arduino, so that also helped in the decision.  I did not update my 3D model, but was able to re-use one of the mounting holes for the PiZero, which is enough to hold it in securely.  With the 2200mAh battery, it can stay on for about 24 hours continuously.  Start-up time is now only 2-3 seconds.  

Insides a little messier now, but still too much space inside.

Home office air not as clean, but still very good!

But pan-frying meat is extremely bad, even with vent on full!

An hour later and across the kitchen, AQI is still very high.  It took 3-4 hours to lower it with a window open.

I had a lot of fun building this and learned a lot regarding 3D modeling and printing.  I learned that Inland Black PLA has bad batches that are very hard to print with, which is why my print does not look very clean.

For the reader:

I have attached all the models and code so have fun building your own!

Feel free to update the 3D model to be more compact and to properly mount the RP2040.

One little issue with the code is that it occasionally runs out of memory, so I have it reset each time it does.  It doesn't bother me enough to dig into it, but it probably is related to driving the OLED graphics.