// ============================================================
// Smart Home Fire & Gas Safety System (FINAL FIXED VERSION)
// ============================================================
#include <WiFi.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
// ---------------- PINS ----------------
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define GAS_PIN 34
#define RED_LED_PIN 25
#define GREEN_LED_PIN 26
#define BUZZER_PIN 27
// ---------------- LCD ----------------
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ---------------- WIFI ----------------
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
// ---------------- GAS CALIBRATION ----------------
// Wokwi MQ2 behaves like:
// Clean air ≈ 3000 ADC
// Max gas ≈ 4095 ADC
#define GAS_BASELINE 3000
#define GAS_MAX 4095
// ---------------- THRESHOLDS ----------------
const int GAS_WARNING = 400;
const int GAS_DANGER = 700;
// ---------------- STATES ----------------
unsigned long lastBlink = 0;
unsigned long lastBeep = 0;
bool ledState = false;
bool buzzerState = false;
DHT dht(DHT_PIN, DHT_TYPE);
// ============================================================
// SETUP
// ============================================================
void setup() {
digitalWrite(25, HIGH); // turn red ON
delay(2000);
digitalWrite(25, LOW);
digitalWrite(26, HIGH); // turn green ON
delay(2000);
digitalWrite(26, LOW);
Serial.begin(115200);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(BUZZER_PIN, LOW);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("System Starting");
delay(1500);
lcd.clear();
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
// ============================================================
// LOOP
// ============================================================
void loop() {
float temp = dht.readTemperature();
float hum = dht.readHumidity();
// -------- GAS FIXED CALIBRATION --------
int rawADC = analogRead(GAS_PIN);
int gasPPM = map(rawADC, GAS_BASELINE, GAS_MAX, 0, 1000);
gasPPM = constrain(gasPPM, 0, 1000);
// -------- CLASSIFICATION --------
String status = classify(gasPPM);
// -------- OUTPUT --------
triggerAlert(status);
updateLCD(temp, hum, gasPPM, status);
// Debug (important for report)
Serial.print("RAW: "); Serial.print(rawADC);
Serial.print(" | PPM: "); Serial.print(gasPPM);
Serial.print(" | Status: "); Serial.println(status);
delay(100);
}
// ============================================================
// CLASSIFICATION
// ============================================================
String classify(int gas) {
if (gas >= GAS_DANGER) return "DANGER";
else if (gas >= GAS_WARNING) return "WARNING";
else return "SAFE";
}
// ============================================================
// ALERT SYSTEM (STABLE + NON-BLOCKING)
// ============================================================
void triggerAlert(String status) {
unsigned long now = millis();
static String lastStatus = "";
// Reset states when status changes
if (status != lastStatus) {
lastStatus = status;
ledState = false;
buzzerState = false;
lastBlink = now;
lastBeep = now;
}
if (status == "DANGER") {
// Fast blink (200ms)
if (now - lastBlink >= 200) {
lastBlink = now;
ledState = !ledState;
digitalWrite(RED_LED_PIN, ledState);
}
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(BUZZER_PIN, HIGH);
}
else if (status == "WARNING") {
digitalWrite(RED_LED_PIN, HIGH);
digitalWrite(GREEN_LED_PIN, LOW);
// Slow beep
if (now - lastBeep >= 800) {
lastBeep = now;
buzzerState = !buzzerState;
digitalWrite(BUZZER_PIN, buzzerState);
}
}
else {
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(BUZZER_PIN, LOW);
}
}
// ============================================================
// LCD DISPLAY (NO FLICKER)
// ============================================================
void updateLCD(float t, float h, int gas, String status) {
static int lastGas = -1;
if (gas == lastGas) return;
lastGas = gas;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T:");
lcd.print(t,1);
lcd.print("C H:");
lcd.print((int)h);
lcd.setCursor(0,1);
lcd.print("G:");
lcd.print(gas);
lcd.setCursor(8,1);
lcd.print(status);
}