Posted on 44 Comments

#38: DIY air quality sensor, part 1 – “Basic” version

It’s surprisingly easy to make your own simple air quality sensor. All you need is a cheap laser-scattering particulate matter sensor, a Wemos D1 Mini, a soldering iron, and Tasmota.

Part 1 shows how to make the simplest possible version of the SuperHouse Air Quality Sensor, the “Basic” version.

Part 2 shows how to improve it to make a more advanced “Display” version, Part 3 is a detailed walkthrough of how the firmware works, Part 4 will explain how various Air Quality Index calculations are done around the world, and Part 5 will step it right up with the “Pro” version with VOC sensor.



Here in Australia we’ve recently had a terrible bushfire season, and there’s been a lot of concern about the effects of smoke on air quality. Smoke particles, pollen, and many other forms of air pollution are tiny. Really tiny. Many people have been wearing “PM2.5” face masks, which means they are designed to filter out particles as small as 2.5 microns in size, but pollen and smoke can be even smaller than that.

Detecting tiny particles down in the 0.1 to 10 micron range is hard. Normally you’d need an electron microscope to detect something this small. In fact these particles are so small that they are often smaller than the wavelength of light, which is in the region of 0.5 microns. This means light doesn’t interact with them in the usual way: instead of bouncing off them like a particle, it can bend around them like a wave, and it can also refract inside them like tiny lenses.

Laser-scattering particle detectors pass a laser through a test chamber, with a deflection sensor on the other side. Particles in the test chamber cause the beam to be scattered in different ways, and the deflection sensor can use this scattering to determine the number and size of particles in the chamber.

This process creates a series of concentric rings on the deflection sensor, which can use the spacing of the rings to determine the characteristics of the particles.

The particles that are detected are then categorised, or “binned”, into different size ranges for reporting.

All of this functionality is wrapped up in the tiny Plantower PMS5003 sensor, which provides a serial interface to report the statistics for the particles that it detects.

Reporting is normally provided in a couple of forms.

The simplest number is the PPD value, which stands for “particles per deciliter”. The higher the number, the more particles there are in the air sample.

The most commonly used number is the “ug/m^3” value, which is micrograms per cubic meter. This is the total mass of particles in that size range in a cubic meter of air, so smaller particles will require a higher raw count to add up to the same mass as larger particles.

Parts required

The “Basic” version of the SuperHouse Air Quality Sensor only requires a a Plantower PMS5003, the connection cable that comes with it, and a Wemos D1 Mini. See the links above for sources to buy them.

You can also print your own 3D-printed enclosure, or buy one from me if you don’t have easy access to a printer.

Connect PMS5003 to D1 Mini

The PMS5003 requires a 5V supply because it has an internal fan to keep air flowing through the test chamber, but all its I/O connections are 3.3V.

This is perfect for a D1 Mini, because we can connect the power pins to 5V on the D1 Mini and connect the sensor “TX” pin to an I/O header on the Mini.

Cut the supplied cable off at about 2/3rds of its length. Plug it into the PMS5003 to check the orientation, and then strip and tin the ends of the wires connected to pins 1, 2, and 5.

Connect VCC and GND from the PMS5003 to the 5V and GND headers on the D1 Mini.

Connect TX from the PMS5003 to the D4 header on the D1 Mini, which is GPIO2 for the ESP8266 MCU.

Connections between PMS5003 and D1 Mini

3D printed case

I’ve designed a case that slips over the PMS5003 and provides a space for the D1 Mini and wires. You can download the STLs and print it yourself, or if you don’t have access to a 3D printer you can buy it from me in a variety of colour options.

The case comes in two halves. Insert the PMS5003 into the case first, and then slip the D1 Mini into the space at the bottom. The case is oriented so that if the USB socket is on the side towards the PMS5003 it will be accessible through a slot.

Push the wires down into the case so everything is neat, and then slide the other half of the case over the top. It may take some jiggling to get the wires out of the way and the D1 Mini properly inserted into the slot.

Install Tasmota

There are many ways to install Tasmota on the D1 Mini, but my new favorite is to use Tasmotizer. I did a whole video about how to install and use Tasmotizer, so follow the instructions here if you need to install it:

SuperHouse #37: Installing Tasmota with Tasmotizer

Once you have Tasmotizer running, connect the D1 Mini using a USB cable and select the port.

Note: As of Tasmota v8.2, support for the PMS5003 has been removed from the normal “tasmota.bin” release binary. Instead, you must select “tasmota-sensors.bin”.

  1. Click the button next to “Release“.
  2. From the drop-down, select “tasmota-sensors.bin” (not the regular “tasmota.bin” as shown above)
  3. Click “Tasmotize!” and wait about a minute for the D1 Mini to be flashed and reboot.

Configure WiFi and apply the “SuperHouse AQS” template

