// Include necessary libraries
#include <Wire.h> // Required for I2C communication (for LCD)
#include <LiquidCrystal_I2C.h> // Required for I2C LCD
#include <DHT.h> // Required for DHT sensor
// --- Pin Definitions ---
// DHT22 Sensor
#define DHTPIN 21 // DHT22 data pin connected to ESP32 GPIO 21
#define DHTTYPE DHT22 // Define sensor type as DHT22
// MQ-2 Gas Sensor
const int MQ2_ANALOG_PIN = 34; // MQ-2 AOUT pin connected to ESP32 GPIO 34 (analog input)
const int MQ2_DIGITAL_PIN = 35; // MQ-2 DOUT pin connected to ESP32 GPIO 35 (digital input)
// Buzzer
const int BUZZER_PIN = 2; // Buzzer connected to ESP32 GPIO 2
// LDR Sensor (Fire Sensor Module)
const int LDR_ANALOG_PIN = 36; // LDR module's AOUT pin connected to ESP32 GPIO 36 (analog input)
const int LDR_DIGITAL_PIN = 14; // LDR module's DOUT pin connected to ESP32 GPIO 14 (digital input)
// IMPORTANT: In the image, this LDR DOUT is connected to GPIO 14.
// LCD 16x2 I2C
// SDA is connected to ESP32 GPIO 21
// SCL is connected to ESP32 GPIO 22
// Adjust I2C address if necessary (0x27 or 0x3F are common)
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// --- Global Variables ---
float temperature_c;
float humidity;
int mq2_analog_value;
int mq2_digital_value;
int ldr_analog_value;
int ldr_digital_value;
// --- Thresholds (Adjust these based on your needs) ---
const float TEMPERATURE_THRESHOLD = 30.0; // degrees Celsius
const float HUMIDITY_THRESHOLD = 80.0; // percent
const int MQ2_ANALOG_THRESHOLD = 1500; // Adjust based on calibration (0-4095 for ESP32)
// A higher value indicates more gas
const int LDR_ANALOG_THRESHOLD = 2000; // Adjust based on light conditions.
// For fire detection, usually a *lower* value (more light = less resistance = higher analog reading)
// or you might look for a sudden *drop* if it's detecting smoke blocking light.
// For direct flame detection, a *high* value is expected from an LDR if there's sudden bright light.
// The digital output (DOUT) is typically easier for fire detection.
void setup() {
Serial.begin(115200); // Start serial communication for debugging
// Initialize DHT sensor
dht.begin();
// Initialize LCD
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
lcd.print("Circuit Initializing...");
lcd.setCursor(0, 1);
lcd.print("Please wait...");
delay(2000);
lcd.clear();
// Set pin modes
pinMode(BUZZER_PIN, OUTPUT);
pinMode(MQ2_DIGITAL_PIN, INPUT); // MQ-2 digital output
pinMode(LDR_DIGITAL_PIN, INPUT); // LDR module digital output
}
void loop() {
// --- Read Sensors ---
// Read DHT22 sensor
humidity = dht.readHumidity();
temperature_c = dht.readTemperature(); // Read temperature in Celsius
// Check if any reads failed
if (isnan(humidity) || isnan(temperature_c)) {
Serial.println("Failed to read from DHT sensor!");
lcd.clear();
lcd.print("DHT Read Error!");
lcd.setCursor(0, 1);
lcd.print("Retrying...");
delay(2000);
} else {
// Read MQ-2 gas sensor
mq2_analog_value = analogRead(MQ2_ANALOG_PIN);
mq2_digital_value = digitalRead(MQ2_DIGITAL_PIN); // Will be HIGH if gas detected (above threshold)
// Read LDR Sensor (Fire Sensor Module)
ldr_analog_value = analogRead(LDR_ANALOG_PIN);
ldr_digital_value = digitalRead(LDR_DIGITAL_PIN); // This will be HIGH or LOW based on the module's sensitivity potentiometer
// --- Display on LCD ---
lcd.clear();
lcd.print("Temp: ");
lcd.print(temperature_c);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Hum: ");
lcd.print(humidity);
lcd.print(" %");
delay(2000); // Display for 2 seconds
lcd.clear();
lcd.print("MQ2 A: ");
lcd.print(mq2_analog_value);
lcd.setCursor(0, 1);
lcd.print("MQ2 D: ");
if (mq2_digital_value == HIGH) {
lcd.print("GAS DETECTED!");
} else {
lcd.print("Normal");
}
delay(2000); // Display for 2 seconds
lcd.clear();
lcd.print("LDR A: ");
lcd.print(ldr_analog_value);
lcd.setCursor(0, 1);
lcd.print("LDR D: ");
if (ldr_digital_value == HIGH) { // Assuming HIGH indicates light (fire) detection
lcd.print("FIRE DETECTED!");
} else {
lcd.print("Normal Light");
}
// Note: The digital output of LDR modules is often HIGH when light is detected,
// but check your specific module's behavior. If it's LOW on detection, reverse the logic.
// --- Serial Debugging ---
Serial.print("Temperature: ");
Serial.print(temperature_c);
Serial.print(" *C, Humidity: ");
Serial.print(humidity);
Serial.print(" %\n");
Serial.print("MQ2 Analog: ");
Serial.print(mq2_analog_value);
Serial.print(", MQ2 Digital: ");
Serial.println(mq2_digital_value == HIGH ? "Gas Detected" : "Normal");
Serial.print("LDR Analog: ");
Serial.print(ldr_analog_value);
Serial.print(", LDR Digital: ");
Serial.println(ldr_digital_value == HIGH ? "Fire Detected (Light)" : "Normal Light");
// --- Alarms/Actions (Based on thresholds) ---
// Buzzer for high temperature
if (temperature_c > TEMPERATURE_THRESHOLD) {
Serial.println("ALERT: High Temperature!");
tone(BUZZER_PIN, 1000); // Play a tone at 1000 Hz
delay(500);
noTone(BUZZER_PIN);
delay(500);
}
// Buzzer for gas detection (using digital output for simplicity)
if (mq2_digital_value == HIGH) {
Serial.println("ALERT: Gas Detected!");
tone(BUZZER_PIN, 2000); // Play a tone at 2000 Hz
delay(1000);
noTone(BUZZER_PIN);
}
// Buzzer for fire detection (using LDR digital output)
if (ldr_digital_value == HIGH) { // Assuming HIGH indicates fire detection
Serial.println("ALERT: FIRE Detected!");
tone(BUZZER_PIN, 3000); // Play a distinct tone for fire
delay(1500); // Longer alert
noTone(BUZZER_PIN);
}
// You could also use the analog value for more granular control:
// if (ldr_analog_value > LDR_ANALOG_THRESHOLD) { ... } // If brighter means fire
// OR if (ldr_analog_value < LDR_ANALOG_THRESHOLD_DARKNESS) { ... } // If very dark means smoke/obscured LDR
// Small delay before next loop iteration to prevent sensor overload and stabilize readings
delay(1000);
}
}