The plan is solid. Let's skip the meta-discussion about page counts, skip the preambles, and start building Volume 1 of your engineering documentation directly.
Here is the complete initial architectural blueprint, high-level system overview, and hardware schematics to establish the foundation of your project.
1. Executive Project Abstract
The AI-Powered Air Pollution Monitoring and Prediction System is an end-to-end Agentic IoT ecosystem designed to sense, analyze, log, and forecast microclimate air quality parameters in real time. Built around an ESP32 microcontroller, the edge node samples particulate matter ($\text{PM}_{2.5}, \text{PM}_{10}$ via PMS5003), hazardous gases ($\text{CO}_2, \text{NH}_3, \text{NO}_x$, VOCs via MQ135), environmental parameters (temperature and humidity via DHT22, barometric pressure via BMP280), and spatial coordinates (via NEO-6M GPS).
Data is transmitted concurrently via dual protocols: HTTP/REST to a ThingSpeak cloud dashboard for real-time visualization, and Webhooks to an n8n orchestration server. The n8n engine feeds an AI Agent (combining localized feature engineering with LLM/ML prediction logic) to predict next-hour AQI trends, optimize fan actuator power cycles, evaluate health risks, and dynamically synthesize localized voice alert notifications pushed directly to users via Telegram.
2. System Hardware Architecture & Bill of Materials
Bill of Materials (BOM)
| Component | Part / Model | Quantity | Operational Voltage | Function |
| Microcontroller | ESP32 DevKit V1 (30-pin) | 1 | 3.3V / 5V USB | Core processing, Wi-Fi stack, sensor sampling |
| PM Sensor | PMS5003 (Plantower) | 1 | 5V (3.3V Logic TX/RX) | Laser scattering for $\text{PM}_{1.0}, \text{PM}_{2.5}, \text{PM}_{10}$ |
| Gas Sensor | MQ135 Breakout | 1 | 5V (Analog Out 0-3.3V) | Air quality ($\text{NH}_3$, $\text{NO}_x$, Alcohol, Benzene, Smoke, $\text{CO}_2$) |
| Temp/Humidity | DHT22 (AM2302) | 1 | 3.3V | Ambient temperature and relative humidity |
| Baro Pressure | BMP280 (I2C) | 1 | 3.3V | Atmospheric pressure and altitude estimation |
| Location Tracking | NEO-6M GPS Module | 1 | 3.3V / 5V (UART TX/RX) | Geospatial tagging (Latitude, Longitude, Altitude) |
| Display | 0.96" SSD1306 OLED | 1 | 3.3V (I2C) | Local real-time telemetry display |
| Actuator | 5V Single-Channel Relay | 1 | 5V (Signal 3.3V compatible) | Drives high-volume air purification fan |
| Audio Alert | 5V Active Buzzer | 1 | 3.3V / 5V | Local acoustic alarm on critical AQI threshold |
| Visual Indicator | 4-Pin Common Cathode RGB LED | 1 | 3.3V (via $220\,\Omega$ Resistors) | Local visual AQI status (Green/Yellow/Red) |
| Power Supply | 5V 2A DC Adapter | 1 | 110-240V AC to 5V DC | Regulated system power source |
3. Comprehensive Circuit Pin Mapping
The pinouts below align with standard ESP32 30-pin DevKit V1 boards:
| ESP32 GPIO | Connected Component | Module Pin | Protocol / Signal Type |
| GPIO 21 | SSD1306 OLED & BMP280 | SDA | I2C Data Line (Shared) |
| GPIO 22 | SSD1306 OLED & BMP280 | SCL | I2C Clock Line (Shared) |
| GPIO 16 (RX2) | PMS5003 | TX | UART2 Receive |
| GPIO 17 (TX2) | PMS5003 | RX | UART2 Transmit |
| GPIO 4 (RX1) | NEO-6M GPS | TX | UART1 Receive |
| GPIO 2 (TX1) | NEO-6M GPS | RX | UART1 Transmit |
| GPIO 15 | DHT22 | DATA | Single-Bus Digital (Requires $10\,\text{k}\Omega$ Pull-up) |
| GPIO 34 (VP) | MQ135 | AOUT | Analog Input (Input-only, no internal pull-ups) |
| GPIO 18 | 5V Relay Module | IN | Digital Output (High = Relay ON) |
| GPIO 19 | Active Buzzer | VCC / SIG | Digital Output (High = Sound Alarm) |
| GPIO 25 | RGB LED | Red Pin | PWM Output (AQI Alert Level) |
| GPIO 26 | RGB LED | Green Pin | PWM Output (AQI Alert Level) |
| GPIO 27 | RGB LED | Blue Pin | PWM Output (AQI Alert Level) |
4. Hardware System Block Diagram
+-------------------------------------------------------------+
| 5V 2A POWER SUPPLY |
+------------------------------+------------------------------+
|
v
+----------------------------------------------+----------------------------------------------+
| ESP32 DEVKIT V1 |
| |
| [UART 1] <---> NEO-6M GPS Module (Geospatial Tagging) |
| [UART 2] <---> PMS5003 Laser Sensor (PM1.0 / PM2.5 / PM10) |
| [I2C] <---> SSD1306 OLED (0.96") + BMP280 Barometric Sensor |
| [GPIO 15] <---> DHT22 (Temperature & Humidity) |
| [GPIO 34] <--- MQ135 Gas Sensor (Analog Raw AQI Signal) |
| |
| [GPIO 18] ---> 5V Relay Output (Exhaust / Fan Control) |
| [GPIO 19] ---> Active Acoustic Buzzer |
| [GPIO 25-27]--> PWM RGB LED Indicator |
+----------------------------------------------+----------------------------------------------+
|
Wi-Fi Dual-Channel Outbound
|
+------------------------+------------------------+
| |
v v
+------------------------+ +------------------------+
| THINGSPEAK CLOUD | | n8n ENGINE |
| Real-time Telemetry & | | Workflow Automation & |
| Analytics Dashboard | | Agentic Processing |
+------------------------+ +-----------+------------+
|
+----------------------+----------------------+
| | |
v v v
+--------------------+ +-------------------+ +--------------------+
| GOOGLE SHEETS | | TELEGRAM BOT | | AI PREDICTION |
| Historical Logger | | Text & Voice | | Power & AQI Model |
+--------------------+ +-------------------+ +--------------------+
5. End-to-End System Processing Flowchart
[ START ]
|
v
[ Initialize Hardware ]
(I2C, UART1, UART2, GPIOs, OLED)
|
v
[ Connect to Wi-Fi ] <--- (Retry Loop if disconnected)
|
v
[ Read Sensor Array ]
- PMS5003 (PM2.5 / PM10)
- MQ135 (Gas Level)
- DHT22 (Temp / Humidity)
- BMP280 (Pressure)
- NEO-6M (GPS Lat / Long)
|
v
[ Compute Air Quality Index (AQI) ]
(Calculate Sub-Indices using US EPA / CPCB formulas)
|
v
[ Update OLED Screen & RGB Status ]
|
+----------------------------------+
| |
v v
[ Local Threshold Check ] [ Transmit Telemetry ]
- If AQI > 200: - POST Payload to ThingSpeak
* Turn ON Relay (Fan) - Trigger n8n Webhook Endpoint
* Sound Buzzer Alarm
- Else:
* Keep Relay/Buzzer OFF
| |
+----------------------------------+
|
v
[ n8n Automation Engine ]
|
+------------------------+------------------------+
| | |
v v v
[ Append Raw Record ] [ Execute AI Agent ] [ Evaluate Risk & Alerts ]
(Google Sheets API) - Predict 1-hr AQI - Is Voice Alert Needed?
- Compute Fan Power - Generate Audio via TTS
Optimization - Post Voice/Text Payload
to Telegram Channel
|
v
[ END / WAIT ]
(Interval Delay ~15s)
6. Base ESP32 Sensor Reading & Transmission Firmware Blueprint
Below is the core firmware skeleton handling multi-UART sensor reading, AQI calculations, local display updates, relay management, and dual-cloud logging.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP280.h>
#include <DHT.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// Screen Config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Sensor Pins & Config
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP280 bmp; // I2C
#define MQ135_PIN 34
#define RELAY_PIN 18
#define BUZZER_PIN 19
#define RGB_R_PIN 25
#define RGB_G_PIN 26
#define RGB_B_PIN 27
// Hardware Serial 2 for PMS5003
#define RXD2 16
#define TXD2 17
// Wi-Fi and API Configuration
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* THINGSPEAK_URL = "http://api.thingspeak.com/update";
const char* THINGSPEAK_API_KEY = "YOUR_THINGSPEAK_WRITE_KEY";
const char* N8N_WEBHOOK_URL = "http://YOUR_N8N_INSTANCE_IP:5678/webhook/air-quality-data";
// Telemetry Storage Struct
struct AirData {
float pm25 = 0.0;
float pm10 = 0.0;
float temp = 0.0;
float hum = 0.0;
float pressure = 0.0;
int rawGas = 0;
int calculatedAQI = 0;
};
AirData currentData;
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // PMS5003
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RGB_R_PIN, OUTPUT);
pinMode(RGB_G_PIN, OUTPUT);
pinMode(RGB_B_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
// Initialize Wire & Displays
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Initializing System...");
display.display();
dht.begin();
if (!bmp.begin(0x76)) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
}
// Connect Wi-Fi
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi Connected!");
}
void readPMS5003(float &pm25, float &pm10) {
if (Serial2.available() >= 32) {
if (Serial2.read() == 0x42 && Serial2.read() == 0x4D) {
uint8_t buffer[30];
Serial2.readBytes(buffer, 30);
pm25 = (float)((buffer[4] << 8) | buffer[5]);
pm10 = (float)((buffer[6] << 8) | buffer[7]);
}
}
}
int calculateSimpleAQI(float pm25) {
// Simplified linear scale for demonstration
if (pm25 <= 12.0) return (int)((50.0 / 12.0) * pm25);
else if (pm25 <= 35.4) return (int)(51 + ((49.0 / 23.4) * (pm25 - 12.1)));
else if (pm25 <= 55.4) return (int)(101 + ((49.0 / 19.9) * (pm25 - 35.5)));
else if (pm25 <= 150.4) return (int)(151 + ((49.0 / 94.9) * (pm25 - 55.5)));
else return 201; // Poor / Critical
}
void updateLEDs(int aqi) {
if (aqi <= 50) { // Green
analogWrite(RGB_R_PIN, 0); analogWrite(RGB_G_PIN, 255); analogWrite(RGB_B_PIN, 0);
} else if (aqi <= 100) { // Yellow
analogWrite(RGB_R_PIN, 255); analogWrite(RGB_G_PIN, 255); analogWrite(RGB_B_PIN, 0);
} else { // Red
analogWrite(RGB_R_PIN, 255); analogWrite(RGB_G_PIN, 0); analogWrite(RGB_B_PIN, 0);
}
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.printf("AQI: %d\n", currentData.calculatedAQI);
display.printf("PM2.5: %.1f ug/m3\n", currentData.pm25);
display.printf("PM10: %.1f ug/m3\n", currentData.pm10);
display.printf("Temp: %.1f C\n", currentData.temp);
display.printf("Hum: %.1f %%\n", currentData.hum);
display.printf("Press: %.1f hPa\n", currentData.pressure);
display.display();
}
void sendTelemetry() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// 1. Post to ThingSpeak
String tsUrl = String(THINGSPEAK_URL) + "?api_key=" + THINGSPEAK_API_KEY +
"&field1=" + String(currentData.calculatedAQI) +
"&field2=" + String(currentData.pm25) +
"&field3=" + String(currentData.pm10) +
"&field4=" + String(currentData.temp) +
"&field5=" + String(currentData.hum) +
"&field6=" + String(currentData.pressure);
http.begin(tsUrl);
http.GET();
http.end();
// 2. Post JSON Payload to n8n Webhook
http.begin(N8N_WEBHOOK_URL);
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<256> doc;
doc["aqi"] = currentData.calculatedAQI;
doc["pm25"] = currentData.pm25;
doc["pm10"] = currentData.pm10;
doc["temp"] = currentData.temp;
doc["humidity"] = currentData.hum;
doc["pressure"] = currentData.pressure;
doc["raw_gas"] = currentData.rawGas;
String jsonString;
serializeJson(doc, jsonString);
http.POST(jsonString);
http.end();
}
}
void loop() {
readPMS5003(currentData.pm25, currentData.pm10);
currentData.temp = dht.readTemperature();
currentData.hum = dht.readHumidity();
currentData.pressure = bmp.readPressure() / 100.0F; // Convert Pa to hPa
currentData.rawGas = analogRead(MQ135_PIN);
currentData.calculatedAQI = calculateSimpleAQI(currentData.pm25);
updateLEDs(currentData.calculatedAQI);
updateDisplay();
// Actuator Safety Logic
if (currentData.calculatedAQI > 150) {
digitalWrite(RELAY_PIN, HIGH); // Turn on exhaust/filter
digitalWrite(BUZZER_PIN, HIGH); // Alarm active
} else {
digitalWrite(RELAY_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
}
sendTelemetry();
delay(15000); // 15-second interval
}
7. Next Architectural Steps
With Volume 1 established, we can delve into any specific volume or module you need to focus on next:
-
n8n Automation Architecture & Webhook Integration: Complete JSON schema, node connection map, Google Sheets logging node, and dynamic Telegram voice message generation (using ElevenLabs/OpenAI TTS API).
-
AI Modeling & Predictive Algorithms: Mathematical formulation for AQI forecasting, fan power optimization algorithms, and feature engineering code.
-
ThingSpeak & Dashboard Configuration: Field mapping, MATLAB analytics scripts for historical analysis, and alert triggers.
Where would you like to direct the next deep dive?

No comments:
Post a Comment