Smart Alarm System

Introduction

In this blog post, I'll walk you through the development of a Smart Alarm System built using the ESP32 microcontroller. This project integrates multiple security features, including a magnetic sensor for door/window monitoring, a keypad for secure access, a buzzer for alarms, an LCD for status display, and Wi-Fi connectivity for remote notifications. The system is housed in a plastic case and powered by a rechargeable battery with a charging circuit.


Project Overview

The Smart Alarm System is designed to:

  • Detect unauthorized entry using a magnetic sensor (reed switch).
  • Allow authorized users to arm/disarm the system via a 4x4 keypad.
  • Trigger a loud buzzer in case of a security breach.
  • Display system status on an LCD screen.
  • Send Wi-Fi notifications (via MQTT, Telegram, or email) when triggered.
  • Operate on battery power with a charging circuit for portability.

1. 3D Design

To ensure a compact and professional look, I designed a custom 3D case. The case includes:


  • Compartments for the ESP32, battery, and PCB.
  • Cutouts for the LCD, keypad, buzzer, and charging port.
  • Mounting holes for the magnetic sensor.

2. Hardware Components

Here’s the complete list of components used:

Component

Description

ESP32

Main microcontroller (Wi-Fi/BLE enabled)

4x4 Matrix Keypad

For secure PIN entry

Magnetic Sensor

Reed switch for door/window detection

Buzzer

Piezo buzzer for alarm sound

LCD (16x2 I2C)

Displays system status

Li-ion Battery

18650 or similar (3.7V)

Charging Module

TP4056 for battery charging

Boost Converter

Steps up 3.7V to 5V for ESP32

Plastic Enclosure

3D-printed case


3. PCB Design

Instead of using a breadboard, I designed a custom PCB for better reliability.

Key Features of the PCB:

  • ESP32 breakout with proper decoupling capacitors.
  • Keypad & LCD connectors for easy wiring.
  • Battery management circuit (TP4056 + boost converter).
  • Buzzer driver circuit (transistor-based for loud sound).
  • Magnetic sensor input with a pull-up resistor.

4. Circuit Diagram & Wiring

Here’s a simplified wiring guide:

ESP32 Pin

Connected To

GPIO 21 (SDA)

LCD I2C Data

GPIO 22 (SCL)

LCD I2C Clock

GPIO 4-11

Keypad Rows/Columns

GPIO 12

Magnetic Sensor (Input)

GPIO 13

Buzzer (via Transistor)

5V & GND

Power Supply (Boost Conv)

ESP 32 Pinout


Smart Alarm System Schematic 


5. Programming the ESP32 (Arduino IDE)

The firmware is written in Arduino C++ and includes:

Key Features of the Code:

  1. Wi-Fi & MQTT Setup – Sends alerts when the alarm is triggered.
  2. Keypad Authentication – Validates user PIN before arming/disarming.
  3. Magnetic Sensor Logic – Detects door/window openings.
  4. Buzzer Control – Activates a loud alarm on intrusion.
  5. LCD Feedback – Shows system status (Armed/Disarmed/Triggered).
  6. Low-Power Mode – Optimizes battery life when idle.

Example Code Snippet (Wi-Fi Alert):

cpp
Copy
// Include necessary libraries
#include <Wire.h>                 // For I2C communication
#include <LiquidCrystal_I2C.h>    // For I2C LCD control
#include <Keypad.h>               // For matrix keypad input

// Initialize I2C LCD (address 0x27, 16 columns, 2 rows)
LiquidCrystal_I2C I2C_LCD(0x27, 16, 2); 

// Define buzzer and magnetic sensor pins
const int buzzerPin = 32;         // Buzzer connected to GPIO 32
const int magnetPin = 33;         // Magnetic sensor (reed switch) on GPIO 33

// Keypad configuration (4x4 matrix)
const byte ROWS = 4;              // Four rows
const byte COLS = 4;              // Four columns
int Token_Number = 0;             // Placeholder for future use

// Define keypad layout
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

// ESP32 GPIO pins connected to keypad rows/columns
byte rowPins[ROWS] = {16, 4, 0, 2};  // ROW pins
byte colPins[COLS] = {19, 18, 5, 17}; // COL pins

// Create Keypad object
Keypad keypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

// Variables for LCD cursor and password handling
uint8_t LCD_CursorPosition = 0;   // Tracks cursor position on LCD
String PassWord = "54321";        // Default system password
String InputStr = "";             // Stores user input from keypad
bool safeMode = true;             // Tracks if the system is armed (true = safe)
bool doorClosed = false;           // Tracks door state (false = open)
bool setupMode = true;             // Flag for initial setup mode
int counter = 10;                 // Countdown timer for setup mode
String setupPass = "#####";        // Password to re-enter setup mode

// Keypad debounce variables
const unsigned long debounceDelay = 50; // Debounce delay (ms)
unsigned long lastKeyPressTime = 0;     // Tracks last key press time

