#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Pin Definitions
#define LED 13
#define IR 15
#define BZ 17
#define HT 16
#define MQ 34
#define SER 33
#define FAN1 18 // Servo acting as fan 1
#define FAN2 19 // Servo acting as fan 2
int heatThreshold = 65;
int gasThreshold = 2000;
int irValue = 0;
int mqValue = 0;
float temperatureC = 0;
bool alarmActive = false;
Servo myServo;
Servo fanServo1; // Servo for fan 1
Servo fanServo2; // Servo for fan 2
LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWire(HT);
DallasTemperature DS18B20(&oneWire);
// Servo positions for fan rotation
const int FAN_STOP = 90; // Stop position for continuous rotation servos
const int FAN_FORWARD = 0; // Full speed forward
const int FAN_BACKWARD = 180; // Full speed backward
void setup() {
Serial.begin(115200);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Starting");
// Initialize pins
pinMode(LED, OUTPUT);
pinMode(BZ, OUTPUT);
pinMode(IR, INPUT);
pinMode(MQ, INPUT);
// Allow allocation of all timers for ESP32
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
// Initialize door servo - START WITH DOOR OPEN (180°)
myServo.setPeriodHertz(50); // Standard 50hz servo
myServo.attach(SER, 500, 2400); // Attach servo to pin with min/max pulse width
myServo.write(180); // Door open initially
// Initialize fan servos (continuous rotation servos)
fanServo1.setPeriodHertz(50);
fanServo1.attach(FAN1, 500, 2400);
fanServo1.write(FAN_STOP); // Stop fans initially
fanServo2.setPeriodHertz(50);
fanServo2.attach(FAN2, 500, 2400);
fanServo2.write(FAN_STOP); // Stop fans initially
// Initialize temperature sensor
DS18B20.begin();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Security System");
lcd.setCursor(0, 1);
lcd.print("Door: OPEN");
delay(2000);
lcd.clear();
}
void loop() {
// Read sensors
irValue = digitalRead(IR);
mqValue = analogRead(MQ);
DS18B20.requestTemperatures();
temperatureC = DS18B20.getTempCByIndex(0);
// Handle invalid temperature readings
if (temperatureC == DEVICE_DISCONNECTED_C) {
temperatureC = 0;
}
// Serial monitor output
Serial.print("IR Motion: ");
Serial.print(irValue ? "YES" : "NO");
Serial.print(" | Temp: ");
Serial.print(temperatureC);
Serial.print("C | Gas: ");
Serial.print(mqValue);
Serial.print(" | Alarm: ");
Serial.println(alarmActive ? "ACTIVE" : "INACTIVE");
// Check alarm conditions (HIGH priority - overrides everything)
if (temperatureC > heatThreshold || mqValue > gasThreshold) {
alarmActive = true;
digitalWrite(BZ, HIGH);
digitalWrite(LED, HIGH);
myServo.write(180); // CLOSE door during alarm
// Start fan servos (rotate continuously)
fanServo1.write(FAN_FORWARD);
fanServo2.write(FAN_FORWARD);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALARM ACTIVATED!");
lcd.setCursor(0, 1);
if (temperatureC > heatThreshold) {
lcd.print("High Temp: ");
lcd.print(temperatureC, 1);
lcd.print("C");
} else {
lcd.print("Gas Leak: ");
lcd.print(mqValue);
}
}
else {
alarmActive = false;
digitalWrite(BZ, LOW);
// Stop fan servos
fanServo1.write(FAN_STOP);
fanServo2.write(FAN_STOP);
// NORMAL OPERATION: Motion detection controls door
if (irValue == 1) { // Motion detected
digitalWrite(LED, HIGH);
myServo.write(180); // CLOSE door when motion detected
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Motion Detected!");
lcd.setCursor(0, 1);
lcd.print("Door: OPENED");
} else {
digitalWrite(LED, LOW);
myServo.write(0); // OPEN door when no motion
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Status: Normal");
lcd.setCursor(0, 1);
lcd.print("Door: CLOSED");
}
// Show sensor readings on second line when no alarm
lcd.setCursor(10, 1);
lcd.print("T:");
lcd.print(temperatureC, 1);
lcd.print(" ");
}
delay(1000); // Wait 1 second between readings
}