A Tutorial to Build Your Own Air Monitoring Sensor!

Incorporating instructions and open-source software from @Luftdaten

With Arduino open-source hardware

Task 0: The Tools You Will Need

A Computer with Wi-Fi Access


Fact Sheet

2. Nova SDS011 Fine Dust Sensor

Fact Sheet

3. DHT22 Temperature Humidity Sensor*

Fact Sheet
There is a 3 and a 4 pins version of the dht; both are suitable, but if possible buy the version with 4 pins

4. Dupont Cables (female-to-female)*

You will need a minimum of 6 cables, at least 10 cm long

5. Flat Micro USB Cables*

Less than 1m
Nylon USB Cable, At least 2m
Having just the 2m Nylon USB Cable should be enough

6. USB to Wall Charger

7. 10 X 12mm Silicone Tube*

The tube doesn't need to be long, at minimum 10 to 15 cm

8. OPTIONAL: 90° PVC Pipes (3 inch / 2.55 cm)*

A PVC Pipe is just one of many ways to shield your sensor from the elements, be creative!

And a healthy dose of perseverance & patience!

Estimated Cost (U.S. Dollar, 2019)

ID Components Amazon AliExpress Bang Good
1 ESP8266 NodeMCU 8.39 2.10 6.33
2 Nova PM Sensor SDS01 40.38 16.40 19.99
3 DHT22 Temperature Humidity Sensor 12.90 2.45 6.53
4 Dupont Cables (female-to-female) 6.98 0.45 3.96
5 Flat Micro USB Cable 2.1A (< 1m) 2.27 1.00 3.22
5 Flat Micro USB Cable 2.1A (Nylon, >=2m) 9.69 3.99 2.89
6 USB to Wall Charger 10.99 1.28 3.60
7 10 X 12mm Silicone Tube 5.99 6.21 5.53
8 90° PVC Pipes (3 inch / 2.55 cm) 8.07 N/A N/A

The total may range from an estimated minimum of 40.17 to an estimated maximum of 106.61 US Dollars (not including shipping).

Task 1: Configure the Arduino Board


Author's parameters in this tutorial:

⚠️ You don't need to have the exact same parametersIf you do run into a problem, it's best practice to include a description of the parameters of your Operating System along with a description of your issue.

You can search for issues and/or ask for help on the following sites:


What does it do?

It enables your computer to communicate (for example, transferring files and installing software) with the computer chip of the Arduino when connected to a USB port; otherwise it won't do anything other than power the arduino board.

No installation required for Linux, chip should be supported

You can always double-check with the 'dmesg' command:

dmesg | grep -i ttyUSB

You should see ttyUSB0 listed:


What does it do?

The Arduino Integrated Development Environment (IDE) is a software to write programs and import libraries from the web onto the Arduino board.

Download the Arduino IDE here.

1.3 Open the IDE

Go to "File -> Preferences" and copy the url below into the "Additional Board Managers URL" field: http://arduino.esp8266.com/stable/package_esp8266com_index.json

Install the libraries

Go to “Tools -> Board … -> Board Administrator” search for “esp8266” and install “esp8266 by ESP8266 Community”




What does it do?

The firmware--built by Luftdaten--configures the Wi-Fi connectivity of the Arduino board and stores the measurements from the SDH011 Dust Sensor and DHT11 Humidity and Temperature Sensor into Luftdaten's database.

The sourcecode of the firmware is available on GitHub.

Download the firmware here

Using the shorter ( < 1m) Flat Micro USB Cable, connect the Arduino to your computer.


Open a terminal/bash & enter the hidden file directory below:

cd ~/.arduino15/packages/esp8266/tools/esptool/0.4.9

Once in the directory, install esptool, the bootloader software:
pip install esptool Reference documentation on esptool: https://github.com/espressif/esptool/blob/master/README.md
⚠️ Hidden Files? Hidden files and folders (whose naming convention starts with ".", such as ".arduino15" in this instance) do not appear while manually browsing or exploring folders, usually to prevent users from deleting sensitive or confidential data. In this case we are making a clear exception as we know which specific file to modify. To show and hide hidden files in Linux, just ctrl + H

Run the command to flash the firmware on Arduino

esptool --port


write_flash 0x0000



: Open the ArduinoIDE, "Tools -> Port", then "Tools > Get board info" to verify that the board is connected to the correct USB port;


: Make sure to write the correct directory path to the firmware.

