กลับหน้าหลัก
views
Using Arduino with PMS5003 G5 Sensor to Measure PM2.5 and Display on OLED
Last updated on

Using Arduino with PMS5003 G5 Sensor to Measure PM2.5 and Display on OLED


Using Arduino with PMS5003 G5 Sensor to Measure PM2.5 and Display on OLED

Air quality monitoring has become increasingly relevant, and building your own PM2.5 sensor with an Arduino is a practical project for anyone interested in IoT. This guide walks through wiring the PMS5003 G5 laser dust sensor to an Arduino UNO and displaying real-time particulate matter readings on a 0.96-inch OLED screen.

Complete breadboard wiring diagram showing Arduino UNO connected to PMS5003 sensor and OLED display with all jumper wires labeled

Required Components

  • Arduino UNO R3 with USB cable
  • PMS5003 G5 laser dust sensor module
  • 0.96-inch OLED 128×64 I2C display
  • MB-102 breadboard (830 points)
  • Jumper wires: male-to-male, male-to-female, female-to-female
  • 9V 2A power adapter (recommended — USB power alone may not sustain the sensor fan)

Wiring Diagram

Arduino UNO to PMS5003 Sensor

Arduino UNOPMS5003 G5
5VVCC
GNDGND
Pin 2 (SoftwareSerial RX)TX
Pin 3 (SoftwareSerial TX)RX

Arduino UNO to OLED Display (I2C)

Arduino UNOOLED 128×64
5VVCC
GNDGND
A4 (SDA)SDA
A5 (SCL)SCL

Critical note: All GND connections from the Arduino, PMS5003 sensor, and OLED display must be tied together at a common ground point (Arduino GND pin). Without a shared ground, serial communication between devices fails silently.

PMS5003 G5 pinout diagram with clearly labeled TX, RX, VCC, and GND pins on the sensor module
OLED 128x64 I2C pinout showing SDA and SCL positions on the display module

Installing Required Libraries

Open Arduino IDE and go to Sketch → Include Library → Manage Libraries. Install the following:

  1. OLED display libraries — Search and install Adafruit SSD1306 and Adafruit GFX Library from Adafruit (both are required)
  2. PMS5003 communication library — Search for PMS in the library manager and install a library that supports PMS5003 sensors

If installing from a downloaded RAR/ZIP file, extract it and move the folder to Documents/Arduino/libraries/

Arduino Code for Reading PM2.5 and Displaying on OLED

This code uses SoftwareSerial on pins 2–3 to avoid conflicting with the hardware Serial that connects to USB for uploading and Serial Monitor output. The code reads the PMS5003 data packet, extracts PM2.5 concentration, calculates AQI, and drives the OLED display.

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// ===== PMS5003 communication using SoftwareSerial =====
#define PMS_PIN_RX 2   // Receive data from sensor
#define PMS_PIN_TX 3   // Transmit to sensor (optional for PMS5003)
SoftwareSerial pmsSerial(PMS_PIN_RX, PMS_PIN_TX);

// ===== OLED display configuration =====
#define OLED_SCREEN_WIDTH 128
#define OLED_SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_I2C_ADDRESS 0x3C
Adafruit_SSD1306 display(OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT, &Wire, OLED_RESET);

// ===== EPA-style AQI calculation from PM2.5 (ug/m3) =====
float pm25ToAQI(float pm25) {
  float aqi;
  if (pm25 <= 12.0) {
    aqi = map(pm25 * 100, 0, 1200, 0, 50);
  } else if (pm25 <= 35.4) {
    aqi = map(pm25 * 100, 1201, 3540, 51, 100);
  } else if (pm25 <= 55.4) {
    aqi = map(pm25 * 100, 3541, 5540, 101, 150);
  } else if (pm25 <= 150.4) {
    aqi = map(pm25 * 100, 5541, 15040, 151, 200);
  } else if (pm25 <= 250.4) {
    aqi = map(pm25 * 100, 15041, 25040, 201, 300);
  } else if (pm25 <= 500.4) {
    aqi = map(pm25 * 100, 25041, 50040, 301, 500);
  } else {
    aqi = 500;
  }
  return aqi;
}

// NOTE: For Arduino MEGA or Leonardo with extra hardware Serial ports,
// replace SoftwareSerial with Serial2 or Serial1 for cleaner operation

