/*
* Burglar Alarm System with Keypad
* Arduino Uno + 20x4 LCD (I2C) + 4x4 Keypad + Buzzer
*
* Features:
* - Arm/Disarm with passcode
* - Entry delay
* - Motion sensor support
* - LCD status display
* - Buzzer alarm
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD Configuration (I2C address 0x27, 20 columns, 4 rows)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Keypad Configuration
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] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Pin Definitions
const int BUZZER_PIN = 10;
const int MOTION_SENSOR_PIN = 11;
const int LED_ARMED = 12;
const int LED_DISARMED = 13;
// System Variables
String correctPassword = "1234"; // Default password
String enteredPassword = "";
bool systemArmed = false;
bool alarmTriggered = false;
unsigned long entryDelayStart = 0;
unsigned long alarmStartTime = 0;
const unsigned long ENTRY_DELAY = 10000; // 10 seconds
const unsigned long ALARM_DURATION = 30000; // 30 seconds
// System States
enum SystemState {
DISARMED,
ARMING,
ARMED,
ENTRY_DELAY,
ALARM_ACTIVE
};
SystemState currentState = DISARMED;
void setup() {
Serial.begin(9600);
// Initialize LCD
lcd.init();
lcd.backlight();
// Initialize pins
pinMode(BUZZER_PIN, OUTPUT);
pinMode(MOTION_SENSOR_PIN, INPUT);
pinMode(LED_ARMED, OUTPUT);
pinMode(LED_DISARMED, OUTPUT);
// Initial state
digitalWrite(LED_DISARMED, HIGH);
digitalWrite(LED_ARMED, LOW);
// Welcome message
displayWelcome();
delay(2000);
updateDisplay();
}
void loop() {
char key = keypad.getKey();
bool motionDetected = digitalRead(MOTION_SENSOR_PIN);
// Handle keypad input
if (key) {
handleKeyInput(key);
}
// Handle motion detection
if (motionDetected && currentState == ARMED) {
startEntryDelay();
}
// Handle state machine
handleStateMachine();
// Update display every second
static unsigned long lastDisplayUpdate = 0;
if (millis() - lastDisplayUpdate > 1000) {
updateDisplay();
lastDisplayUpdate = millis();
}
}
void handleKeyInput(char key) {
if (key == '#') {
// Enter key - process password
if (enteredPassword == correctPassword) {
if (currentState == DISARMED) {
armSystem();
} else {
disarmSystem();
}
} else {
wrongPassword();
}
enteredPassword = "";
} else if (key == '*') {
// Clear key
enteredPassword = "";
lcd.setCursor(0, 3);
lcd.print(" ");
} else if (key == 'A') {
// Change password
changePassword();
} else if (key == 'B') {
// Emergency disarm (could require admin code)
emergencyDisarm();
} else {
// Add digit to password
if (enteredPassword.length() < 8) {
enteredPassword += key;
displayPasswordInput();
}
}
}
void handleStateMachine() {
switch (currentState) {
case ENTRY_DELAY:
if (millis() - entryDelayStart > ENTRY_DELAY) {
triggerAlarm();
}
break;
case ALARM_ACTIVE:
// Flash LEDs and sound buzzer
static unsigned long lastBeep = 0;
if (millis() - lastBeep > 500) {
digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
digitalWrite(LED_ARMED, !digitalRead(LED_ARMED));
lastBeep = millis();
}
// Auto-stop alarm after duration
if (millis() - alarmStartTime > ALARM_DURATION) {
currentState = ARMED;
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(LED_ARMED, HIGH);
}
break;
}
}
void armSystem() {
currentState = ARMED;
systemArmed = true;
digitalWrite(LED_ARMED, HIGH);
digitalWrite(LED_DISARMED, LOW);
lcd.clear();
lcd.setCursor(6, 1);
lcd.print("SYSTEM ARMED");
lcd.setCursor(4, 2);
lcd.print("Motion Protected");
// Confirmation beep
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(2000);
}
void disarmSystem() {
currentState = DISARMED;
systemArmed = false;
alarmTriggered = false;
digitalWrite(LED_ARMED, LOW);
digitalWrite(LED_DISARMED, HIGH);
digitalWrite(BUZZER_PIN, LOW);
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("SYSTEM DISARMED");
lcd.setCursor(7, 2);
lcd.print("Welcome Home");
// Confirmation beeps
for (int i = 0; i < 2; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
delay(2000);
}
void startEntryDelay() {
currentState = ENTRY_DELAY;
entryDelayStart = millis();
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("ENTRY DETECTED");
lcd.setCursor(2, 2);
lcd.print("Enter Code or Alarm!");
}
void triggerAlarm() {
currentState = ALARM_ACTIVE;
alarmTriggered = true;
alarmStartTime = millis();
lcd.clear();
lcd.setCursor(7, 1);
lcd.print("ALARM!");
lcd.setCursor(4, 2);
lcd.print("INTRUDER ALERT");
}
void wrongPassword() {
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("WRONG PASSWORD");
lcd.setCursor(6, 2);
lcd.print("Try Again");
// Error beep
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
delay(2000);
}
void changePassword() {
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("CHANGE PASSWORD");
lcd.setCursor(0, 1);
lcd.print("Enter current code:");
String currentCode = "";
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (currentCode == correctPassword) {
// Get new password
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter new code:");
String newCode = "";
while (true) {
char newKey = keypad.getKey();
if (newKey) {
if (newKey == '#') {
if (newCode.length() >= 4) {
correctPassword = newCode;
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("CODE CHANGED");
delay(2000);
return;
}
} else if (newKey == '*') {
return; // Cancel
} else {
newCode += newKey;
lcd.setCursor(newCode.length() - 1, 1);
lcd.print("*");
}
}
}
} else {
wrongPassword();
return;
}
} else if (key == '*') {
return; // Cancel
} else {
currentCode += key;
lcd.setCursor(currentCode.length() - 1, 2);
lcd.print("*");
}
}
}
}
void emergencyDisarm() {
disarmSystem();
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("EMERGENCY DISARM");
delay(2000);
}
void displayWelcome() {
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("SECURITY SYSTEM");
lcd.setCursor(6, 1);
lcd.print("v1.0");
lcd.setCursor(3, 2);
lcd.print("Initializing...");
}
void updateDisplay() {
if (currentState == ENTRY_DELAY) {
// Show countdown
unsigned long remaining = (ENTRY_DELAY - (millis() - entryDelayStart)) / 1000;
lcd.setCursor(0, 3);
lcd.print("Time left: ");
lcd.print(remaining);
lcd.print(" sec ");
return;
}
if (currentState == ALARM_ACTIVE) {
return; // Don't update during alarm
}
lcd.clear();
// Status line
lcd.setCursor(0, 0);
if (systemArmed) {
lcd.print("Status: ARMED ");
} else {
lcd.print("Status: DISARMED ");
}
// Instructions
lcd.setCursor(0, 1);
lcd.print("Enter code + #");
lcd.setCursor(0, 2);
lcd.print("A=Change B=Emergency");
// Show entered password
if (enteredPassword.length() > 0) {
displayPasswordInput();
}
}
void displayPasswordInput() {
lcd.setCursor(0, 3);
lcd.print("Code: ");
for (int i = 0; i < enteredPassword.length(); i++) {
lcd.print("*");
}
// Clear remaining characters
for (int i = enteredPassword.length(); i < 8; i++) {
lcd.print(" ");
}
}
void calibratePiezoSensor() {
lcd.clear();
lcd.setCursor(2, 1);
lcd.print("Calibrating Piezo");
lcd.setCursor(4, 2);
lcd.print("Please wait...");
// Take baseline readings
long total = 0;
for (int i = 0; i < 50; i++) {
total += analogRead(PIEZO_SENSOR_PIN);
delay(20);
}
piezoBaseline = total / 50;
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Calibration Done");
lcd.setCursor(2, 2);
lcd.print("Baseline: ");
lcd.print(piezoBaseline);
delay(2000);
}
bool checkPiezoSensor() {
if (millis() - lastPiezoTrigger < PIEZO_COOLDOWN) {
return false; // Still in cooldown period
}
int reading = analogRead(PIEZO_SENSOR_PIN);
int difference = abs(reading - piezoBaseline);
if (difference > piezoThreshold) {
lastPiezoTrigger = millis();
return true;
}
return false;
}
void adjustSensitivity() {
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("PIEZO SENSITIVITY");
lcd.setCursor(0, 1);
lcd.print("Current: ");
lcd.print(piezoThreshold);
lcd.setCursor(0, 2);
lcd.print("1-9=Set #=Save *=Exit");
while (true) {
char key = keypad.getKey();
if (key) {
if (key >= '1' && key <= '9') {
piezoThreshold = (key - '0') * 20; // 20-180 range
lcd.setCursor(9, 1);
lcd.print(" "); // Clear old value
lcd.setCursor(9, 1);
lcd.print(piezoThreshold);
} else if (key == '#') {
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("SENSITIVITY SET");
lcd.setCursor(6, 2);
lcd.print("Value: ");
lcd.print(piezoThreshold);
delay(2000);
return;
} else if (key == '*') {
return; // Exit without saving
}
}
}
}
void testSensors() {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("SENSOR TEST");
lcd.setCursor(0, 1);
lcd.print("PIR: ");
lcd.setCursor(0, 2);
lcd.print("Piezo: ");
lcd.setCursor(0, 3);
lcd.print("Press * to exit");
while (true) {
char key = keypad.getKey();
if (key == '*') {
return;
}
// Test PIR sensor
bool pirState = digitalRead(PIR_SENSOR_PIN);
lcd.setCursor(5, 1);
if (pirState) {
lcd.print("MOTION ");
} else {
lcd.print("CLEAR ");
}
// Test Piezo sensor
int piezoReading = analogRead(PIEZO_SENSOR_PIN);
int difference = abs(piezoReading - piezoBaseline);
lcd.setCursor(7, 2);
lcd.print(" "); // Clear old reading
lcd.setCursor(7, 2);
lcd.print(difference);
if (difference > piezoThreshold) {
lcd.setCursor(11, 2);
lcd.print("TRIGGER");
} else {
lcd.setCursor(11, 2);
lcd.print(" ");
}
delay(100);
}
}
Comments1
Recipe
Required Components:
Wiring Connections:
LCD (I2C):
4x4 Keypad:
Other Components:
Required Libraries:
Install these libraries in Arduino IDE:
LiquidCrystal_I2Cby Frank de BrabanderKeypadby Mark StanleyFeatures:
Usage:
The system includes visual feedback on the LCD, audio alerts via buzzer, and LED status indicators. The motion sensor will trigger the entry delay when the system is armed, giving you time to disarm before the alarm sounds.