Reference documentation: https://github.com/opendata-stuttgart/meta/wiki/EN-Installing-firmware
⚠️ IF YOU GET ERROR: [Errno 13]

[Errno 13] could not open port /dev/ttyUSB0: [Errno 13] Permission denied: '/dev/ttyUSB0

Change permission privileges with: sudo chmod 666 /dev/ttyUSB0
The Arduino’s LED (light) should be blinking while the firmware being uploaded, and your terminal should look like this during the import process:
And at the end, you should see the installation completed:
The Arduino Board is now ready to collect & send data! Let's get to the hardware!

Task 2: Assembly Required

We will follow the schema below as our guide to connect the components

Source (open image in a separate tab)

2.1 Connect the Thermometer to the Board*

Schema adjusted for a 3 pin model

Connect Pin 1 to 3V3

Connect Pin 2 to D7

Connect Pin 3 to GND

End Result

2.2 Connect the Dust Sensor to the Board*

Schema adjusted for NodeMCU v1,v2 using (VIN); for NodeMCU v3 use (VU)

Connect 5V to Vin/VU

Connect GND to GND

Connect RXD to D2

Connect TXD to D1

End Result


Great, you now have all of the essential hardware connected!

Task 3: Get Connected

3.1 Plug the Flat USB Micro Nylon Cable to the Arduino Board

Make sure the WiFi chip faces away from the dust sensor
Tie together the dupont cables to prevent the wires from getting loose

3.2 Connect the Flat USB Micro Nylon Cable to the Wall Adapter, and Plug to power supply

3.3 Connect to the sensor's Access Point

The Access Point is defined as "Feinstaubsensor-Your Device ID"; detected over your Wi-Fi networks

⚠️ Access Point not showing up? If the Access Point does not show up in your list of Wi-Fi networks, try plugging the power supply in-and-out. It can take several attempts for the Access Point to show up.

3.4 Configure the sensor's Wi-Fi connectivity

