#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Change this to use Blynk
// Since we cant use it in wokwi, it will show error
#define USE_BLYNK 1
#if USE_BLYNK
#define BLYNK_TEMPLATE_ID "BLYNK_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Wokwi"
#define BLYNK_AUTH_TOKEN "BLYNK_AUTH_TOKEN"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
// don't change the ssid and pass as they are the default for wokwi
// for doing this on your own machine, change it to match the ssid and password
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
#endif
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int PIN_LED_G = 0; // Green LED
const int PIN_LED_R = 2; // Red LED
const int PIN_MQ2 = 34; // MQ-2 sensor analog pin
const int PIN_BUZZER = 3; // Buzzer pin
const int PIN_SWITCH = 4; // Reset button pin
const int HIGH_THRESHOLD = 2000;
bool alarmLatched = false;
bool previousState = alarmLatched;
int previousLevel = 0;
#if USE_BLYNK
BLYNK_WRITE(V0) {
if (param.asInt() == 1) {
resetAlarm();
Blynk.virtualWrite(V0, 0);
}
}
#endif
void resetAlarm() {
alarmLatched = false;
digitalWrite(PIN_BUZZER, LOW);
digitalWrite(PIN_LED_G, HIGH);
digitalWrite(PIN_LED_R, LOW);
#if USE_BLYNK
Blynk.virtualWrite(V1, 0);
#endif
Serial.println("Alarm reset.");
lcd.setCursor(0, 1);
lcd.print(" ");
}
void checkSwitch() {
if (!alarmLatched) return;
if (digitalRead(PIN_SWITCH) == LOW) {
resetAlarm();
}
}
void setup() {
Serial.begin(115200);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_SWITCH, INPUT_PULLUP);
lcd.init();
lcd.backlight();
digitalWrite(PIN_LED_G, HIGH);
digitalWrite(PIN_LED_R, LOW);
digitalWrite(PIN_BUZZER, LOW);
#if USE_BLYNK
Serial.println("Connecting to Wi-Fi & Blynk...");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
#else
Serial.println("Running in OFFLINE mode");
#endif
}
void loop() {
#if USE_BLYNK
Blynk.run();
#endif
int gas = analogRead(PIN_MQ2);
#if USE_BLYNK
Blynk.virtualWrite(V2, gas);
#endif
Serial.print("Gas Level: ");
Serial.println(gas);
#if USE_BLYNK
Blynk.virtualWrite(V0, gas);
#endif
if (!alarmLatched && gas >= HIGH_THRESHOLD) {
alarmLatched = true;
digitalWrite(PIN_LED_G, LOW);
digitalWrite(PIN_LED_R, HIGH);
digitalWrite(PIN_BUZZER, HIGH);
Serial.println("⚠️ High Gas Level Detected! Alarm Triggered.");
#if USE_BLYNK
Blynk.virtualWrite(V1, 1);
Blynk.logEvent("gas_alert", String("High gas level: ") + gas);
#endif
}
if (!alarmLatched) {
digitalWrite(PIN_LED_G, HIGH);
digitalWrite(PIN_LED_R, LOW);
digitalWrite(PIN_BUZZER, LOW);
}
if (gas != previousLevel) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Gas:");
lcd.print(gas);
}
if (alarmLatched) {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("!!! WARNING !!!");
checkSwitch();
}
else {
lcd.setCursor(0, 1);
lcd.print("Safe");
}
previousLevel = gas;
previousState = alarmLatched;
delay(500);
}