DIY Air Quality Monitor With ESP32, PMS7003 and Grafana - Open Source Project

by m4CI0 in Circuits > Electronics

255 Views, 6 Favorites, 0 Comments

DIY Air Quality Monitor With ESP32, PMS7003 and Grafana - Open Source Project

IMG_2424.JPG
Grafana_visualize.png
IMG_2427.JPG

AirForecast is a compact air quality monitoring system designed to help you stay informed about the air you breathe. It continuously collects real-time air pollution data, stores it in InfluxDB, and visualizes trends using Grafana. To provide accurate air quality forecasts, it leverages the Holt-Winters model, predicting future AQI levels.

One of the standout features of AirForecast is its RGB LED indicators, which provide instant AQI feedback without the need for a screen—just a quick glance lets you know if the air is safe. The project was inspired by the increasing frequency of wildfires and growing concerns about air pollution worldwide. So how to make this project ?

Supplies

You’ll just need a few key components:

  1. 1x ESP32 SUPER MINI
  2. 1x PMS7003 – A sensor that measures air pollution levels (PM2.5 & PM10 & PM1).
  3. 1x BME280 (I2C) – Monitors temperature, humidity, and air pressure
  4. 2x WS2812B RGB LEDs – Instantly show air quality status
  5. 2x 100nF capacitors - for WS2812B
  6. 1x USB-C cable
  7. Custom PCB from JLCPCB
  8. 3D-Printed Case

PMS7003 Sensor & BME280

PMS.png
51ODgsbP5WL._AC_UF1000,1000_QL80_.jpg

The PLANTOWER PMS7003 is a compact and accurate air quality sensor that measures PM1.0, PM2.5, and PM10 using laser scattering technology. A built-in laser detects particles as they pass through, and a photodetector measures their size and concentration in real time. An internal fan maintains airflow, ensuring consistent and reliable readings.

I chose the PMS7003 for its precision, real-time monitoring, and ease of integration. Unlike older sensors, it provides detailed data on different particle sizes, making it useful for indoor and outdoor air quality tracking. Its UART interface allows seamless communication with microcontrollers like the ESP32, and its low power consumption makes it ideal for continuous operation.

To complement the PMS7003, I also integrated the BME280 sensor, which adds temperature, humidity, and atmospheric pressure monitoring. This sensor provides essential environmental data, helping to analyze how weather conditions impact air quality. The BME280 measures:

  1. Temperature from -40°C to 85°C with an accuracy of ±1.0°C
  2. Humidity from 0% to 100% with an accuracy of ±3%
  3. Pressure from 300 hPa to 1100 hPa with an accuracy of ±1 hPa

By combining the PMS7003 and BME280, this project provides a complete air quality analysis, offering both pollution levels and climate conditions in real time.

PMS7003 LINK

BME280 LINK

Soldering & Schematics

Schematic_AirForecastV1.0.png
Zrzut ekranu 2025-02-22 135658.png
s-l1200.jpg
Zrzut ekranu 2025-02-22 141033.png

Before uploading the code, it's a good idea to test your components by connecting them according to the schematic above. This ensures that everything is working properly before soldering components on PCB. Below is a detailed step-by-step guide to wiring and assembling the device.

LINK to schematics: LINK

BME280

⚠️ Important: Setting the Correct I2C Address

Some BME280 modules have an I2C address of 0x77 by default, but your ESP32 might be looking for it at 0x76. If the sensor isn’t being detected, you might need to solder the two address selection pads on the board. It’s a simple fix—just a small dab of solder on the correct pads will ensure the ESP32 can communicate with it properly.

Connecting the BME280 to the ESP32

  1. VCC3.3V on ESP32
  2. GNDGND on ESP32
  3. SCLGPIO7 on ESP32
  4. SDAGPIO6 on ESP32

PMS7003

The PMS7003 is the heart of the air quality monitoring system, providing real-time PM1.0, PM2.5, and PM10 data.

⚠️ Important: PMS7003 Extension cable and THT connector

If you're ordering the PMS7003, make sure to get an extension cable and a THT connector. THT connector will make it much easier to solder the sensor to a PCB later and will give you flexibility when placing it in the final enclosure.

  1. VCC → 5V on ESP32
  2. GND → GND on ESP32
  3. TX → RX (GPIO20) on ESP32
  4. RX → TX (GPIO21) on ESP32

WS2812B

Finally, to complete the prototype, connect two WS2812B RGB LEDs to the ESP32. These LEDs will provide instant air quality feedback with color-coded indicators.

  1. VCC → 5V on ESP32
  2. GND → GND on ESP32
  3. DIN (Data Input) → GPIO4 on ESP32

RGB colors meaning

🟢 Green (0 - 50 AQI) → Good air quality: The air is clean and poses little to no health risk.

🟡 Yellow (51 - 100 AQI) → Moderate air quality: Acceptable for most people, but sensitive individuals should be cautious.

🟠 Orange (101 - 150 AQI) → Unhealthy for sensitive groups: Children, elderly, and those with respiratory conditions should limit prolonged outdoor exposure.

🔴 Red (151 - 200 AQI) → Unhealthy air quality: Everyone may start to experience health effects, and sensitive groups should avoid outdoor activities.

🟣 Violet (201 - 300 AQI) → Very unhealthy air quality: Serious health effects possible, with emergency conditions for those at risk.

⚪ White (301+ AQI) → Hazardous air quality: Health warnings of emergency conditions. Everyone should avoid outdoor exposure.

InfluxDb & Arduino Code

IMG_2429.JPG
1.png
5.png

1. Creating an InfluxDB Account and Bucket

To store sensor data in InfluxDB, you first need to create an account and set up a data bucket:

  1. Go to InfluxDB Cloud and sign up or log in.
  2. In the left-hand menu, navigate to Load Data → Buckets.
  3. Click + CREATE BUCKET to add a new data storage container.
  4. Enter a name for the bucket, such as PMS sensor project.
  5. Set a retention period (e.g., 30 days) to define how long data will be stored.
  6. Click Create to finalize the bucket setup.

Your bucket is now ready to receive data from the ESP32 C3 Mini.

2. Generating an API Token

To securely send data to InfluxDB, you need an API token:

  1. Go to Load Data → API Tokens in the left menu.
  2. Click + Generate API Token to create a new access key.
  3. Choose either All Access Token (for full control) or Custom Token (to set specific permissions).
  4. If using a Custom Token, grant Read & Write access for your bucket.
  5. Click Generate Token, then copy and save it securely. You won’t be able to view it again later.

3. Configuring and Uploading Code to ESP32 C3 Mini


Link to Arduino Code: LINK

With your bucket and API token ready, update your ESP32 C3 Mini code to connect to InfluxDB:

#define WIFI_SSID "Your_WiFi_SSID" // Your WiFi network name
#define WIFI_PASSWORD "Your_WiFi_Password" // Your WiFi password

#define INFLUXDB_URL "http://your-influxdb-server" // InfluxDB server URL
#define INFLUXDB_TOKEN "your-api-token" // API Token from InfluxDB
#define INFLUXDB_ORG "your-organization" // Your InfluxDB organization name
#define INFLUXDB_BUCKET "PMS sensor project" // Your created bucket
  1. Replace the placeholders with your actual WiFi credentials and InfluxDB details.
  2. Upload the code to your ESP32 C3 Mini using the Arduino IDE.
  3. Open the serial monitor to check if the device connects successfully and starts sending data.

Your ESP32 C3 Mini is now connected to InfluxDB and will continuously send sensor data for storage with specified delay in the code.

Displaying InfluxDB Data in Grafana

Grafana_visualize.png
12.png

1. Adding InfluxDB as a Data Source

To retrieve data from InfluxDB in Grafana, you first need to add it as a data source:

  1. Open Grafana and log in.
  2. Click on the Settings (⚙️) icon in the left menu.
  3. Select Data Sources.
  4. Click the + Add data source button.
  5. From the list of available data sources, select InfluxDB.

2. Configuring the InfluxDB Connection

Once InfluxDB is selected, configure its connection settings in Grafana.

Basic Settings

  1. Name: Enter a descriptive name such as PMS sensor project.
  2. Query Language: Select Flux (recommended for InfluxDB 2.0 and later).

HTTP Settings

  1. URL: Enter your InfluxDB instance URL.
  2. Example: https://us-east-1-1.aws.cloud2.influxdata.com
  3. The exact URL depends on your InfluxDB cloud region. You can find this in your InfluxDB dashboard.
  4. Enable Basic Authentication
  5. Toggle Basic auth to ON.

Basic Auth Details

  1. User: Enter your InfluxDB account email (e.g., your-email@example.com).
  2. Password: Enter your InfluxDB account password.

InfluxDB Details

  1. Organization: Enter your InfluxDB organization name.
  2. Token: Paste the API Token generated from InfluxDB.

After filling in the details, click Save & Test to verify the connection. If successful, Grafana will confirm the data source is working.

3. Creating a Dashboard and Visualizing Data

  1. In Grafana, go to the Dashboards section.
  2. Click + Create → New Dashboard.
  3. Click + Add a new panel to create a visualization.
  4. In the Query Editor, select InfluxDB as the data source.
  5. Use Flux queries to filter and display data from your PMS sensor project bucket.
  6. Choose a visualization type (e.g., Graph, Gauge, Table) and customize it as needed.
  7. Click Save to store your dashboard.

The finished dashboard layout is shown in the picture above. Simply copy the FLUX queries and paste them to set up your dashboard.

Link to FLUX queries: LINK

PCB & 3D Printed Case

Airforecast_device.jpeg
AirForecast_device1.jpeg
PCB_bottom.png
PCB_top.png

The PCB files for this project are available on my GitHub, so you can download them and easily order a board from JLCPCB or any other manufacturer. Using a custom PCB makes the whole setup much neater and more reliable compared to a breadboard with loose wires. It keeps everything well-organized, reduces the risk of connection issues, and fits perfectly inside the enclosure.

For the enclosure, I 3D printed it in white PLA. I went with white not just because it looks clean and minimal, but also because it allows the AQI color indicators to shine through the material. This way, you can see the air quality status at a glance without needing a separate display or extra cutouts for LEDs. The design also includes ventilation for the sensors.