// ===================== SETUP =====================
void setup() {
  Serial.begin(115200);            // Start serial communication for debugging

  // Initialize I2C LCD
  I2C_LCD.init();                  // Initialize LCD
  I2C_LCD.backlight();             // Turn on backlight
  I2C_LCD.clear();                 // Clear display
  I2C_LCD.setCursor(0, 0);         // Set cursor to first line
  I2C_LCD.print("WELCOME:");       // Display welcome message

  // Configure buzzer and magnetic sensor pins
  pinMode(buzzerPin, OUTPUT);      // Buzzer as output
  pinMode(magnetPin, INPUT);       // Magnetic sensor as input

  // Ensure buzzer is initially off (active-low logic)
  digitalWrite(buzzerPin, HIGH);   
}

// ===================== MAIN LOOP =====================
void loop() {
  int magnetPin_state = digitalRead(magnetPin); // Read door sensor
  Serial.println(magnetPin_state);              // Debug output

  // Setup mode (runs once at startup)
  if (setupMode == true) {
    I2C_LCD.backlight();                       // Ensure backlight is on
    printMsg("SETUP MODE", 0);                 // Display setup message
    for (int i = counter; i >= 0; i--) {      // Countdown timer
      printMsg("SETUP MODE", 0);
      printMsg(String(i), 1);                 // Show countdown
      delay(1000);
    }
    I2C_LCD.noBacklight();                     // Turn off backlight
    setupMode = false;                         // Exit setup mode
  } 
  // Normal operation mode
  else {
    // Check if door is opened while system is armed
    if (magnetPin_state == LOW && safeMode == true) {
      delay(5000);                            // Grace period before alarm
      I2C_LCD.backlight();                    // Turn on LCD
      printMsg("CLOSE THE DOOR:", 0);         // Alert user
      safeMode = false;                       // Disarm system
      doorClosed = false;                      // Mark door as open
      digitalWrite(buzzerPin, LOW);            // Activate buzzer (alarm)
    } 

    // If door is closed, handle keypad input
    if (magnetPin_state == HIGH) {
      if (doorClosed == false) {               // Reset input if door just closed
        resetInput();
        doorClosed = true;                     // Mark door as closed
      }
      handleKeypadInput();                     // Process keypad entries
    }
  }
}

// ===================== FUNCTIONS =====================

// Handles keypad input with debouncing
void handleKeypadInput() {
  char key = keypad.getKey();                 // Read pressed key
  if (key && millis() - lastKeyPressTime > debounceDelay) {
    lastKeyPressTime = millis();               // Update last key press time

    // If 'D' is pressed, reset input
    if (key == 'D') {
      resetInput();
    } 
    // Otherwise, append key to input string
    else {
      InputStr += key;                         // Add key to input buffer
      I2C_LCD.setCursor(LCD_CursorPosition++, 1); // Move cursor
      I2C_LCD.print('*');                     // Mask input with '*'
      
      // If 5 characters entered, check password
      if (LCD_CursorPosition == 5) {
        checkPassword();
      }
    }
  }
}

// Resets the LCD and input buffer
void resetInput() {
  InputStr = "";                              // Clear input buffer
  LCD_CursorPosition = 0;                     // Reset cursor position
  I2C_LCD.clear();                            // Clear LCD
  I2C_LCD.setCursor(0, 0);                    // Move to first line
  I2C_LCD.print("Enter PassWord:");           // Prompt for password
} 

// Prints a message to the LCD at specified line
void printMsg(String message, int lineNumber) {
  if (lineNumber == 0) 
    I2C_LCD.clear();                          // Clear screen if line 0
  I2C_LCD.setCursor(0, lineNumber);           // Set cursor position
  I2C_LCD.print(message);                     // Print message
} 

// Validates the entered password
void checkPassword() {
  String message;
  // Correct password: disarm system
  if (InputStr == PassWord) {
    message = "Alarm STOPPED!";
    digitalWrite(buzzerPin, HIGH);            // Turn off buzzer
    safeMode = true;                          // Re-arm system
  } 
  // Setup password: re-enter setup mode
  else if (InputStr == setupPass) {
    setupMode = true;
  }
  // Incorrect password
  else {
    message = "Wrong PassWord!";
  }

  // Display result and reset input
  InputStr = "";
  LCD_CursorPosition = 0;
  I2C_LCD.clear();
  I2C_LCD.setCursor(0, 0);
  I2C_LCD.print(message);
  delay(2000);                                // Show message for 2s
  
  // Turn off LCD backlight if system is armed
  if (safeMode == true)
    I2C_LCD.noBacklight();
    
  resetInput();                               // Reset for next input
}

6. Final Assembly & Testing

  1. 3D-Print the Case and fit all components.
  2. Solder the PCB (or use a breadboard for prototyping).
  3. Upload the Code to the ESP32 via USB.
  4. Test Each Feature:
    • Keypad PIN entry.
    • Magnetic sensor triggering.
    • Buzzer alarm.
    • Wi-Fi notifications.
  5. Optimize Power Consumption for longer battery life.
Smart Alarm System Components



Conclusion

This Smart Alarm System is a versatile, low-cost security solution that can be customized further (e.g., adding PIR motion sensors, GSM backup, or integrating with Home Assistant).


Download Resources

🔗 GitHub Repository 

Thanks for reading! 🚀

Comments