After the D1 Mini has been flashed, click “Send config” in Tasmotizer to open the configuration screen.

  1. Click the checkbox to enable the WiFi section, and put in the details for your WiFi network.
  2. If you use MQTT, click the checkbox to enable the WiFi section and put in the address for your broker. My personal preference is to change the “Topic” entry to “tasmota-%06X” so that the MQTT topics will be dynamically generated using the unique ID of each D1 Mini.
  3. Click the button next to “Template”.
  4. Copy the template below, and paste it into the text box at the bottom of the config screen:
{"NAME":"SuperHouse AQS","GPIO":[255,255,69,255,255,255,255,255,255,255,255,255,255],"FLAG":15,"BASE":18}

Click “Save” to send the new configuration to the D1 Mini.

It will then restart, and will connect to your WiFi network using the values you just provided.

Connect to Tasmota web interface

You can use a serial console connected at 115200bps to get the IP address directly from the D1 Mini, or look in the management interface for your DHCP server to find the recently added device.

Once you’ve found the IP address, put it into a web browser to load up Tasmota’s web interface.

The module will report its latest readings, updating as fast as the sensor is sending them.

You can also configure the D1 Mini manually if you didn’t use the template above. Starting from a default Tasmota installation, log into the web interface and set up the module as shown below.

Access data via MQTT

Tasmota periodically publishes all the PMS5003 readings aggregated into a single JSON string, in the “../SENSOR” topic.

The topic will depend on the settings you applied for MQTT. In my case, with the “Topic” modified as explained above, the readings are published to a topic that looks similar to “tele/tasmota-5F596F/SENSOR” with the unique ID of this particular device substituted.

The published value will look something like this:


You can parse the JSON using your favorite method, such as with Node-RED. I’ll go over this in more detail in Part 2 when we look at more advanced software options.

The “PMx” values are micrograms per cubic meter. The “PBx” values are particles per deciliter.

Further improvements

This “Basic” version of the SuperHouse Air Quality Sensor is very simple to make, but it has a couple of limitations.

The laser and the deflection sensor in the PMS5003 can degrade over time. After about 6000 hours of continuous use it may begin to decrease in sensitivity. The life of the sensor can be dramatically extended by shutting it down for a couple of minutes, then waking it up, giving it time to stabilise, taking a reading, and shutting it down again. With this change the sensor can last for many years.

There is also no way to interact with the device directly. You have to access it over the network, either by loading the Tasmota web interface or by using the data published to MQTT. Adding a screen and a mode button can make it easy to read particulate levels directly on the device.

Both of these limitations are fixed in the “Display” version of the SuperHouse Air Quality Sensor in the next episode. Stay tuned!

