It's easy to use the PM2.5 and the Adafruit CircuitPython PM25 module. This library allows you to easily write Python code that reads particle concentrations, and particle diameter and the number of particles with different diameters per unit volume.
You can use this sensor with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.
CircuitPython Microcontroller Wiring
First, connect the sensor to your microcontroller board using UART (a serial port).
Here is an example of it connected to a Feather M0 using UART:
- Sensor VCC to board 5V
- Sensor GND to board GND
- Sensor TX to board RX
Remember: RX does not connect to RX!
Python Computer Wiring
Since there's dozens of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported.
Here you have two options: An external USB-to-serial converter, or the built-in UART on the Pi's RX pin. Here's an example of wiring up the USB-to-serial converter:
- Sensor VCC to USB 5V
- Sensor GND to USB GND
- Sensor TX to USB RX (white wire)
Remember: RX does not connect to RX!
Here's an example using the Pi's built-in UART:
If you want to use the built-in UART, you'll need to disable the serial console and enable the serial port hardware in raspi-config. See the UART/Serial section of the CircuitPython on Raspberry Pi guide for detailed instructions on how to do this.
To demonstrate the PM2.5 in CircuitPython and Python, let's look at a complete program example.
CircuitPython Microcontroller
With a CircuitPython microcontroller, save this file as code.py on your board. Then comment out the following lines by inserting a '#
' before each one:
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) pm25 = adafruit_pm25.i2c.PM25_I2C(i2c, reset_pin)
And uncomment the following lines by removing the '#
' (hash and space both!) before each one:
# uart = busio.UART(board.TX, board.RX, baudrate=9600) # pm25 = adafruit_pm25.uart.PM25_UART(uart, reset_pin)
Then, open up the serial console to see its output.
When using a USB to serial cable or a Raspberry Pi, comment out the following lines by inserting a '#
' before each one:
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) pm25 = adafruit_pm25.i2c.PM25_I2C(i2c, reset_pin)
For Raspberry Pi, uncomment the following lines by removing the '#
' (hash and space both!) before each one:
# import serial # uart = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=0.25)
For a USB to serial cable, uncomment the following lines by removing the '#
' (hash and space both!) before each one:
# import serial # uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=0.25)
Install the python serial
with library with
pip3 install pyserial
Now you're ready to run the program with the following command:
python3 pm25_simpletest.py
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT """ Example sketch to connect to PM2.5 sensor with either I2C or UART. """ # pylint: disable=unused-import import time import board import busio from digitalio import DigitalInOut, Direction, Pull from adafruit_pm25.i2c import PM25_I2C reset_pin = None # If you have a GPIO, its not a bad idea to connect it to the RESET pin # reset_pin = DigitalInOut(board.G0) # reset_pin.direction = Direction.OUTPUT # reset_pin.value = False # For use with a computer running Windows: # import serial # uart = serial.Serial("COM30", baudrate=9600, timeout=1) # For use with microcontroller board: # (Connect the sensor TX pin to the board/computer RX pin) # uart = busio.UART(board.TX, board.RX, baudrate=9600) # For use with Raspberry Pi/Linux: # import serial # uart = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=0.25) # For use with USB-to-serial cable: # import serial # uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=0.25) # Connect to a PM2.5 sensor over UART # from adafruit_pm25.uart import PM25_UART # pm25 = PM25_UART(uart, reset_pin) # Create library object, use 'slow' 100KHz frequency! i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) # Connect to a PM2.5 sensor over I2C pm25 = PM25_I2C(i2c, reset_pin) print("Found PM2.5 sensor, reading data...") while True: time.sleep(1) try: aqdata = pm25.read() # print(aqdata) except RuntimeError: print("Unable to read from sensor, retrying...") continue print() print("Concentration Units (standard)") print("---------------------------------------") print( "PM 1.0: %d\tPM2.5: %d\tPM10: %d" % (aqdata["pm10 standard"], aqdata["pm25 standard"], aqdata["pm100 standard"]) ) print("Concentration Units (environmental)") print("---------------------------------------") print( "PM 1.0: %d\tPM2.5: %d\tPM10: %d" % (aqdata["pm10 env"], aqdata["pm25 env"], aqdata["pm100 env"]) ) print("---------------------------------------") print("Particles > 0.3um / 0.1L air:", aqdata["particles 03um"]) print("Particles > 0.5um / 0.1L air:", aqdata["particles 05um"]) print("Particles > 1.0um / 0.1L air:", aqdata["particles 10um"]) print("Particles > 2.5um / 0.1L air:", aqdata["particles 25um"]) print("Particles > 5.0um / 0.1L air:", aqdata["particles 50um"]) print("Particles > 10 um / 0.1L air:", aqdata["particles 100um"]) print("---------------------------------------")
You should see output looking something like the following:
That's all there is to using the PM2.5 air quality sensor with CircuitPython!
Page last edited January 21, 2025
Text editor powered by tinymce.