Go to the following IP address: (If you're prompted by a menu, select 'Configure')
Enter the Wi-Fi network credentials (name and password) that the Arduino will be connecting to collect and send data

3.5 Once you land on the Configuration Page, verify that all of your components are recognized

Sample picture for scroll box

⚠️ What's Madavi.de?
Madavi.de is a hosting service used by Luftdaten of data graphed from your device in real time, for the purposes of troubleshooting (i.e. verifying whether your sensor has a reliable Wi-Fi connection, and whether the dust and thermometer data are communicated to the database).
Good job! But this won't fly until we make sure everything is working properly!

Task 4: Troubleshooting

4.1 Verify your sensor's Wi-Fi connectivity

Your device's connectivity is primordial in collecting data; the arduino does not nearly have enough memory to store the data, so if the Wi-Fi is disconnected then the data gets lost. Search for your device (by its unique ID) again: https://www.madavi.de/sensor/signal.php

⚠️ Why is the link to my sensor highlighted in red? Your device isn't registered on Luftdaten's database yet. The purpose of the Madavi's links is to troubleshoot your sensor's connectivity and settings.

4.2 Check that you're getting the data

Check if your sensor is emitting temperature/humidity and Fine Particles data in real time on Madavi: https://www.madavi.de/sensor/graph.php (search the link by your sensor's unique ID). All that you want to observe is whether lines are being drawn on your charts, indicating that measurements are taken in real-time.

Dust Sensor
Fantastic! Now get outside!

Task 5: Setting Up Your Sensor Outdoors

5.1 Tighten the silicone tube to the dust sensor

5.2 Set up your device inside the PVC Pipe

You will want the tube and power cord out of one end of the pipe
Verify your components on the other end are not getting disconnected

5.3 Seal both of the pipe's ends

Be creative! Make your own lid: re-use materials, like a net or, in this example, old pantyhose and rubber bands!
Prevent your components inside from falling out, with the tube and power cord sticking out.

5.4 Set your sensor outside

Plug to a reliable power source
That's it!

5.5 Troubleshoot once more your components' connectivity

Repeat steps 4.1 and 4.2. It's always possible a dupont wire may have been disconnected while setting up your components in the PVC pipe, or that your power outlet doesn't work; in any case, troubleshoot, troubleshoot, troubleshoot!

Links to Madavi below: (once again, search by your sensor's unique ID)

Splendid! Now is time to get serious!

Task 6: Register On Luftdaten

6.1 Create an account on Luftdaten

Once you've troubleshooted and everything is working normally, register your device on Luftdaten. You will need an email address and create a password, and click 'Register'.

In [5]:
IFrame(src='https://meine.luftdaten.info/register', width=800, height=400)

You will receive a confirmation email to the address provided. Click the link to confirm your account and log-in with the credentials you used to register.

In [9]:
IFrame(src='https://meine.luftdaten.info/login', width=800, height=400)

6.2 Register your device

Click on 'Register new sensor'

'Sensor ID' is your sensor's unique ID, the same you've used to search the Madavi links

The sensor board we used in this tutorial is the default listed: esp8266

'Personal Sensor Name' is just a nickname you give to your sensor; this is useful especially if you are registering multiple sensors

Type in the address where the sensor is located (at your own discretion)

If the sensor is set-up inside a building, i.e. it is not taking outside measurements, make sure to check the box 'Indoor Sensor'.

Check the 'Publish exact location' box if you want to make that information public knowledge.

Specify how high from the ground your sensor is installed. My was installed on the balcony of a house, about 3.6 meters high, or 3600 cm.

Specify where your sensor is located relative to traffic. The balcony where my sensor is located faces a residential dirt road, not directly above it but close, thus I have it a rating of 8.The rating is somewhat suggestive, so use your best informed judgement. You can outline your reasoning in the 'Short description of location' section.

If you have used all of the same components as in this tutorial, there is nothing that needs changing.

If you've provided an address, just click 'lookup entered address' and the coordinates will be geocoded to the sensor's location. If the address isn't geocoding or you didn't want to provide an address, specify a latitute and longitude at your discretion.

Once you're done, click 'save settings'

Your sensor is now registered on Luftdaten!

YOU DID IT! But what if I told you that this is just the penguining of fun?

Task 7: Data & You

Check your device's location on Luftdaten's Map!

Your device will be geolocated along with its current measurements
There isn't a search bar; to find your device zoom-in on its known location; note that the sensor's location is mapped at a resolution up to 100 meters
In [3]:
IFrame(src='https://deutschland.maps.luftdaten.info/#16/37.5436/-122.5123', width=1000, height=350)

But I want to do SOMETHING with the data!

Great! The raw data stored as a csv file can be found on Madavi's data directory; the data is compilled by days and months.
You will need to search the directory by your device's unique ID once again (CTRL + F).

Show me the (meta)data!

Open the CSV file in Excel, Python Pandas, or another software of your choosing. Note that certain fields correspond to different models of sensors, so don't expect to have data for fields other than what's specified below (per this Tutorial's parameters):

Field Description
TimeIn UTC (Coordinated Universal Time), convert the time and date of your measurement to match your timezone.
You will also notice that the sensor is taking measurement at intervals of about 150 seconds: For 125 seconds, the SDS011 is shut down & the fan is off. Then for 20 seconds, the SDS011 is activated and the fan is on. For the last 5 seconds measurements are taken, averaged, and saved to Luftdaten's servers.
SDS_P1Coarse Dust Particles (PM10), less than 10 to 2.5 microns in diameters, measurements in µg/m3 (micrograms per meter cubed) averaged over 20 seconds of data collection
SDS_P2Fine Particles (PM2.5), less than 2.5 microns, measurements in µg/m3 (micrograms per meter cubed) averaged over 20 seconds of data collection
TempIn degrees Celcius (°C)
HumidityMeasured as the percentage of saturation humidity
SamplesThe number of measurements taken within the span the Dust Sensor is activated; the raw particle measurements (SDS_P1 & SDS_P2) are averages of those samples

OK here's some dank data, what now?


Pro-Data Scientist Tip #1: Always check your data distribution first! This is super duper important for statistical analysis like regressions which relies on a set of assumptions about the distribution of sample data my dude!


Woa! PM10 readings are much higher than PM2.5, although they trend in the same direction most of the time. Well, PM10, known as coarse particles, are common where dust is stirred up by vehicles on roads. And since the sensor is located facing a dust road, well, there's a probable correlation. That's what we call an alternative hypothesis, which posits that sample observations are influenced by some non-random cause. Gnarly.

Play to your strenghts! Data is a means to an end: explore, ask questions, relate quantitative evidence with your own day-to-day qualitativde observations! Start simple and make your life miserable by getting better.

Congradulations! I hope you learned a things or two, and that you'll keep messing around with the open-source ecosystem that's waiting for you to be explored!