#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// ---------------- SENSOR PINS ----------------
const int tcrt1 = 2; // Door 1 sensor
const int tcrt2 = 5; // Door 2 sensor
const int buttonPin = 3;
// ---------------- OUTPUTS ----------------
const int buzzer1 = 6;
const int buzzer2 = 7;
const int buzzer3 = 8;
// ---------------- BUZZER FREQUENCIES ----------------
const int freq1 = 1000;
const int freq2 = 1500;
const int freq3 = 2000;
// ---------------- SYSTEM ----------------
bool systemActive = true;
bool lastButtonState = HIGH;
bool failsafeActive = false;
unsigned long previousMillis = 0;
const long buzzerInterval = 500;
int buzzerStep = 0;
// BACKLIGHT CONTROL
unsigned long lastLightDetectedTime = 0;
const unsigned long backlightTimeout = 60000;
// FAILSAFE CONTROL
unsigned long buttonHoldStart = 0;
bool holdingButton = false;
unsigned long failsafeTriggerTime = 0;
// LCD state tracker
int lastDisplayState = -1;
void setup() {
pinMode(tcrt1, INPUT);
pinMode(tcrt2, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buzzer1, OUTPUT);
pinMode(buzzer2, OUTPUT);
pinMode(buzzer3, OUTPUT);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Security System ");
delay(1500);
lcd.clear();
}
void turnBuzzersOff() {
noTone(buzzer1);
noTone(buzzer2);
noTone(buzzer3);
}
void cycleBuzzers() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= buzzerInterval){
previousMillis = currentMillis;
buzzerStep = (buzzerStep + 1) % 3;
turnBuzzersOff();
if(buzzerStep == 0) tone(buzzer1, freq1);
else if(buzzerStep == 1) tone(buzzer2, freq2);
else tone(buzzer3, freq3);
}
}
void loop() {
unsigned long currentMillis = millis();
bool door1 = digitalRead(tcrt1) == HIGH;
bool door2 = digitalRead(tcrt2) == HIGH;
bool bothDoorsOpen = door1 && door2;
bool buttonState = digitalRead(buttonPin);
// -------- FAILSAFE FROM BOTH DOORS --------
if(bothDoorsOpen && !failsafeActive){
failsafeActive = true;
failsafeTriggerTime = currentMillis;
}
// -------- BUTTON HOLD FOR FAILSAFE --------
if(buttonState == LOW){
if(!holdingButton){
holdingButton = true;
buttonHoldStart = currentMillis;
}
if(holdingButton && (currentMillis - buttonHoldStart >= 10000)){
failsafeActive = !failsafeActive;
holdingButton = false;
failsafeTriggerTime = currentMillis;
}
} else {
holdingButton = false;
}
// -------- FAILSAFE MODE --------
if(failsafeActive){
turnBuzzersOff();
if(currentMillis - failsafeTriggerTime >= 2000){
lcd.noBacklight();
lcd.clear();
}
return;
}
// -------- BUTTON TO ARM/DISARM --------
if(buttonState == LOW && lastButtonState == HIGH){
systemActive = !systemActive;
lcd.backlight();
lastLightDetectedTime = currentMillis;
delay(200);
}
lastButtonState = buttonState;
bool doorTriggered = door1 || door2;
if(doorTriggered){
lcd.backlight();
lastLightDetectedTime = currentMillis;
}
if(currentMillis - lastLightDetectedTime >= backlightTimeout){
lcd.noBacklight();
}
// -------- SYSTEM DISARMED --------
if(!systemActive){
turnBuzzersOff();
lcd.setCursor(0,0);
lcd.print(" SYSTEM DISARMED ");
lcd.setCursor(0,1);
lcd.print(" SENSORS OFF ");
lcd.setCursor(0,2);
lcd.print(" Hold 10s = FAILSAFE ");
lcd.setCursor(0,3);
lcd.print(" ");
return;
}
// -------- NO DOOR DETECTED --------
if(!doorTriggered){
turnBuzzersOff();
lcd.setCursor(0,0);
lcd.print(" SECURED ");
lcd.setCursor(0,1);
lcd.print(" All Doors Closed ");
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" System: ARMED ");
}
// -------- DOOR TRIGGERED --------
else{
lcd.setCursor(0,0);
lcd.print("DOOR OPENED ");
lcd.setCursor(0,1);
if(door1 && door2) lcd.print(" BOTH DOORS ALERT ");
else if(door1) lcd.print(" DOOR 1 ");
else if(door2) lcd.print(" DOOR 2 ");
cycleBuzzers();
lcd.setCursor(0,2);
if(buzzerStep == 0) lcd.print("Buzzer 1 ACTIVE ");
else if(buzzerStep == 1) lcd.print("Buzzer 2 ACTIVE ");
else lcd.print("Buzzer 3 ACTIVE ");
lcd.setCursor(0,3);
lcd.print(" System: ARMED ");
}
}