Sniffer Air Quality Sensor using ESP32 with LCD + PMSA003 + BME680

With the California wild fires most keeping me indoors, I couldn’t help but build a project to monitor it.
Here’s my Sniffer air quality sensor using:

  • ESP32 TTGO T-Display 1.14" LCD
  • PMSA003 Air particulate sensor
  • BME680 Temperature, Pressure, Humidity, and Gas Sensor
  • Simple PCB to integrate all the pieces without wires

Sharing Kicad PCB + Gerbers and ESPHome config on Github sniffer project.

Early pics of it just assembled this weekend:

Home Assistant:

Comparison of sensor while placed outside near Purple Air Sensors:

11 Likes

This is awesome. I live in Aus and was looking for exactly this as we are coming up to bushfire season. Any chance of doing a full tutorial?

1 Like

Thanks! I’ll probably put together a write-up on my blog. Need to write-up the first part but hate writing so I need to do that.

It’s mostly buy 4 parts, solder them together with provided pin headers and flash it.

1 Like

this looks cool! I have some AQ sensors on order from Aliexpress. If you have this to measure outdoor air quality, why include the screen? (could a non-screen esp32 work?)

Also what is the part to get the port the PMS plugs into?

I bought the ESP32 T-Display because it was $12 and had a display that I wanted. I’d only save a few dollars without the display and I find it handy. No need to use it. Will certainly work without a display, just modify the ESPHome config yaml on the github page to drop the display and you’re on your way.

Which part do you mean? The connector is a 1.27mm pitch 2x5 pin header. The PMSA003 I bought included the pin headers.

The PCB that the connector plugs in to (aka “Sniffer” design) is my design. There’s a link to order them from PCBWay here or on the Github project page.

1 Like

I ordered some of your boards. Looks like a clean way to set this all up!

1 Like

Awesome! Enjoy it and let us know how it works out!

Wrote up a blog post on this with more details for those interested.

1 Like

Got it up and running. Now why is my indoor air so bad…

1 Like

Awesome, do you have an indoor air purifier/filter? Try turning that on.

Also need to let it run for a short while (a few minutes at least) to stabilize.

no purifier… my wife has an oil diffuser running right near by so that may be throwing it off. also overdue on changing my furnace air filter.

This is an awesome project. I’m getting the components to build it. Once I’m done with the unit, I’ll work on the enclosure for 3d printing. Thanks for sharing!

3 Likes

Got one of your boards and got everything running to my liking despite knowing NOTHING about all of this stuff - also my first time soldering!

I was able to get the BME680 to pull CO2 and VOC averages using some stuff I discovered in newer documentation on the device, and it’s working pretty well.

Only question I have, and I’m sorry if this is entirely clueless - is there a TX pin for the particulate sensor? I was looking for a way to slow down the gathering of data so that there’s not so much coming in and it says I need to designate a TX pin to do so. Haven’t got the first idea how to determine that if there is one at all in this particular setup.

Thanks for doing all of this!

Are you able to tell me the part number of the TTGO board you got?

T-Display v1.1 - I may have figured it out. Just plugged in the next number down from the RX pin and it seems to have worked.

Seems everything has worked out at this point, really!

Hello. As I am waiting for my final part to arrive, I wanted to test the code. When tried to verify, it says temp2 is not defined. Skimming through the files, I do not see temp2 but temp.

These are the parts I will have.

ESP32 TTGO T-Display module
PMSA003 module
BME680 CJMCU module
display:
  - platform: st7789v
    model: TTGO TDisplay 135x240
    backlight_pin: GPIO4
    cs_pin: GPIO5
    dc_pin: GPIO16
    reset_pin: GPIO23
    update_interval: 1s
    rotation: 270
    lambda: |-
.
.
.
.
      r += 25;
      it.print(120,    r, id(sz_24), id(my_gray),   TextAlign::TOP_CENTER,  "Environment");

      r += 23;
      float temp_f = id(temp).state * (9.0/5.0) + 32.0;
      float temp2_f = id(temp2).state * (9.0/5.0) + 32.0; # <<<----------
      /*it.printf(4,   r, id(sz_20), id(my_yellow), TextAlign::TOP_LEFT, "%0.1f°F", id(temp).state); */
      it.printf(4,   r, id(sz_20), id(my_yellow), TextAlign::TOP_LEFT, "%0.1f°F", temp_f);
      it.printf(125, r, id(sz_24), id(my_yellow), TextAlign::TOP_CENTER, "%0.1f°F", temp2_f);
      it.printf(236, r, id(sz_20), id(my_yellow), TextAlign::TOP_RIGHT,  "%0.1f%%", id(humidity).state);
1 Like

Anyone have this sensor placed outside of the home? If so, how are you enclosing the device???

How did you wire the PMSA003 sensor to the ESP32? I can’t get mine to output any data, but the fan spins up

i’m having this same issue. did you ever figure this out?

1 Like

Hey. I don’t remembered why I did it this way, but looking at the block of code I posted. I replaced the temp2 with temp. You can paste this block of code and see if it works for you.

      r += 23;
      float temp_f = id(temp).state;
      float temp2_f = id(temp).state * (9.0/5.0) + 32.0;
      /*it.printf(4,   r, id(sz_20), id(my_yellow), TextAlign::TOP_LEFT, "%0.1f°F", id(temp).state); */
      it.printf(4,   r, id(sz_20), id(my_yellow), TextAlign::TOP_LEFT, "%0.1f°C", temp_f);
      it.printf(125, r, id(sz_24), id(my_yellow), TextAlign::TOP_CENTER, "%0.1f°F", temp2_f);
      it.printf(236, r, id(sz_20), id(my_yellow), TextAlign::TOP_RIGHT,  "%0.1f%%", id(humidity).state);