ESP32 Particulate Matter Monitoring

By Somnath Bera. He is an electronic hobbyist and enthusiast since 2005.


Particulate matter

Dust is a silent killer. Ever since the smog pollution of Delhi has hit the headlines, the public awareness about these two particulate matters have become a bone of contention. PM2.5 is particulate matters which is less than 2.5 micron in diameter and PM10 is particulate matters which is less than 10 micron in diameter. That means a PM10 report includes PM2.5 as well. Both these particles are way smaller than a human hair which is about 70 microns in width.

What causes PM10

Crushing and grinding operations like stone crushers, coal grinders, rotary kiln in cement industry, dusts on the roads stirred by moving vehicles. These particles are about 30 times smaller than the width of a human hair and is small enough to get inhaled past our defensive nose hairs and settles into our lungs. Limit of PM10 for 24 hour average is 150 µg/m3

What causes PM2.5

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. While a PM10 ends at our lungs, PM2.5 passes further through alveoli of our lungs and gets mixed into our blood cells and be carried throughout our bodies thereby making them “the invisible killer”. Limit of PM2.5 for 24 hour average is 35 µg/m3.

The common diseases that are caused by these two particulate matters are – Asthma, Influenza, lung-heart-cardiovascular diseases and premature death.

Although there a few air monitoring systems using Nova done in the previous years like the one published in 2016 on a Air Quality Monitoring System which is a stand alone display unit based on Arduino using DHT11, SDS011, MQ135 and DS1307 (RTC) units. This is not an IOT in true sense as it is not connected to any network.

But this new improved version is an IOT project using powerful and latest ESP32 board using SDS011, colorful TFT display and more precise BME280 with correction factor for PM measurements. The major plus point of it is to connect to a cloud [] using WiFi and it uploads data o the cloud in regular interval. In the cloud one can do MATLAB analysis for further deep study of data. The time is automatically stamped by the cloud. Code is simple and smaller on side.

Measurement of PM2.5 & PM10

Since both these particulates are invisible in nature, there measurements are not easy. Big Industries at their factory entrances put up display of many pollutants including these two particulate matters. But as the industries themselves are the big polluter of these particulate matters, most of these readings are tampered. So to have a clear idea of these two parameters, it’s better to develop your own measurement system using cheap yet efficient electronics.

Nova Dust sensor – SDS011

With it’s size, it’s the best and the finest particulate sensor in terms of accuracy & price ($20 , It has an UART interface and has a measurement resolution of 0.3μg/m3. Operating voltage is 5V.

RH Correction of PM2.5 & PM10

The PM2.5 & PM10 has a relation with Relative Humidity. Therefore, an RH correction has been placed in the sketch as well to fine tune the readings. For Temperature, pressure and relative humidity we have added a cheap BME280 on I2C bus of ESP32.

SDS011 on ESP8266 & ESP32

Arduino being an advanced technology as on date, almost for anything and everything there is always a library available for any kind of sensors. So for SDS011 too a ready made library is available which uses SoftwareSerial library and works out of the box for UNO and ESP8266 as both these hardwares can use SoftwareSerial library. However, in ESP8266 I could not make it work along with a colored display ILI9361 (128×128).

But my preferred hardware is ESP32 and it doesn’t work with SoftwareSerial. It has three UART ports and it uses HardwareSerial for connecting the UART devices. To tackle the problem I studied the existing library and the same command is imitated with the hardwareserial and the PM data started coming from the sensor. These commands are placed in processdata.h file which is to be kept in the same folder of the Arduino sketch and to be compiled together with the main sketch.

Sleep mode of SDS011

As per specification the SDS011 has a sleep current of 2mA. I tried with the sleep commands as stated all over Internet. The sensor worked on sleep mode infrequently – not always to be precise. These commands are also placed in the processdata.h file for you to try. However, I used a GPIO pin (D13) to switch on an NPN transistor (2N 2219) to keep the SDS011 on during the active stage and then it goes into power off mode.


ILI9163 OLED pinESP32
ILI9163 OLED pinESP32
ESP32 pin
ESP32 pin
ILI9163 OLED pin
 ESP32 pin
AD D15
Reset D4

Schematic: Table-1 [ OLED & ESP32 ]

SDS011 ESP32 pin
5V VIN / 5Volt
TX RX2 (D16)
RX TX2 (D17)

Schematic: Table-2 [ SDS011 & ESP32 ]

BME280 ESP32 pin
CSB n.c

Schematic: Table-3 [BME280 & ESP32]


Final Schematic



  1. hi Bera,
    thanks you share this project, i have duplicate and test this. but do you have meet ESP32 crash and LCD white screen, sometimes the project can runs dozens of loop, but some time only several loop, the LCD will happen display abnormality or ESP32 going to breakdown.

  2. How do you manage to connect the 5v serial TX from SDS011 to the 3.3v RX2 of the ESP32 directly? Is not there any problem doing that? is it 5volt tolerant?

  3. Hi,
    I was looking exactly for this scenario with the ESP32. Everything compiled, just while flashing I get this error: v2.3.1
    Chip is ESP32D0WDQ6 (revision 1)
    Features: WiFi, BT, Dual Core
    Uploading stub…
    Running stub…
    Stub running…
    Configuring flash size…
    Flash params set to 0x0220
    Compressed 8752 bytes to 5467…

    A fatal error occurred: Timed out waiting for packet content
    A fatal error occurred: Timed out waiting for packet content

    However, when I remove the SDS011 from ESP32, the binary gets downloaded. While connecting the SDS011, the ESP32 keeps on reseting – rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

    Is there anything you can suggest where I can start looking at ?


Please enter your comment!
Please enter your name here