void setup() {
  Serial.begin(9600);        // Serial Monitor output
  pmsSerial.begin(9600);    // PMS5003 communication

  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
    Serial.println(F("OLED allocation failed"));
    while (true) { delay(1000); }
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.display();
  delay(500);
}

void loop() {
  // Wait for data packet from PMS5003
  if (pmsSerial.available()) {
    if (pmsSerial.read() == 0x42) {           // First byte of PMS5003 frame
      if (pmsSerial.read() == 0x4D) {         // Second byte of PMS5003 frame
        unsigned char pmsData[30];
        pmsData[0] = 0x42;
        pmsData[1] = 0x4D;
        for (int i = 2; i < 30; i++) {
          pmsData[i] = pmsSerial.read();       // Read remaining 28 bytes
        }

        // PM2.5 atmospheric concentration in ug/m3 (bytes 12-13 of data packet)
        unsigned int pm25 = (pmsData[12] << 8) | pmsData[13];
        float aqi = pm25ToAQI(pm25);

        // ===== Output to Serial Monitor =====
        Serial.print("PM2.5 = ");
        Serial.print(pm25);
        Serial.print(F(" ug/m3  |  AQI = "));
        Serial.println(aqi);

        // ===== Output to OLED display =====
        display.clearDisplay();
        display.setTextSize(2);
        display.setCursor(10, 10);
        display.print("PM2.5");
        display.setTextSize(3);
        display.setCursor(10, 32);
        display.print(pm25);
        display.setTextSize(1);
        display.setCursor(10, 56);
        display.print("ug/m3");
        display.display();
      }
    }
  }
}

Adjustments for different boards:

  • Arduino Nano (ATmega328P): Works with this code as-is. Select “Arduino Nano” under Tools → Board during upload. Pin 13 LED still works for basic blinking tests.
  • Arduino MEGA: Replace SoftwareSerial with Serial2 (pins 17/18) or Serial3 (pins 15/14). Change pmsSerial.begin(9600) to Serial2.begin(9600) and use Serial2.read() instead of pmsSerial.read(). This frees up pins 2–3 for other uses.
  • Arduino Leonardo / Pro Micro: Uses ATmega32U4 which has a native USB Serial (Serial) separate from the main UART (Serial1). You can use Serial1 for PMS5003 without SoftwareSerial.
  • ESP32: Supports multiple hardware UARTs on any GPIO pins via HardwareSerial. Define HardwareSerial PMS(1); and assign any two free pins. Remember ESP32 is 3.3V logic — use a logic level shifter or verify your OLED and sensor support 3.3V input.

Upload and Test Procedure

  1. Double-check all wiring against the diagram above. Confirm all three GND pins are connected together.
  2. Connect the 9V 2A adapter to power the Arduino board — do not rely on USB power alone for the sensor fan.
  3. Open Arduino IDE and paste the code from above.
  4. Go to Tools → Port and select the COM port where your board is connected.
  5. Go to Tools → Board and select your board type.
  6. Click Sketch → Upload and wait for the “Done uploading” message.
  7. Open Serial Monitor via Tools → Serial Monitor and set the baud rate to 9600.
  8. If everything is correct, you will see PM2.5 concentration values printed in the Serial Monitor and updated on the OLED screen simultaneously.

Practical Test: Generate PM2.5 with a Soldering Iron

A simple way to verify the sensor works is to hold a soldering iron near the PMS5003 air intake inlet. The smoke produced contains fine particulate matter, and you should see the PM2.5 value spike on both the OLED and Serial Monitor within seconds. This test confirms both the wiring and software are functioning correctly.

อยากทำโปรเจคแบบนี้?

รับทำโปรเจค Arduino / IoT จบงานไว ส่งงานครบ พร้อมสอน

If you need Arduino project service or urgent IoT development, see full service details on the services page

จ้างทำโปรเจคเลย

Project estimate

Want something like this? Open the estimate page.

The long form is now on a separate estimate page, so this article stays clean.

ความคิดเห็น

รีวิวจากคนใช้งานจริง

รีวิวจากลูกค้าและคนที่เคยใช้งาน

ถ้าเคยสั่งงาน เคยอ่านหน้านี้แล้วได้ประโยชน์ หรือมีข้อเสนอแนะ ฝากรีวิวไว้ได้เลย

กำลังโหลดรีวิว...