#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// Pin definitions
#define LDR_PIN 34 // Light sensor (analog)
#define SMOKE_PIN 35 // Smoke sensor (analog)
#define IR_PIN 2 // IR motion sensor (digital)
#define LED_PIN 16 // LED
#define BUZZER_PIN 18 // Buzzer
#define SERVO_PIN 15 // Servo motor
// Keypad setup
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27}; // Keypad row pins
byte colPins[COLS] = {26, 25, 33, 32}; // Keypad column pins
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// I2C LCD (address 0x27, 16 columns, 2 rows)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// System state variables
bool smokeDetected = false;
bool smokeAlarmActive = false;
bool isDark = false;
bool ledOn = false;
bool doorOpen = false;
bool motionDetected = false;
bool motionAlarmActive = false;
// Password system
String correctPassword = "1234";
String enteredPassword = "";
bool passwordMode = false;
unsigned long passwordStartTime = 0;
const unsigned long PASSWORD_TIMEOUT = 10000; // 10 seconds to enter password
// Timing variables
unsigned long doorOpenTime = 0;
unsigned long buzzerStartTime = 0;
unsigned long lastUpdate = 0;
// Constants
const int SMOKE_THRESHOLD = 2000;
const int LIGHT_THRESHOLD = 1500;
const int DOOR_OPEN_DURATION = 5000; // 5 seconds
const int BUZZER_DURATION = 500;
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(IR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize servo
ledcAttach(SERVO_PIN, 50, 12);
setServoAngle(90); // Door closed position
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.print("Smart Home");
lcd.setCursor(0, 1);
lcd.print("System Ready");
delay(2000);
lcd.clear();
Serial.println("Smart Home Security System Started");
Serial.println("Press * to enter password mode");
}
void loop() {
// Read all sensors
readSensors();
// Handle keypad input
handleKeypad();
// Handle smoke detection
handleSmoke();
// Handle light control
handleLighting();
// Handle door control
handleDoor();
// Handle motion detection
handleMotion();
// Update display every 500ms
if (millis() - lastUpdate > 500) {
updateDisplay();
lastUpdate = millis();
}
delay(100);
}
void readSensors() {
// Read smoke sensor
int smokeLevel = analogRead(SMOKE_PIN);
smokeDetected = (smokeLevel > SMOKE_THRESHOLD);
// Read light sensor
int lightLevel = analogRead(LDR_PIN);
isDark = (lightLevel < LIGHT_THRESHOLD);
// Read motion sensor
motionDetected = digitalRead(IR_PIN);
// Debug output
Serial.print("Smoke: "); Serial.print(smokeLevel);
Serial.print(", Light: "); Serial.print(lightLevel);
Serial.print(", Motion: "); Serial.print(motionDetected);
Serial.println();
}
void handleKeypad() {
char key = keypad.getKey();
if (key) {
Serial.print("Key pressed: ");
Serial.println(key);
if (key == '*' && !passwordMode) {
// Start password entry mode
passwordMode = true;
enteredPassword = "";
passwordStartTime = millis();
Serial.println("Password mode activated. Enter 4-digit password:");
} else if (passwordMode) {
if (key == '#') {
// Submit password
checkPassword();
} else if (key == '*') {
// Cancel password entry
passwordMode = false;
enteredPassword = "";
Serial.println("Password entry cancelled");
} else if (enteredPassword.length() < 6) { // Max 6 digits
// Add digit to password
enteredPassword += key;
Serial.print("Password: ");
for (int i = 0; i < enteredPassword.length(); i++) {
Serial.print("*");
}
Serial.println();
}
}
}
// Password timeout
if (passwordMode && (millis() - passwordStartTime > PASSWORD_TIMEOUT)) {
passwordMode = false;
enteredPassword = "";
Serial.println("Password entry timeout");
}
}
void checkPassword() {
if (enteredPassword == correctPassword) {
// Correct password - open door
Serial.println("Password CORRECT! Opening door...");
openDoor();
} else {
// Wrong password
Serial.println("Password INCORRECT!");
// Short error beep
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
}
passwordMode = false;
enteredPassword = "";
}
void openDoor() {
if (!doorOpen) {
doorOpen = true;
doorOpenTime = millis();
setServoAngle(0); // Open position
// Success beep
digitalWrite(BUZZER_PIN, HIGH);
buzzerStartTime = millis();
Serial.println("Door OPENING");
}
}
void handleSmoke() {
if (smokeDetected && !smokeAlarmActive) {
smokeAlarmActive = true;
digitalWrite(BUZZER_PIN, HIGH);
Serial.println("SMOKE DETECTED! Alarm ON");
}
if (!smokeDetected && smokeAlarmActive) {
smokeAlarmActive = false;
digitalWrite(BUZZER_PIN, LOW);
Serial.println("Smoke cleared. Alarm OFF");
}
}
void handleLighting() {
if (isDark && !ledOn) {
ledOn = true;
digitalWrite(LED_PIN, HIGH);
Serial.println("Dark detected. LED ON");
} else if (!isDark && ledOn) {
ledOn = false;
digitalWrite(LED_PIN, LOW);
Serial.println("Light detected. LED OFF");
}
}
void handleDoor() {
// Auto-close door after timeout
if (doorOpen && (millis() - doorOpenTime > DOOR_OPEN_DURATION)) {
doorOpen = false;
setServoAngle(90); // Closed position
// Closing beep
digitalWrite(BUZZER_PIN, HIGH);
buzzerStartTime = millis();
Serial.println("Door CLOSING (auto)");
}
// Turn off buzzer after beep duration
if (millis() - buzzerStartTime > BUZZER_DURATION && !smokeAlarmActive) {
digitalWrite(BUZZER_PIN, LOW);
}
}
void handleMotion() {
if (motionDetected && !doorOpen && !motionAlarmActive) {
motionAlarmActive = true;
Serial.println("MOTION DETECTED! Door is closed - ALARM!");
} else if (!motionDetected && motionAlarmActive) {
motionAlarmActive = false;
Serial.println("Motion stopped. Alarm cleared.");
}
// Motion alarm uses buzzer alternating pattern
if (motionAlarmActive && !smokeAlarmActive) {
static unsigned long lastToggle = 0;
static bool buzzerState = false;
if (millis() - lastToggle > 200) {
buzzerState = !buzzerState;
digitalWrite(BUZZER_PIN, buzzerState);
lastToggle = millis();
}
}
}
void setServoAngle(int angle) {
int pulseWidth = map(angle, 0, 180, 204, 410);
ledcWrite(SERVO_PIN, pulseWidth);
}
void updateDisplay() {
lcd.clear();
// Line 1: Main status or password entry
lcd.setCursor(0, 1);
if (passwordMode) {
lcd.print("Enter Password:");
lcd.setCursor(0, 1);
for (int i = 0; i < enteredPassword.length(); i++) {
lcd.print("*");
}
} else if (smokeAlarmActive) {
lcd.print("SMOKE ALARM!");
} else if (motionAlarmActive) {
lcd.print("MOTION ALARM!");
} else {
// Normal status display
lcd.setCursor(0, 0);
lcd.print("Status: OK");
lcd.setCursor(0, 1);
lcd.print("L:");
lcd.print(ledOn ? "ON" : "OFF");
lcd.print(" D:");
lcd.print(doorOpen ? "OPEN" : "SHUT");
lcd.print(" M:");
lcd.print(motionDetected ? "Y" : "N");
}
}