Air Pollution Monitoring Project

Monitoring and graphing pm2.5 and pm10 air particles with ESP32, SDS011 and Cacti.

Similar projects worth following
Monitoring pm2.5 and pm10 air particles with ESP32 and SDS011.
Creating graphs for multiple sensors.

Monitoring pm2.5 and pm10 air particles with ESP32 and SDS011.

Work Flow

As shown above, the esp32 has a sds011(air pollution module) and a oled screen, the esp will connect to the internet of the local network using it’s onboard controller, will use the sds011 to get the correct pm data, will show it on the oled screen, sent it to the cacti server and then the cacti server will create graphs from it.

Zip Archive - 2.48 kB - 09/05/2019 at 07:49


RAR Archive - 46.65 kB - 08/28/2019 at 19:52


ino - 9.23 kB - 08/28/2019 at 19:52


ESP32 and SDS011.docx

Detailed Instructions for the whole project.

document - 2.83 MB - 08/28/2019 at 19:29


  • 1 × ESP32 Microcontroller
  • 1 × SDS011 PM2.5 and PM10 air particles measurement tool
  • 1 × Cacti Graphing software
  • 1 × Server Windows server

  • 1
    All of the steps for the project!

    Let’s get to it!

    Install Arduino IDE, the esp32 board and the Fixed Libraries.

    To install the ESP32 board in your Arduino IDE, follow these next instructions:

    1) Open the preferences window from the Arduino IDE. Go to FilePreferences

    2) Enter into the “Additional Board Manager URLs” field as shown in the figure below. Then, click the “OK” button:

    3) Open boards manager. Go to Tools > Board > Boards Manager…

    4) Search for ESP32 and press install button for the “ESP32 by Espressif Systems“:

    5) That’s it. It should be installed after a few seconds.

    Select the esp32 board in the board selection in the Arduino interface.

    I’ve downloaded all of the libraries and insert them here, please notice, the sds011 library that I’ve used had an issue getting the sds to sleep, in the githab there’s a whole session about it, I had to modify the sleep function so this code includes the already modified sleep code. Please download "libraries.rar" file.

    Copy the libraries to the libraries installation folder – ex.

    C:\Program Files (x86)\Arduino\libraries

    Components and Connections.

    I tried using schematics software, but most of them didn’t have the sds011 and the usb that goes with it so I will write down the connections and will add some pictures. Promise, it will be clear!

    Here’s the components list, links to buy and pictures:


    2 cables Power

    SDS011 with cable and usb

    ESP32 (please notice, there might be different versions of esp32 boards, so when pushing code you might need to select the “ESP32 Pico Kit” instead of the Dev kit here:

    Ok, now that we have all of the necessary parts, we will connected everything as following:

    • Connect the cable that came with the sds011 to the sds011.
    • Connect the 5v to the v5 on the USB dongle that came with the esp32 and well as the ground.
    • Connect the RX of the sds011 to the TX2 on the ESP32 and the TX of the sds011 to the RX2 of the ESP32:
    • Connect the OLED 3v(VCC) to the 3v of the ESP32, the GND of the OLED to a GND in the ESP32, the SCL of the OLED goes to D21 of the ESP32 and the SDA of the OLED goes to D22 of the ESP32:
    • Connect the Cables to the Power so the whole device should look something like this:

    ESP32 Code

    Now for the ESP32 Code, Here’s a final version of the code, after a lot of troubleshooting and modifications. I have put it in github and will updated in case we need to change anything.

    Here’s the link to github: 

    I've also attached the code in the project, please download "esp32_sds011.ino"

    The code do the following:

    • Connect to wireless.
    • Gets the time.
    • Wake up SDS011
    • Get Values from SDS011
    • Send the Values to the remote server.
    • Get the SDS011 to sleep.
    • Wait ~5 minutes and does the loop again…

    (Everything is being displayed on the screen of course.)

    As you can see from the Code there are a lot of waits between the operations, restart every few runs and in case wifi doesn’t work etc. please go thru the code and notes and let me know if you have any questions/suggestions.

    Remote server

    OK, now we have our values on the remote server – Let’s look at the remote server components and configurations!


    • .Net site:  Receiving the file using GET requests.
    • Powershell script: Zeroing the files in case of a none working Sensor.
    • Cacti: Making Graphs.

    Let’s dive in to each Component.

    • .Net site

    A very simple code that uses .Net 4(I believe), so you will just need to create new site in IIS copy these files from github:

    or get it here in the project: "DataCollectorFiles.rar"

    Now go to \App_Code\WebService.cs and edit the location of the destination files ex.


    using (StreamWriter writer = new StreamWriter("C:\\inetpub\\wwwroot\\DataCollector\\Files\\" + Filename))


    The above will write the files to “C:\\inetpub\\wwwroot\\DataCollector\\Files\\”,


    After that a simple get call to your site as following will create a file and the content you want in that file, ex:

    This will create a file name “FileName.txt” and the content will be “FileContent”

    Please notice I’ve set the port to 81… you can use anything you’d like as long as you set your IIS correctly...

    • Powershell script: Zeroing the files in case of a none working Sensor.

    In the RAR folder under \Files\Zeroing_Files.ps1 you also have a simple powershell script that when it runs it will go over all of the Sensor*.* files and if they were not modified in the last 15 min will insert a “0” into them as we don’t want strait lines that will confuse us. So in case a sensor is down we will see 0 in the graphs. Please modify the location of your files and the Name of the files in the script ex:


    So if you have a folder ‘d:\MyFolder’ and your files are named ‘AirFiles’, it will look like this:

    $folder=" d:\MyFolder\AirFiles*"

    • CACTI
      • We shall start by installing cacti, as you notice from the above .net, I am using a windows box so we will download the cacti installation for windows, please go here and download the last version:

    Once you have Cacti Installed, follow the instructions and login to your new CACTI.

    For getting the actual graphs in place I will be doing explanation and screenshots, as it’s not so intuitive (for some (myself included)).

    • Create a New Data Input Method

    Go to “Data Collection -> Data Input Methods” and click the plus sign and create two of them:” Echo PM2.5 Value” and “Echo PM10 Value” they should look like this:

    • Now let’s create a new data source, go to Templates->Data Source and click on the plus sign to create a new one, we will create again two of them: “PM10” and “PM2.5”, they should look like this:
    • Let’s create the Graph template, I’ve called it "Air Pollution”, you will be able to call the graphs anything you’d like later on of course. So let’s go to “Templates->Graphs” and click on the plus sign, as usual…we will need to add the Graphs inputs that we created and the graph templates of course. The configuration of the template should look like this:
    • OK, Now we can finally create the a graph for our device, go to “Create->New Graphs” on the device I usually have my “Local Windows Machine” (as I didn’t add anything else…), I will just use if for all of my graphs…Under the graph templates we will select the “Air Pollution” template and click on “Create”

       at the bottom, this is how it should look:

    Now we will get to the graph creation…:

    Title: name of the graph.

    Under “Data Source [Template: PM10]”

    Name: *doesn’t really matter but I use something that will ring a bell…

    Internal Data Source Name: *Leave as it is.

    Custom Data [Template: PM10]: The actual file locatio that has the number for the graph.

    Same as the above for “Data Source [Template: PM25]”

    Here’s how it should look like:

    Now, click on Create! Ok we are all set, to view the graph we will just click on the Graph tab:

    And on the right side we can select the tree view or the List View. Let’s go to the list view:

    And select our new Graph, now we can view our graph and history:

    Please notice,

    • It takes cacti a few polls for the graphs to actually start working so please be patient – give it at least 15 minutes!
    • There are A LOT of options in Cacti, you are welcome to read thru the documentations and set your own configuration. Such as specific trees view for specific users, and tones more options, Cacti is GREAT!.

    If you have any questions, please don’t hesitate to contact me, either here to my email. 

View all instructions

Enjoy this project?



Gin Fiz wrote 11/09/2020 at 16:41 point

Thanks for the project! I will try it this week. I will put the Cacti server on a RASPI. Hopping it will work!

  Are you sure? yes | no

Tim Rightnour wrote 08/29/2019 at 01:36 point

Love it.  I'm planning a project that might involve one of these sensors, so tagging along..

I used o use cacti for this kind of thing, and recently I found InfluxDB and Grafana.  I had all kinds of code to build cacti graphs, and huge sets of steps like yours, but with influx/grafana, I found that if I just aimed the data at it, it practically spat graphs at me with no actual work.  It's *way* easier to setup.

I've heard these fan-type sensors get dirty over time, and then start increasing readings artificially.  I'd be curious to see how it does over time...

  Are you sure? yes | no

Nir H wrote 08/29/2019 at 12:47 point

Thank you Tim, I am actually going to create another sensor that is connect to the cellular network with this ESP32 and going to use the deep sleep capabilities for the esp, that's going to be fun!

InfluxDB and Grafana looks nice, I think I've heard of it in the past but my default is always cacti, but on my next project I will be giving them a chance as you made me curious! :)

Regarding the fan-type sensors, you are correct, over time the do become inaccurate, we have a sds011 that works continuously  for almost a year with this debugging board:,searchweb201602_9,searchweb201603_53

it is off by about 2-3 (on low values, and about 5-8 on high values) in PM2.5 and PM10 then a new board... not too bad, please don't forget that it also has a max of 8000 working hours which is about 11.1 months. In the above project I am putting the sds011 to sleep and using it for about 20 seconds every 5 minutes so that should (in theory) give us much more usability time.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates