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



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


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:
- Temperature from -40°C to 85°C with an accuracy of ±1.0°C
- Humidity from 0% to 100% with an accuracy of ±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.
Soldering & Schematics




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
- VCC → 3.3V on ESP32
- GND → GND on ESP32
- SCL → GPIO7 on ESP32
- SDA → GPIO6 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.
- VCC → 5V on ESP32
- GND → GND on ESP32
- TX → RX (GPIO20) on ESP32
- 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.
- VCC → 5V on ESP32
- GND → GND on ESP32
- 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



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:
- Go to InfluxDB Cloud and sign up or log in.
- In the left-hand menu, navigate to Load Data → Buckets.
- Click + CREATE BUCKET to add a new data storage container.
- Enter a name for the bucket, such as PMS sensor project.
- Set a retention period (e.g., 30 days) to define how long data will be stored.
- 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:
- Go to Load Data → API Tokens in the left menu.
- Click + Generate API Token to create a new access key.
- Choose either All Access Token (for full control) or Custom Token (to set specific permissions).
- If using a Custom Token, grant Read & Write access for your bucket.
- 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:
- Replace the placeholders with your actual WiFi credentials and InfluxDB details.
- Upload the code to your ESP32 C3 Mini using the Arduino IDE.
- 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


1. Adding InfluxDB as a Data Source
To retrieve data from InfluxDB in Grafana, you first need to add it as a data source:
- Open Grafana and log in.
- Click on the Settings (⚙️) icon in the left menu.
- Select Data Sources.
- Click the + Add data source button.
- 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
- Name: Enter a descriptive name such as PMS sensor project.
- Query Language: Select Flux (recommended for InfluxDB 2.0 and later).
HTTP Settings
- URL: Enter your InfluxDB instance URL.
- Example: https://us-east-1-1.aws.cloud2.influxdata.com
- The exact URL depends on your InfluxDB cloud region. You can find this in your InfluxDB dashboard.
- Enable Basic Authentication
- Toggle Basic auth to ON.
Basic Auth Details
- User: Enter your InfluxDB account email (e.g., your-email@example.com).
- Password: Enter your InfluxDB account password.
InfluxDB Details
- Organization: Enter your InfluxDB organization name.
- 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
- In Grafana, go to the Dashboards section.
- Click + Create → New Dashboard.
- Click + Add a new panel to create a visualization.
- In the Query Editor, select InfluxDB as the data source.
- Use Flux queries to filter and display data from your PMS sensor project bucket.
- Choose a visualization type (e.g., Graph, Gauge, Table) and customize it as needed.
- 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




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.