Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » Interfacing PMS5003 PM2.5 Air Quality Sensor with Arduino
Arduino Projects

Interfacing PMS5003 PM2.5 Air Quality Sensor with Arduino

Mamtaz AlamBy Mamtaz AlamUpdated:August 22, 202247 Comments6 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
Air Quality Sensor Arduino
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

In this tutorial, we learn how to interface PMS5003 PM2.5 Air Quality Sensor with Arduino. We will make a simple Arduino Code and measure the dust particle concentration in the air with size and quantity for PM1.0, PM2.5, and PM10. PMS5003 is a kind of digital and universal particle concentration sensor, which can be used to obtain the number of suspended particles in the air, i.e. the concentration of particles, and output of them in the form of digital interface.

Check the advanced version of this project here: IoT Based Air Pollution/Quality Monitoring with ESP8266


Overview

PM2.5 and PM10 refer to particulate matter with particle diameter up to 2.5 microns and 10 microns respectively and are among the most dangerous air pollutants. Due to their small size, PM2.5 particles can travel deep into the human lung and cause a variety of health issues; for instance, by triggering asthma attacks or contributing to cardiovascular disease.



High concentrations of dust or PM is a serious health concern. PM2.5 is less than 2.5 microns in diameter, and PM10 is less than 10 microns in diameter. This means a PM10 report includes PM2.5 as well. Both these particles are much smaller than a human hair, which is about 70 microns in width.

PM10: Operations such as stone crushing, coal grinding, rotary kilning in the cement industry, and dust on road stirred by moving vehicles can increase PM10 levels. PM10 limit for 24-hour average is 150µg/m3.

PM2.5: This is a result of fine particles produced from all types of combustion, including motor vehicles, thermal power plants, residential wood burning, forest fires, agricultural burning, and other industrial processes. PM2.5 limit for 24-hour average is 35µg/m3.

So for measuring the Particulate Matter size of PM1.0, PM2.5 & PM10 we are using Plantpower PMS5003 Dust Sensor. You can also use other Plantpower PMS x003 Sensor like PMS1003, PMS3003, PMS5003, PMS6003 & PMS7003.The code given below supports all these models with Arduino.


Bill of Materials

You need to purchase the following components if you want to make this project. All the components can be saily purchased from Amazon.

S.N.Components QuantityPurchase Links
1Arduino UNO Board1Amazon | AliExpress
2PMS5003 PM2.5/PM10 Sensor1Amazon | AliExpress
320x4 LCD Display1Amazon | AliExpress
4Potentiometer 10K1Amazon | AliExpress
5Connecting Wires10Amazon | AliExpress
6Breadboard1Amazon | AliExpress

PMS5003 Air Quality Sensor

Overview

PMS5003

The Plantower PMS5003 is a low-cost laser particle counter, one of a range of sensors by Plantower that also include the PMS1003, PMS3003, and PMS7003. PMS5003 is a kind of digital and universal particle concentration sensor, which can be used to obtain the number of suspended particles in the air, i.e. the concentration of particles, and output them in the form of a digital interface. This sensor can be inserted into variable instruments related to the concentration of suspended particles in the air or other environmental improvement equipment to provide correct concentration data in time.

Working Principle

Laser scattering principle is used for such sensor, i.e. produce scattering by using a laser to radiate suspending particles in the air, then collect scattering light in a certain degree, and finally obtain the curve of scattering light change with time. In the end, equivalent particle diameter and the number of particles with different diameters per unit volume can be calculated by microprocessor-based on MIE theory.

PM2.5 Sensor Working



PM5003 Pins

PMS5003 Pins

Some of the PM2.5 pins are numbered from left to right as 1, 2, 3……8. But in case of PM5003, the pins are named from right to left. Be careful while connecting PM5003 pins as you might connect it reversely.

