Do it yourself Air quality sensor ( PM2.5, VOCs, CO2, ... )

How to build an air quality sensor with an esp8266 and a few cheap sensors

August 19, 2021
esp8266 home-assistant air quality

What is that ?

As usual, a simple list of steps to build your own air quality sensor. This requires a working installation of home-assistant, and the tasmota and mqtt integrations running. Setting that up is out of scope since there’s plenty of tutorials on how to do so.


Links to amazon at the bottom of the article to the exact sensors and board I used.

  • 1 esp8266 board ( NodeMCU preferred since it gets you an easy usb flash and power )
  • 1 PMS5003 pm sensor
  • 1 DHT22/AM2302 Temp and humidity sensor
  • 1 CCS811 CO2/VOC Sensor

The build, connecting the sensors on the esp:

for the purpose of this build, if you look at the PMS5003 from the side where the connector goes, the pin nearest to the edge of the case is pin 8.

Pin1: VIN ( 5V )
Pin2: Ground
Pin4: TX
Pin5: RX\

You can easily use Female/Male jumper wires to avoid soldering. Remove carefully the connector from the ribbon cable supplied with your PMS5003 and the male jumper should fit in the hole. You can use electric tape to secure everything in place.

Connect the pin1 to VIN on the esp, then pin2 to any ground. Pin4 goes to d6 and pin5 to d7.

For the rest, female to female jumpber wires will help without any soldering.

For the DHT22, + goes to 3.3V, - goes to ground and the single out pin goes to D4

For the CCS811 now, VCC goes to 3.3V, GND and WAKE to ground, SCL goes to d1 and sda to d2.

Flashing firmware/config

Simply connect to your computer with a microusb cable, then use tasmotizer to flash the latest tasmota-sensors.bin

I suggest you also use tasmotizer to inject the wifi config.

Once this is done, you can use the web interface of your newly flashed tasmota ( Tasmotizer get ip is useful ).

Configure as such in the module section:\

  • Generic module ( 18 ) -> at the end\
  • D4 as AM2301\
  • D2 as I2C SDA\
  • D1 as I2C SCL\
  • D6 as PMS5003 Tx\
  • D7 as PMS5003 Rx\

Then configure your MQTT params as you would do any tasmota device so that Home-Assistant can find it ( you can add the Tasmota integration in Hass to make it easier ).

Then in the console section:

Set temps in Farhenheit:

SetOption8 1

To get a better lifespan on the pms5003, get one measure every 5mn instead of permanent activated, do not do that before the discovery on home-assistant, or home-assistant will not see the pms5003.

Sensor18 300

And if you want to add a custom mqtt sensor in home assistant to have the pm2.5 AQI calculated:

ON Tele-PMS5003#PM2.5==0 DO Backlog var1 0; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<12 DO Backlog var1 %value%;mult1 4.16; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<35.4 DO Backlog var1 %value%;SUB1 12.1; MULT1 2.10;ADD1 51; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<55.4 DO Backlog var1 %value%;SUB1 35.5; MULT1 2.46;ADD1 101; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<150.4 DO Backlog var1 %value%;SUB1 55.5; MULT1 0.51;ADD1 151; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<250.4 DO Backlog var1 %value%;SUB1 150.5; MULT1 0.99;ADD1 201; event sendaqi BREAK 
ON Tele-PMS5003#PM2.5<350.4 DO Backlog var1 %value%;SUB1 250.5; MULT1 0.99;ADD1 301; event sendaqi ENDON 
ON Tele-PMS5003#PM2.5>=350.4 DO Backlog var1 %value%;SUB1 350.5 MULT1 0.66;ADD1 401; event sendaqi ENDON
ON event#sendaqi DO publish airsensor/pm25aqi %var1% ENDON

then activate the rule:

Rule1 1

Same thing if you want a text to help make sense of the CO2 levels:

ON Tele-CCS811#eCO2<450 DO Backlog var2 Co2 level ideal ( Planet is at 440 ); event sendco2 BREAK
ON Tele-CCS811#eCO2<1000 DO Backlog var2 Co2 level normal ( < 1000 ); event sendco2 BREAK
ON Tele-CCS811#eCO2<2000 DO Backlog var2 Co2 level poor ( 1000-2000 ); event sendco2 BREAK
ON Tele-CCS811#eCO2<5000 DO Backlog var2 Co2 level bad ( 2000-5000 ); event sendco2 BREAK
ON Tele-CCS811#eCO2<40000 DO Backlog var2 Co2 level hazardous ( > 5000 ); event sendco2 BREAK
ON Tele-CCS811#eCO2>=40000 DO Backlog var2 Co2 level deadly, evacuate ( > 40000 ); event sendco2 ENDON
ON event#sendco2 DO publish airsensor/co2text %var2% ENDON

then activate the rule:

Rule2 1 

Example config for those custom sensors in home assistant:

  - platform: mqtt
    state_topic: 'airsensor/pm25aqi'
    unit_of_measurement: 'aqi'
    name: 'Airsensor2 AQI'
    value_template: "{{ value | int }}"

And, voila ! you can now use the home-assistant dashboard to add the different sensors, or whatever your heart desires !


Check if you did not inverted d6/d7 if you don’t see the pms5003 sensor.

Products I used for this: