#define BLYNK_TEMPLATE_ID "TMPL33CiJ--hj"
#define BLYNK_TEMPLATE_NAME "GasSafetyMonitor"
#define BLYNK_AUTH_TOKEN "y4YWCP9rBwBdtTHou7X6aeRId042OSzu"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C screen(0x27, 16, 2);
#define SENSOR_PIN 34
#define LED_OK 18
#define LED_DANGER 19
#define ALERT_BUZZER 25
#define BTN_RESET 15
char wifi_ssid[] = "Wokwi-GUEST";
char wifi_pass[] = "";
int gasLimit = 2000;
bool warningTriggered = false;
BLYNK_WRITE(V4) {
gasLimit = param.asInt();
screen.setCursor(0, 1);
screen.print("Limit:");
screen.print(gasLimit);
screen.print(" ");
}
void setup() {
pinMode(LED_OK, OUTPUT);
pinMode(LED_DANGER, OUTPUT);
pinMode(ALERT_BUZZER, OUTPUT);
pinMode(BTN_RESET, INPUT_PULLUP);
screen.init();
screen.backlight();
screen.clear();
screen.print("Booting...");
Blynk.begin(BLYNK_AUTH_TOKEN, wifi_ssid, wifi_pass);
digitalWrite(LED_OK, HIGH);
digitalWrite(LED_DANGER, LOW);
digitalWrite(ALERT_BUZZER, LOW);
delay(1000);
screen.clear();
}
void loop() {
Blynk.run();
int gasReading = analogRead(SENSOR_PIN);
Blynk.virtualWrite(V1, gasReading);
screen.setCursor(0, 0);
screen.print("Gas: ");
screen.print(gasReading);
screen.print(" ");
if (gasReading > gasLimit) {
if (!warningTriggered) {
warningTriggered = true;
digitalWrite(LED_OK, LOW);
digitalWrite(LED_DANGER, HIGH);
digitalWrite(ALERT_BUZZER, HIGH);
screen.setCursor(0, 1);
screen.print("!! GAS DETECTED !!");
Blynk.virtualWrite(V2, 1);
Blynk.logEvent("gas_leak", "Gas concentration above threshold!");
}
} else {
if (!warningTriggered) {
digitalWrite(LED_OK, HIGH);
digitalWrite(LED_DANGER, LOW);
digitalWrite(ALERT_BUZZER, LOW);
screen.setCursor(0, 1);
screen.print("Environment Safe ");
Blynk.virtualWrite(V2, 0);
}
}
// --- Manual reset button (always works) ---
if (digitalRead(BTN_RESET) == LOW) {
warningTriggered = false;
digitalWrite(ALERT_BUZZER, LOW);
digitalWrite(LED_DANGER, LOW);
digitalWrite(LED_OK, HIGH);
screen.setCursor(0, 1);
screen.print("System Reset ");
Blynk.virtualWrite(V2, 0);
delay(1000); // Debounce delay
}
delay(300);
}