Pin Function Description Remarks
1 VCC Supply voltage 5V 4.5 – 5.5V
2 GND Ground
3 SET HIGH or SUSPENDED – work mode
LOW – sleep mode
3.3V logic
4 RXD UART/TTL data recieve 3.3V logic
5 TXD UART/TTL data transmit 3.3V logic
6 Reset LOW to reset 3.3V logic
7 NC Not connected
8 NC Not connected


Some of the PMSx003 Sensors comes with connectors like shown below:
PM2.5 Connector

In case if you don’t have the connector with you, then simply you can cut the connector with the scissors and solder the hard wire that can be inserted easily on Arduino Board or breadboard.

PM5003 Connector


Interfacing PMS5003 PM2.5 Air Quality Sensor with Arduino

The interfacing of PMS5003 with Arduino is pretty easy. You just need 4 connections. Connect PIN1 VCC of PMS5003 to Arduino 5V Pin and PIN2 GND to GND of Arduino. The UART Pin, i.e PIN4 Rx & PIN5 Tx is connected to Arduino pin 3 & 4 respectively as shown in the figure below.

Interfacing Air Quality Sensor with Arduino

The Plantower sensors output serial data at 9600 baud that can be read by many computers and can be connected to a PC via a USB adaptor such as this USB 2.0 to TTL UART Serial Converter CP2102.

PMS5003 Arduino


Source Code/Program

The source code for interfacing PM2.5 PMS5003 with Arduino is given below. Simply copy the code and upload to the Arduino UNO Board.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <SoftwareSerial.h>
SoftwareSerial pmsSerial(2, 3);
 
void setup() {
  // our debugging output
  Serial.begin(115200);
 
  // sensor baud rate is 9600
  pmsSerial.begin(9600);
}
 
struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};
 
struct pms5003data data;
    
void loop() {
  if (readPMSdata(&pmsSerial)) {
    // reading data was successful!
    Serial.println();
    Serial.println("---------------------------------------");
    Serial.println("Concentration Units (standard)");
    Serial.print("PM 1.0: "); Serial.print(data.pm10_standard);
    Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_standard);
    Serial.print("\t\tPM 10: "); Serial.println(data.pm100_standard);
    Serial.println("---------------------------------------");
    Serial.println("Concentration Units (environmental)");
    Serial.print("PM 1.0: "); Serial.print(data.pm10_env);
    Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_env);
    Serial.print("\t\tPM 10: "); Serial.println(data.pm100_env);
    Serial.println("---------------------------------------");
    Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(data.particles_03um);
    Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(data.particles_05um);
    Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(data.particles_10um);
    Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(data.particles_25um);
    Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(data.particles_50um);
    Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(data.particles_100um);
    Serial.println("---------------------------------------");
  }
}
 
boolean readPMSdata(Stream *s) {
  if (! s->available()) {
    return false;
  }
  
  // Read a byte at a time until we get to the special '0x42' start-byte
  if (s->peek() != 0x42) {
    s->read();
    return false;
  }
 
  // Now read all 32 bytes
  if (s->available() < 32) {
    return false;
  }
    
  uint8_t buffer[32];    
  uint16_t sum = 0;
  s->readBytes(buffer, 32);
 
  // get checksum ready
  for (uint8_t i=0; i<30; i++) {
    sum += buffer[i];
  }
 
  /* debugging
  for (uint8_t i=2; i<32; i++) {
    Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
  }
  Serial.println();
  */
  
  // The data comes in endian'd, this solves it so it works on all platforms
  uint16_t buffer_u16[15];
  for (uint8_t i=0; i<15; i++) {
    buffer_u16[i] = buffer[2 + i*2 + 1];
    buffer_u16[i] += (buffer[2 + i*2] << 8);
  }
 
  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);
 
  if (sum != data.checksum) {
    Serial.println("Checksum failure");
    return false;
  }
  // success!
  return true;
}

Once the code is uploaded, you can open the serial monitor and set the baud rate to 9600. You will see the sensor start collecting the data. The sensor will start giving the correct value after 30 Seconds as it requires to some times to get warm.




Interfacing PMS5003 PM2.5 Air Quality Sensor with Arduino & LCD Dsiplay

