tutorialspinouttools
Sensors · ESP32-C3

PMS5003 on OLED: PM2.5 Air Particulates

Free ESP32 & Arduino tutorial · wiring, code & parts · gokul.builds

Overview & Wiring

What it is: The PMS5003 is a laser particulate sensor that counts fine dust in the air and reports PM1.0, PM2.5 and PM10 in micrograms per cubic metre — the same numbers used in official air-quality indexes. How it works: A small fan pulls air past a laser; scattered light is counted and converted to particle mass. It streams data frames over a 3.3V UART at 9600 baud. You only need to read from it, so the sensor's TX goes to the ESP32's RX. Wiring (UART — note the crossover; uses the 5-pin/G-series cable): PMS5003 TX -> GPIO20 (ESP32 RX) PMS5003 RX -> GPIO21 (ESP32 TX) PMS5003 VCC -> 5V (the fan + laser need 5V) PMS5003 GND -> GND OLED VCC=3V3, GND=GND, SDA=GPIO4, SCL=GPIO5 Libraries: "PMS Library" by Mariusz Kacki (Markusz), plus "Adafruit SSD1306" and "Adafruit GFX Library". On screen / Serial: PM1.0, PM2.5 and PM10 in µg/m³. Light a match nearby (then blow it out) to see PM2.5 spike. Gotchas: Logic is 3.3V so no shifter needed, but it must have 5V power for the fan. Give it ~30 seconds after power-on for the fan to stabilise. The frame reader can miss a packet occasionally; the sketch simply waits for the next one.

Circuit Diagram

PMS5003 on OLED: PM2.5 Air Particulates wiring diagram for ESP32-C3

Parts You Need

ESP32-C3 SuperMiniBuy →
0.96" SSD1306 OLEDBuy →

Source Code (Arduino / ESP32)

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <PMS.h>

Adafruit_SSD1306 display(128, 64, &Wire, -1);

HardwareSerial pmsSerial(1);   // UART1
PMS pms(pmsSerial);
PMS::DATA data;

void setup() {
  Serial.begin(115200);
  Wire.begin(4, 5);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  pmsSerial.begin(9600, SERIAL_8N1, 20, 21);  // RX=GPIO20, TX=GPIO21
}

void loop() {
  if (pms.readUntil(data)) {                  // wait for a full frame
    display.clearDisplay();
    display.setTextColor(SSD1306_WHITE);
    display.setTextSize(1);
    display.setCursor(0, 0);  display.println("PMS5003 ug/m3");
    display.setCursor(0, 18); display.printf("PM1.0: %u", data.PM_AE_UG_1_0);
    display.setCursor(0, 34); display.printf("PM2.5: %u", data.PM_AE_UG_2_5);
    display.setCursor(0, 50); display.printf("PM10 : %u", data.PM_AE_UG_10_0);
    display.display();

    Serial.printf("PM1.0 %u  PM2.5 %u  PM10 %u ug/m3\n",
                  data.PM_AE_UG_1_0, data.PM_AE_UG_2_5, data.PM_AE_UG_10_0);
  }
  delay(1000);
}
Browse all tutorials ESP32-C3 pinout Calculators