44 thoughts on “#38: DIY air quality sensor, part 1 – “Basic” version

  1. Don’t be so harsh on your abilities, you do much better than most of us do or try to do.

  2. find the datasheet of the module on

    PMS5003T support pm_2_5, temperature and humidity,
    PMS5003ST supports pm_2_5, temperature, humidity and formaldehyde measurement.

    I’d interesting to also have temperature and humidity data out of the same box.

    1. The “Pro” version of this project (which will be part 3 in the series) uses a PMS7003 sensor and a BME680, so it gives all the particle data plus temperature, humidity, and volatile organic compound level. It also has a big colour LCD on the front, and RGB LEDs so it can glow different colours to give warnings about dangers.

      1. Hi Jonathan,

        I really like your video’s. Watch them a lot.
        When will this Part 3 be available? Haven’t found it yet.
        I am really curious about this “Pro” version of the Air Quality Sensor.

        Thanks and keep up the good work.

        1. I’ve split up the video that was going to be part 3, and it’ll be coming out hopefully in a few days as a separate video about how to do datalogging using MQTT, Node-RED, InfluxDB, and Grafana. I realised when I was working on it that it’s not specific to air quality, so I thought I’d do it as a separate video. Then part 3 will be more about how air quality is reported, and part 4 will be the Pro version with a colour screen.

          1. Hi Jonathan, looking forward for the Pro version of the air quality sensor. Any clues as to when it will be available?
            Cheers mate!

  3. This seems like an ideal application for one of the <US$20 ePaper+ESP32 modules, so that the last readings can be continuously displayed.

    1. Yes, they look quite nice but I don’t have one. The “Pro” version of the project I’m doing (which will be Part 3) is a bit like this, except with an ESP32, a PMS7003, and a BME680 so it can do VOC reporting.

      1. That’s really nice project. Waiting for part3!

  4. Does anybody know how to calculate the air quality index AQI? I quite like the approach to put all measurements together in 1 index, maybe put the dominentpol as well like do.

  5. hi as another posted earlier i was looking too the same item and I was wondering if it is possible to share the data pin by just adding a nodemcu to this so you can have the data also reported to home assistant ?

    thank you for all your great videos.

    1. Great question! I think probably yes, because you’d just have the TX from the PMS going to an RX pin on the NodeMCU board, so the normal controller in that device should still get the data too. You’d need to have a common GND connection to the original controller. If you try it, please let us know how it goes on the Discord server or the forum.

  6. Hey Jonathan,

    Can we have the BOM list of the full featured part 3 sensor that we can order those parts now? I’d really like to make one myself.
    I really liked the first video and can’t wait for part 2 and 3.

    Greetings from Germany

    Michael aka Hasitier on Twitter

    1. Hi Michael!

      The design for the “Pro” version is on GitHub. It’s still work in progress though:

  7. Notice the pro version uses a ESP32. If I keep the ESP8266 and Tasmota firmware, can I put the PMS5003 to sleep, and then wake it up once per minute to take a reading to preserve the laser? Is this possible in Tasmota?

    1. I don’t know how to do that with Tasmota, and I don’t think it’s possible because the Tasmota driver doesn’t have a connection for sending commands to the PMS. In part 2 I’m going to show how to install firmware that supports sensor sleep, and it also reports the values in the same format as Tasmota. The firmware is already up if you want to play with it before the video comes out:

      1. Thanks for the reply. I’ll take a look at the Tasmota code and see if I can add the functionality. Unfortunately, the datasheet is very poorly written and there is little information on what the warmup period is. I looked at your code above and noticed you have the warmup period set to 30 seconds before taking a reading after waking up. Do you know where that value came from?

  8. Is the device calibrated?

    1. It doesn’t come with a calibration certificate. However, various people have independently compared it with calibrated sensors and the results seem to be very good. So it’s ok for your own use as a general indication, but you couldn’t use this to do proper “official” air quality testing unless you calibrated it yourself.

      1. Hi,
        I have reconstructed the sensor thanks to the excellent tutorial and a nice Grafana dashboard. Unfortunately, the sensor is highly dependent on the RH and actually unreliable for the PM10.
        It is however credible for the PM2.5 concentration compared to our Met One BAM 1020 (reference measurement device).
        Plantower does not provide a calibration certificate even to research institutions, nor the applied algorithm. It is therefore a low cost sensor that can show trends in air pollution.
        However, it remains a splendid and instructive exercise for students.


        1. Thanks for that information, Roland! It’s interesting to hear how it compares to your calibrated sensor.

  9. Tasmota 8.3.0 now has the option to put a pms5003 to sleep

    1. tasmota 8.3.1 kills it, no pms5003 anymore

      1. it works, was updates to tasmota.bin and not tasmota-sensors.bin , corrected it and is OK now.

        1. you did right thing, I did the same initially(as it says so in this post).
          Uploading tasmota-sensors.bin instead did the trick!

          1. also, the templating configuration won’t work(at least in 8.3.1). You need to set GPIO2 to 69 in module configuration instead.

        2. Thanks this worked for me.

    2. how do you do it? Looking at setting, can’t figure this out.

  10. Is there an issue with Tasmota 8.4.0? I’m not getting any data from the module.

    1. Did you get it working?

  11. Hi Jonathan,
    I also love the Wemos D1 Mini!
    We have an open-source, open-hardware built for a similar air quality sensor using the PMS5003 but also including a CO2 and humidity/temperature sensor. We use a small i2c OLED display or link it to a backend.

    We also published our own Arduino Library to make coding really simple.

    You can read more about our project here:

    Would be great to hear some feedback from you!


  12. Great tutorial! I managed to connect Node MCU with PMS and obtain some reading. Is it possible to connect the MQTT data to Home Assistant without node red?

    1. Sorry, I meant D1 mini

  13. Hello. This is a great presentation. Where did you get the PM5003 file so that it is selectable under “Configure Module”, D2 GPIO4 drop down ?

  14. Possible to deactivate the sensor to keep the life of the laser and fan? thank you

    1. Yes, that’s mentioned in the video and explained in more detail in part 2, which also has the code to do it:

  15. Question… It looks like it only publishes to MQTT every 5 minutes… Any way to change that time interval?

  16. Does anyone have details on how to connect a PMSA003 to wemos d1 mini instead of PMS5003 or PMS7003?? If yes please let me know the Template details for the same.

  17. I cant get any data. Pleae help!

  18. Hi,

    first, thanks a lot for the really great tutorial. Everything‘s working almost fine, except that the blue led is always blinking and that mqtt message’s JSON include for example „PM2.5“ which leads to a „PM2/5“ when the JSON is parsed in iobroker’s Sonoff adapter. Is it possible to deactivate the led and use a different name for the „PM2.5“ attribute, such as „PM2_5“.

    Thanks, Oli

  19. Is it me, or is this no longer supported in Tasmota 12.5.0?
    I can no longer find ‘PMS5003Rx’ in the list.

    1. I had this trouble too. You will need to switch to the tasmota_sensor firmware.

  20. Hi Jonathon, great project! I used a PMS7003 which is half the thickness of the PMS5003 still used the same 3D printed case which allowed me to add a 1000mAh Lithium flat battery TP4056 charger board and on/off switch. Fits like a glove and totally portable..
    Cheers Gary

Leave a Reply

Your email address will not be published. Required fields are marked *