Interfacing PMS5003 PM2.5 Air Quality Sensor with Arduino & LCD Dsiplay

The interfacing of PMS5003 with Arduino and LCD Display is pretty easy. You just need 4 connections. Connect PIN1 VCC of PMS5003 to Arduino 5V Pin and PIN2 GND to GND of Arduino. The UART Pin, i.e PIN4 Rx & PIN5 Tx is connected to Arduino pin 3 & 4 respectively as shown in the figure below. For 20×4 LCD Display, connect pin 1, 3, 16 to GND & 2, 15 to VCC 5V. Connect pin 4, 6, 11, 12, 13, 14 of LCD to Arduino 13, 12, 11, 10, 9, 8 Pin. Connect 10K potentiometer at pin 3 of LCD to adjust the contrast.

PM2.5 Air Quality Sensor Arduino




Source Code/Program

The source code for interfacing PM2.5 PMS5003 Air Quality Sensor with Arduino and LCD Display is given below. Simply copy the code and upload to the Arduino UNO Board.

But before that you need to add the library for PMS5003 Sensor. So simply install the following library from the library manager.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "PMS.h"
#include "SoftwareSerial.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
 
SoftwareSerial Serial1(2, 3); // RX, TX
 
PMS pms(Serial1);
PMS::DATA data;
 
void setup()
{
  Serial1.begin(9600);
  lcd.begin(20,4);
  lcd.setCursor(0, 0);
  lcd.print("Warming up");
  delay(4000);
  lcd.clear();
}
 
void loop()
{
  if (pms.read(data))
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Dust Concentration");
    lcd.setCursor(0, 1);
    lcd.print("PM1.0 :" + String(data.PM_AE_UG_1_0) + "(ug/m3)");
    lcd.setCursor(0, 2);
    lcd.print("PM2.5 :" + String(data.PM_AE_UG_2_5) + "(ug/m3)");
    lcd.setCursor(0, 3);
    lcd.print("PM10  :" + String(data.PM_AE_UG_10_0) + "(ug/m3)");
    
    delay(1000);
  }
}


Video Tutorial & Explanation

PM2.5 Air Quality/Dust Sensor & Arduino Interfacing tutorial with PMS5003
Watch this video on YouTube.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleESP8266 & BME280 Based Mini Weather Station
Next Article RTC Based Automatic Street Light Using Arduino & LDR

Related Posts

DC Energy Meter using Arduino

Build a DC Energy Meter using Arduino – 32V/5A

Updated:August 26, 20252K
Interfacing ADXL375 Accelerometer with Arduino

Interfacing ADXL375 Accelerometer with Arduino (±200g)

Updated:June 28, 2025
PZEM-004T Arduino Energy Meter

DIY AC Energy Meter using PZEM-004T & Arduino

Updated:March 6, 20258K
Interfacing BMI160 Accelerometer & Gyroscope with Arduino

Interfacing BMI160 Accelerometer & Gyroscope with Arduino

Updated:February 2, 20259K
Password Based Door Lock Security System Using Arduino & Keypad

Password Based Door Lock Security System Using Arduino & Keypad

Updated:February 2, 20252436K
Earthquake Detector Alarm with with Accelerometer & Arduino

Earthquake Detector Alarm with Accelerometer & Arduino

Updated:February 2, 2025661K
View 47 Comments

