SkillAgentSearch skills...

PMserial

Arduino library for PM sensors with serial interface

Install / Use

/learn @avaldebe/PMserial

README

PMSerial

Arduino library for PM sensors with serial interface

PlatformIO CI GitHub issues GitHub license

Sensors

| Plantower | Tested Works | Doesn't Work | Not Tested | Datasheet | Notes | | -------------------- | :----------: | :----------: | :--------: | --------------------------- | -------------------- | | PMS1003 (aka G1) | | | X | en, cn | | PMS3003 (aka G3) | X | | | en, cn | No passive mode read | | PMS5003 (aka G5) | X | | | en, cn | | PMS5003S (aka G5S) | | | X | cn | | PMS5003T (aka G5T) | | | X | | PMS5003ST (aka G5ST) | | | X | | PMS7003 (aka G7) | X | | | cn | | PMSA003 (aka G10) | X | | | cn |

Compatibility

| MCU | Tested Works | Doesn't Work | Not Tested | Examples | Notes | | ------------------ | :----------: | :----------: | :--------: | ----------------------------------------------------- | -------------------------------------- | | ATmega168 @ 8MHz | | | X | SoftwareSerial | | Atmega168 @ 16MHz | | | X | | 5V boards need 3.3V/5V level shifter | | Atmega328 @ 8MHz | X | | | SoftwareSerial | | Atmega328 @ 16MHz | | | X | | 5V boards need 3.3V/5V level shifter | | Atmega32u4 @ 8MHz | | | X | | | Atmega32u4 @ 16MHz | | | X | HardwareSerial | 5V boards need 3.3V/5V level shifter | | Atmega2560 @ 16MHz | X | | | HardwareSerial | 5V boards need 3.3V/5V level shifter | | STM32f103c8 | X | | | HardwareSerial | | STM32f103cb | | | X | HardwareSerial | | ESP8266 | X | | | HardwareSerial SoftwareSerial OLED 64x48 | [needs EspSoftwareSerial@>=6.7.1][GH6] | | ESP32 | X | | | HardwareSerial SoftwareSerial OLED 64x48 | [Serial1 as SoftwareSerial][GH7] |

Usage

PMSx003 sensor type

The PMSx003 sensor type will infer the sensor type from the message header. The sensor type inference does not cover the PMS5003S and PMS5003T variants, see [#10][GH10]. PMS5003S and PMS5003T sensors need to be declared explicitly on the SerialPM constructor.

PMSx003 on HardwareSerial

#include <PMserial.h>
SerialPM pms(PMSx003, Serial);  // PMSx003, UART

void setup() {
  Serial.begin(9600);
  pms.init();                   // config serial port
}

void loop() {
  pms.read();                   // read the PM sensor
  Serial.print(F("PM1.0 "));Serial.print(pms.pm01);Serial.print(F(", "));
  Serial.print(F("PM2.5 "));Serial.print(pms.pm25);Serial.print(F(", "));
  Serial.print(F("PM10 ")) ;Serial.print(pms.pm10);Serial.println(F(" [ug/m3]"));
  delay(10000);                 // wait for 10 seconds
}

Setup for different MCU is covered on the HardwareSerial example.

PMSx003 on SoftwareSerial

#include <PMserial.h>
SerialPM pms(PMSx003, 10, 11);  // PMSx003, RX, TX

void setup() {
  Serial.begin(9600);
  pms.init();                   // config serial port
}

void loop() {
  pms.read();                   // read the PM sensor
  Serial.print(F("PM1.0 "));Serial.print(pms.pm01);Serial.print(F(", "));
  Serial.print(F("PM2.5 "));Serial.print(pms.pm25);Serial.print(F(", "));
  Serial.print(F("PM10 ")) ;Serial.print(pms.pm10);Serial.println(F(" [ug/m3]"));
  delay(10000);                 // wait for 10 seconds
}

Setup for different MCU is covered on the SoftwareSerial example.

ESP32 Serial1

On some ESP32 boards Serial1 default pins are connected to the flash. Using the standard constructor will cause a crash, see espressif/arduino-esp32#148.

// will crash the ESP32
SerialPM pms(PMSx003, Serial1);

Fortunately, it is possible to define alternative for pins by calling:

// define Serial1 pins
Serial1.begin(9600, SERIAL_8N1, <RX>, <TX>);

The PMSerial library uses this feature to implement the flexibility of SoftwareSerial

// define Serial1 pins
SerialPM pms(PMSx003, <RX>, <TX>);

The SoftwareSerial example uses Serial1 on pins 23 (RX) and 19 (TX). The HardwareSerial example uses Serial2.

Advanced usage

Sensor message/protocol

With the exemption of the PMS3003 and PMS5003ST, all supported sensors transmit particulate matter (PM) and number concentrations (NC) measurements in a 32 byte long message. The PMS3003 only transmit PM measurements in a 24 byte message. The PMS5003ST transmit PM, NC, temperature (T), relative humidity (RH) and formaldehyde concentration (HCHO) measurements on a 40 byte message.

On the examples, the PMSx003 sensor type will infer the sensor type from the message header and select the message length and decoding protocol accordingly. The supported protocols are:

| message/protocol | length | PM | NC | T & RH | HCHO | sensors (aliases) | | ----------------- | -------------- | :---: | :---: | :----: | :---: | ------------------------------------------ | | PLANTOWER_AUTO | self discovery | 3 | auto | | | PMSx003 | | PLANTOWER_24B | 24 bytes | 3 | | | | PMS3003 | | PLANTOWER_32B | 32 bytes | 3 | 6 | | | PMS1003, PMS5003, PMS7003, PMSA003 | | PLANTOWER_32B_S | 32 bytes | 3 | 6 | | X | PMS5003S, can not be self discovered | | PLANTOWER_32B_T | 32 bytes | 3 | 4 | X | | PMS5003T, can not be self discovered | | PLANTOWER_40B | 40 bytes | 3 | 6 | X | X | PMS5003ST |

Additional measurements

The pms.read() method will request a new measurement set from the sensor and decode the sensor message. The has_particulate_matter()/has_number_concentration() methods indicate if the message was valid and PM/NC measurements were successfully decoded. Similarly the has_temperature_humidity/has_formaldehyde methods indicate if the message was valid and T & RH/HCHO measurements were successfully decoded, however this kind of additional measurements are only available on PMS5003S, PMS5003T and PMS5003ST sensors.

Decoded measurements

All measurements found in the sensor message will be decoded and stored in following member variables:

| variable | type[len] | measurement | particle diameter | unit | Notes | | -------- | ------------- | ----------- | -------------------- | --------- | --------------------------------- | | pm01 | uint16_t | PM | <= 1.0 µm | µg/m³ | PM1.0, ultra fine particles | | pm25 | uint16_t | PM | <= 2.5 µm | µg/m³ | PM2.5, fine particles | | pm10 | uint16_t | PM | <= 10 µm | µg/m³ | PM10 | | n0p3 | uint16_t | NC | >= 0.3 µm | #/100 cm³ | | n0p5 | uint16_t | NC | >= 0.5 µm | #/100 cm³ | | n1p0 | uint16_t | NC | >= 1.0 µm | #/100 cm³ | | n2p5 | uint16_t | NC | >= 2.5 µm | #/100 cm³

View on GitHub
GitHub Stars58
CategoryDevelopment
Updated4mo ago
Forks23

Languages

C++

Security Score

97/100

Audited on Nov 7, 2025

No findings