#define BLYNK_TEMPLATE_ID "TMPL4iwlB_40u"
#define BLYNK_TEMPLATE_NAME "MULTI GAS DETECTION SYSTEM SIMULATION"
#define BLYNK_AUTH_TOKEN "Sdpjkk52g8BeIzZ0UyckYwN7ebjOquU-"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// -------- WiFi --------
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// -------- OLED --------
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// -------- Pins --------
#define MQ2_PIN 34
#define MQ7_PIN 35
#define MQ135_PIN 33
#define DHT_PIN 4
#define DHTTYPE DHT22
DHT dht(DHT_PIN, DHTTYPE);
// -------- Kalman Filter --------
class KalmanFilter {
public:
float Q, R, X, P, K;
KalmanFilter(float q, float r, float initVal) {
Q = q; R = r; X = initVal; P = 1;
}
float update(float m) {
P += Q;
K = P / (P + R);
X = X + K * (m - X);
P = (1 - K) * P;
return X;
}
};
// Filters
KalmanFilter mq2F(0.1, 10, 1000);
KalmanFilter mq7F(0.1, 10, 1000);
KalmanFilter mq135F(0.1, 10, 2000);
// -------- Alert Flags --------
bool smokeAlert = false;
bool coAlert = false;
bool co2Alert = false;
// -------- Timer --------
BlynkTimer timer;
// -------- Data Function --------
void sendData() {
float mq2 = mq2F.update(analogRead(MQ2_PIN));
float mq7 = mq7F.update(analogRead(MQ7_PIN));
float mq135 = mq135F.update(analogRead(MQ135_PIN));
float mq2P = (mq2 / 4095.0) * 100;
float mq7P = (mq7 / 4095.0) * 100;
float mq135P = (mq135 / 4095.0) * 100;
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (isnan(temp) || isnan(hum)) return;
// -------- Send to Blynk --------
Blynk.virtualWrite(V0, mq2P);
Blynk.virtualWrite(V1, mq7P);
Blynk.virtualWrite(V2, mq135P);
Blynk.virtualWrite(V3, temp);
Blynk.virtualWrite(V4, hum);
// -------- ALERTS --------
if (mq2P > 50 && !smokeAlert) {
Blynk.logEvent("gas_alert", "Smoke Detected");
smokeAlert = true;
}
if (mq2P < 50) smokeAlert = false;
if (mq7P > 60 && !coAlert) {
Blynk.logEvent("gas_alert", "Carbon monoxide detected");
coAlert = true;
}
if (mq7P < 60) coAlert = false;
if (mq135P > 60 && !co2Alert) {
Blynk.logEvent("gas_alert", "Carbon dioxide detected");
co2Alert = true;
}
if (mq135P < 60) co2Alert = false;
// -------- OLED --------
display.clearDisplay();
display.setCursor(0, 0);
display.println("Gas Monitor");
display.setCursor(0, 10);
display.print("T:");
display.print(temp, 1);
display.print("C H:");
display.print(hum, 0);
display.println("%");
display.setCursor(0, 25);
display.print("MQ2:");
display.print(mq2P, 1);
display.setCursor(0, 35);
display.print("MQ7:");
display.print(mq7P, 1);
display.setCursor(0, 45);
display.print("MQ135:");
display.print(mq135P, 1);
display.display();
// -------- SERIAL MONITOR OUTPUT --------
Serial.println("------ GAS READINGS ------");
Serial.print("MQ-2 (Smoke): "); Serial.print(mq2P); Serial.println(" %");
Serial.print("MQ-7 (CO): "); Serial.print(mq7P); Serial.println(" %");
Serial.print("MQ-135 (Air): "); Serial.print(mq135P); Serial.println(" %");
Serial.print("Temperature: "); Serial.print(temp); Serial.println(" C");
Serial.print("Humidity: "); Serial.print(hum); Serial.println(" %");
Serial.println("---------------------------\n");
}
// -------- Setup --------
void setup() {
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
dht.begin();
// WiFi connect (only once)
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
Blynk.config(BLYNK_AUTH_TOKEN);
Blynk.connect();
timer.setInterval(1000L, sendData);
}
// -------- Loop --------
void loop() {
if (Blynk.connected()) {
Blynk.run();
}
timer.run();
}