47 Comments

  1. Leo on January 3, 2020 11:49 PM

    Hello,
    I’m trying to use this tutorial with a similar sensor ( YEETC CP-15-A4-CG ) and I2C-LCD screen. The problem is that the values are always down to 0, do you know if there is any other similar tutorial for my specific sensor. I’ve tried looking for it on the internet but didn’t found it …
    I can send you the computer code, the components, and how i connect the components if you think you will be able to directly help me.

    Yours sincerely

    Reply
    • Alex on January 3, 2020 11:50 PM

      Make sure your sensor is getting 5V power supply. The sensor requires high current too.
      I suggest you to check once by giving 5V supply from external adapter.

      Reply
  2. Andrew Clark on January 18, 2020 9:07 PM

    Hi Alex, tried this with newer PMS7003 sensor and getting strange results, most are 10X over values from PM5003. I have adjusted pins to match 5003 and software is the same. Do you have any experience with the 7003? Thanks!

    Reply
    • Alex on January 18, 2020 9:08 PM

      Send me 1 sample of pms7003 to india if you have multiple sensor. I will do the coding and let you know.

      Reply
  3. keeratiburt on February 12, 2020 8:41 AM

    Can you tell me what are the differences between standard and environment values

    and what does “Particles > 2.5um / 0.1L air: xx” mean?

    thank you

    Reply
  4. Len on February 25, 2020 8:01 PM

    Hi,

    When I run this code by itself, it works fine. However, when I combine this code with other sensors and breakout boards (e.g. BME280, SD card etc.) I have a checksum failure approx. every 5 seconds. Please could you suggest any problems with this?

    Many thanks.

    Reply
    • Mr. Alam on February 25, 2020 8:03 PM

      Please remove the delay if you are using any delay function in the code. I was having the same issue.

      Reply
  5. Richard on February 28, 2020 4:16 AM

    How can we check if the sensor is connected? If not I would like to print message on LCD.

    Reply
  6. Jonathan Sritharan on March 24, 2020 7:56 PM

    For the concentration values, it states that they are standard and environmental. Is there a specific unit for the concentration values? Thanks.

    Reply
    • Mr. Alam on March 24, 2020 8:02 PM

      micro gram per centimeter cube. You are measuring the PM concentration per unit volume.

      Reply
  7. kami on April 8, 2020 1:28 AM

    i have the same problem, ill add external 5v and values on my arduino leonardo are zeros :/

    Reply
  8. Robbe on April 10, 2020 8:54 PM

    I get a checksum error, any suggestions?

    Reply
  9. Mr. Lowe on April 17, 2020 9:22 PM

    Can anyone provide a more in-depth explanation of connecting and interfacing the LCD + Breadboard + Arduino. It is very hard to follow the provided picture and the video glances over that part of the process.

    Thank you in advance.

    Reply
  10. Kchal km on May 7, 2020 5:28 PM

    I have a problem with the code. It can’t run.
    “‘data’ was not declared in this scope”

    Reply
  11. Vineeth Ravulapalli on July 9, 2020 1:03 AM

    Hello,
    Thank you for the project; actually, I am new to arduino, so I don’t understand most of the part related to “Checksum”. But, I was able to use your code and acquire data from the Plantower sensor.
    But, I would like to also connect another PM sensor: Shinyei PD42NS along with the Plantower, to my Arduino. When I am trying to do this I am not able to acquire data from Plantower. Can you kindly help me with this.
    Thanks
    Vineeth R

    Reply
  12. Santosh Pattapu on August 29, 2020 7:59 PM

    Hey bro,
    Your project looks very good. I have gone through it and I didn’t understand how you converted the number of suspended particles to weight. Can you please explain that. Did you multiply it with density considering all the particles are in spherical shape.?

    thanks in advance bro.

    Reply
  13. artem on September 17, 2020 3:18 AM

    hello , pleaze!!I im noob, and don’t understand this at all, can you tell me how to make 1 relay turn on when 70-100 ppm particles are detected, and the second relay turns on at 100-150 ppm?

    Reply
  14. Pieter on September 19, 2020 4:11 PM

    Hi,
    Your code works very nice with an Arduino Uno or Nano. But on a Mega it doesn’t work. Do you have a solution for the Mega? Thanks for your time

    Reply
  15. Nema on September 22, 2020 12:22 PM

    When I open the serial monitor, all I see is a bunch of random looking symbols. They look like this:

    K⸮⸮X[-⸮dT[⸮⸮⸮⸮⸮l⸮⸮ڣ⸮(|⸮⸮XG⸮Λ⸮,⸮⸮⸮=df4VhD@T⸮⸮⸮K⸮l⸮⸮(ۛ⸮4>⸮Q⸮A⸮⸮k⸮⸮\’
    7⸮p⸮ۛ⸮Kٛi⸮A ⸮ۛX5=I(⸮K⸮K⸮⸮⸮ ⸮[F⸮⸮⸮⸮,⸮⸮l[-⸮dT[⸮⸮⸮⸮⸮l⸮⸮ڣ⸮(|⸮⸮XG⸮Λ⸮,⸮⸮⸮=df4VhD@T⸮⸮⸮K⸮l⸮⸮(ۛ⸮4>⸮Q⸮A⸮⸮k
    ⸮⸮\’
    7⸮p⸮ۛ⸮Kٛi⸮A ⸮ۛX5=I(⸮K⸮K⸮⸮⸮ ⸮[F⸮⸮⸮⸮,⸮⸮llқڣel⸮⸮X⸮Cl⸮⸮T⸮dZ;
    ⸮!ЂDD⸮ٛ⸮K⸮⸮\ ؛⸮⸮⸮=P(⸮K⸮K⸮⸮⸮ ⸮[F⸮⸮⸮⸮⸮,⸮⸮l⸮K⸮⸮⸮H⸮⸮⸮l⸮.IZ⸮⸮k*ɂ\”⸮⸮⸮Z⸮p⸮ۛ⸮⸮⸮l5⸮J)⸮ٛH8Z⸮⸮)⸮ۛ4⸮⸮fb!⸮d⸮⸮!@Lۛ⸮l⸮⸮$⸮”X

    Can you help me? What is happing?

    Reply
    • Mr. Alam on September 23, 2020 12:01 PM

      Check the baud rate.

      Reply
  16. benutzer8 on October 11, 2020 2:00 PM

    it also works on Mega but on different PINs. Have a closer look on SoftwareSerial-Library. I’m using A10 and A11, and it works fine for me.

    Reply
  17. benutzer8 on October 11, 2020 2:08 PM

    I guess the difference between standard and environment is that standard is a normed value like ICAO standard atmosphere (15°C, 1013,25 hPa, …) Standard value is interesting because you can compare two or more values on different places.

    Reply
  18. Antonio on October 12, 2020 3:36 AM

    Any clue on why arduino is not getting any data from the sensor? I can hear the sensor running, but it doesn’t communicate any data to the arduino

    Reply
  19. Greg on October 15, 2020 11:41 PM

    Is there any way to save the data in a csv instead of just printing it?

    Reply
  20. JoséPablo Canal on March 10, 2021 9:01 AM

    Hello Allam,
    Thank you very much for this project, I am trying to build a multi sensor air quality meter, I used your example and now it is desplaying only 0, Other sensors SCD30 and BMP80 are working correctly
    Im a a newbie on Arduiino so your help is much appreciated, here is my code:

    // SCD30 + bmp280 + pms
    #include <Adafruit_SCD30.h>
    #include <SoftwareSerial.h>
    SoftwareSerial pmsSerial(2,3);
    Adafruit_SCD30 scd30;
    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_BMP280.h>
    #define BMP_SCK (13)
    #define BMP_MISO (12)
    #define BMP_MOSI (11)
    #define BMP_CS (10;)
    Adafruit_BMP280 bmp;// I2C

    void setup(void) {
    Serial.begin(115200);
    while (!Serial) delay(10);
    Serial.println(“Adafruit SCD30, BMP280 Y pms”);
    // Try to initialize!
    if (!bmp.begin()) {
    Serial.println(F(“Could not find a valid BMP280 sensor, check wiring!”));
    while (1);
    }
    if (!scd30.begin()) {
    Serial.println(“Failed to find SCD30 chip”);
    while (1) {
    delay(10);
    }
    if (!scd30.startContinuousMeasurement()) {
    Serial.println(“Failed to set ambient pressure offset”);
    while (1) {
    delay(10);
    }
    }
    Serial.print(“Ambient pressure offset: “);
    Serial.print(scd30.getAmbientPressureOffset());
    Serial.println(” mBar”);
    }
    Serial.println(“SCD30 Found!”);

    // if (!scd30.setMeasurementInterval(10)){
    // Serial.println(“Failed to set measurement interval”);
    // while(1){ delay(10);}
    // }
    Serial.print(“Measurement Interval: “);
    Serial.print(scd30.getMeasurementInterval());
    Serial.println(” seconds”);
    };
    struct pms5003data {
    uint16_t framelen;
    uint16_t pm10_standard, pm25_standard, pm100_standard;
    uint16_t pm10_env, pm25_env, pm100_env;
    uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
    uint16_t unused;
    uint16_t checksum;
    };

    struct pms5003data data;

    void loop() {
    if (scd30.dataReady()) {
    Serial.println(“Data available!”);
    scd30.startContinuousMeasurement(bmp.readPressure()/100);

    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <code>if (!scd30.read()) {
      Serial.println("Error reading sensor data");
      return;
    }
    Serial.println("---------------------------------------");
    Serial.print("SCD30Temperature: ");
    Serial.print(scd30.temperature);
    Serial.println(" degrees C");
    Serial.print(F("BMP280Temperature = "));
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    Serial.print("Relative Humidity: ");
    Serial.print(scd30.relative_humidity);
    Serial.println(" %");
    Serial.print(F("Pressure = "));
    Serial.print(bmp.readPressure() / 100);
    Serial.println(" mBar");
    Serial.print("CO2: ");
    Serial.print(scd30.CO2, 3);
    Serial.println(" ppm");
    Serial.print(F("Approx altitude = "));
    Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
    Serial.println(" m");
    Serial.print(scd30.getAmbientPressureOffset());
    Serial.println(" mBar");
    Serial.println("Concentration Units (standard)");
    Serial.print("PM 1.0: ");
    Serial.print(data.pm10_standard);
    Serial.print("\t\tPM 2.5: ");
    Serial.print(data.pm25_standard);
    Serial.print("\t\tPM 10: ");
    Serial.println(data.pm100_standard);
    Serial.println("Concentration Units (environmental)");
    Serial.print("PM 1.0: ");
    Serial.print(data.pm10_env);
    Serial.print("\t\tPM 2.5: ");
    Serial.print(data.pm25_env);
    Serial.print("\t\tPM 10: ");
    Serial.println(data.pm100_env);
    Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(data.particles_03um);
    Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(data.particles_05um);
    Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(data.particles_10um);
    Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(data.particles_25um);
    Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(data.particles_50um);
    Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(data.particles_100um);
    Serial.println("---------------------------------------");
    </code>

    }
    }

    boolean readPMSdata(Stream *s) {
    if (! s->available()) {
    return false;
    }

    // Read a byte at a time until we get to the special ‘0x42’ start-byte
    if (s->peek() != 0x42) {
    s->read();
    return false;
    }

    // Now read all 32 bytes
    if (s->available() < 32) {
    return false;
    }

    uint8_t buffer[32];
    uint16_t sum = 0;
    s->readBytes(buffer, 32);

    // get checksum ready
    for (uint8_t i=0; i<30; i++) {
    sum += buffer[i];
    }

    /* debugging
    for (uint8_t i=2; i<32; i++) {
    Serial.print(“0x”); Serial.print(buffer[i], HEX); Serial.print(“, “);
    }
    Serial.println();
    */

    // The data comes in endian’d, this solves it so it works on all platforms
    uint16_t buffer_u16[15];
    for (uint8_t i=0; i<15; i++) {
    buffer_u16[i] = buffer[2 + i2 + 1];
    buffer_u16[i] += (buffer[2 + i
    2] << 8);
    }

    // put it into a nice struct 🙂
    memcpy((void *)&data, (void *)buffer_u16, 30);

    if (sum != data.checksum) {
    Serial.println(“Checksum failure”);
    return false;
    }
    // success!
    return true;
    delay(2000);
    };/*

    */

    Heres is what the monitor is showing:
    21:29:07.706 -> Data available!
    21:29:07.706 -> —————————————
    21:29:07.706 -> SCD30Temperature: 25.69 degrees C
    21:29:07.706 -> BMP280Temperature = 24.28 *C
    21:29:07.706 -> Relative Humidity: 29.17 %
    21:29:07.706 -> Pressure = 782.88 mBar
    21:29:07.706 -> CO2: 1237.405 ppm
    21:29:07.706 -> Approx altitude = 2123.39 m
    21:29:07.706 -> 782 mBar
    21:29:07.706 -> Concentration Units (standard)
    21:29:07.706 -> PM 1.0: 0 PM 2.5: 0 PM 10: 0
    21:29:07.706 -> Concentration Units (environmental)
    21:29:07.706 -> PM 1.0: 0 PM 2.5: 0 PM 10: 0
    21:29:07.706 -> Particles > 0.3um / 0.1L air:0
    21:29:07.706 -> Particles > 0.5um / 0.1L air:0
    21:29:07.753 -> Particles > 1.0um / 0.1L air:0
    21:29:07.753 -> Particles > 2.5um / 0.1L air:0
    21:29:07.753 -> Particles > 5.0um / 0.1L air:0
    21:29:07.753 -> Particles > 10.0 um / 0.1L air:0
    21:29:07.753 -> —————————————

    Reply
  21. Hugo on March 31, 2021 6:28 PM

    I had the same problem. You have to put 115200 baud like in the screenshot and NOT 9600.

    Reply
    • Fiona on July 12, 2021 4:22 PM

      Hi. Did you just change it in the code here?

      #include <SoftwareSerial.h>
      SoftwareSerial pmsSerial(2, 3);

      void setup() {
      // our debugging output
      Serial.begin(115200);

      // sensor baud rate is 9600
      pmsSerial.begin(9600);
      }

      Reply
  22. Faisal Saleem on April 23, 2021 8:39 PM

    Sir I am trying the same code using same sensor and same pin connection but i couldn’t seen any value or any thing on screen I also change bode plot rate but couldn’t get any value

    Reply
  23. Faisal Saleem on April 23, 2021 8:44 PM

    Sir i used A10 A11 but couldn’t seen any value for Arduino mega also use digital but same problem what i could do

    Reply
    • Alex Newton on April 23, 2021 8:46 PM

      Not all the pins of Arduino mega can be used as software serial. You can only use those pins which accepts interrupt. Check the Arduino Mega documentation to find out which pin supports Software Serial command.

      Reply
  24. Michele Faverio on May 16, 2021 11:14 PM

    could someone send me the code with the i2c please

    Reply
  25. dave on October 9, 2021 9:25 PM

    Thanks for the tutorial. super simple and easy to follow.

    I use the EXP8266 and like many others, got nothing……
    what I ASSUMED is to use TX/DX of the microcontroller and not regular digital output pins.
    then, I got that X[-⸮dT[⸮⸮⸮⸮⸮l⸮⸮ڣ⸮(|⸮ nonsense……
    changed the baud rate on the terminal to 112500, and it worked perfectly !

    as a note, II am using the 5v output of the ESP8266, but I do not know if that has enough power to do that safely.

    I changed to : SoftwareSerial pmsSerial(D5, D6);

    Thank you again for the great tutorial

    Reply
  26. dave on October 10, 2021 2:15 AM

    I was successful in following this tutorial. thanks, it was very well done and easy to follow.

    I do have a couple of questions.
    there are three sections in the serial display

    data.pm10_standard
    and
    data.pm10_en
    and
    data.particles_10um

    each outputs a different value. I don’t understand the differences and why they are all different.

    Reply
  27. Suraj Kumar on December 13, 2021 11:58 PM

    hi ,this S K from west bengal
    sir i am using this code form my project on my PMSA003-C Plantower Sensor it showing nothing please help me

    Reply
  28. Suraj Kumar on December 14, 2021 1:33 AM

    hi ,this S K from west bengal
    sir i am using this code form my project on my PMSA003-C Plantower Sensor it showing nothing please help me

    Reply
  29. Daniel Francisco Maala on January 4, 2022 4:45 AM

    Hi Mr: Alam how can i find the libaries for your codes?

    Reply
  30. N.Laribi on March 11, 2022 7:23 PM

    Could you share your code, please it doesn’t work for me!!

    Reply
  31. N.Laribi on March 11, 2022 7:31 PM

    Did you find the solution of this problem . If yes could you share with me your code (I have the same problem) ?

    Reply
  32. Vasilis Makris on August 27, 2022 5:12 AM

    did you find out whats the difference?

    Reply
  33. Mateusz on February 2, 2024 1:07 PM

    Thank you, your code help me a lot. It was hard to understand it from datasheet in clear way.

    Reply
  34. Ed on February 10, 2024 5:55 AM

    You state “Once the code is uploaded, you can open the serial monitor and set the baud rate to 9600”, but i think that is wrong. The connection to the sensor is 9600 baud but the connection to the serial monitor is 115200 baud.
    Also, is there any specific reason why in one program you use a pms library and in the other you dont

    Reply
  35. Jerson Luis on March 2, 2024 9:02 AM

    Buenas
    Quisiera saber si quiero guardar la información en un Micro SD con un modulo Micro SD, así como la hora con un Modulo de hora en la cual fue tomada los datos, cual seria el código que colocaría
    Gracias de antemano
    Bendiciones

    Reply
  36. david steel on April 1, 2024 3:47 PM

    Doesnt work. checked & double checked everything. PMS5003 is putting out data, as checked with a scope. The program is just not displaying any readings.

    Reply
    • David Steel on April 2, 2024 6:34 PM

      Suddenly started working now 🙂

      Reply
  37. LP on October 17, 2024 6:08 PM

    Hello, thanks for this code.
    When I copy pasted this and try to compile, I get this:
    “Downloading index: package_index_tar.bz2”
    What is this?
    – thank you!

    Reply
  38. LP on October 17, 2024 6:11 PM

    (scratch last comment – cancelled the process and started again – compiled and upload)

    Reply
  39. LP on October 17, 2024 6:18 PM

    For a very quick instant, I saw some data, but went to gibberish.
    set to 9600 baud

    Before I even got anything close to being legible, it was all gibbered before I commented out this setup() line:

    // our debugging output
    Serial.begin(115200);

    What can be happening?

    Here’s what I saw…

    18:12:43.314 ->
    18:12:43.314 -> ———————————-icles > 10.0 um / 0.1L air:0
    18:12:43.314 -> —————————————
    18:12:43.314 -> 2.5um / 0.1L air:0
    18:12:43.314 -> Particles > 5.0um / 0.1L air:0
    18:12:43.314 -> Particles > 10.0 um / 0.1L air:0
    18:12:43.314 -> —————————————
    18:12:45.301 -> 6�_,� �ʛ�9�� ؛�d8L; 0���x�54����ɒK�L�I���̛6��lI�!Ђ3� 3�HFY�l�
    18:12:54.840 -> �DP�ћl�Kٛ�,�

    …and now I see nothing…

    Reply

CommentsCancel reply

Latest Posts
ESP32 Fingerprint Attendance System with Live Web Dashboard

ESP32 Fingerprint Attendance System with Live Web Dashboard

June 21, 2026
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

June 14, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
Top Posts & Pages
  • ESP32 Fingerprint Attendance System with Live Web Dashboard
    ESP32 Fingerprint Attendance System with Live Web Dashboard
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • How to use Modbus RTU with ESP32 to read Sensor Data
    How to use Modbus RTU with ESP32 to read Sensor Data
  • ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
    ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
  • How to use INA226 DC Current Sensor with Arduino
    How to use INA226 DC Current Sensor with Arduino
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • MAX30102 & Arduino: Heart Rate + Blood Oxygen Monitoring
    MAX30102 & Arduino: Heart Rate + Blood Oxygen Monitoring
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (205)
    • ESP32 MicroPython (7)
    • ESP32 Projects (82)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.