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:
- Wi-Fi & MQTT Setup – Sends alerts when the alarm is triggered.
- Keypad Authentication – Validates user PIN before arming/disarming.
- Magnetic Sensor Logic – Detects door/window openings.
- Buzzer Control – Activates a loud alarm on intrusion.
- LCD Feedback – Shows system status (Armed/Disarmed/Triggered).
- Low-Power Mode – Optimizes battery life when idle.
Example Code Snippet (Wi-Fi Alert):
// 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
- 3D-Print the Case and fit all components.
- Solder the PCB (or use a breadboard for prototyping).
- Upload the Code to the ESP32 via USB.
- Test Each Feature:
- Keypad PIN entry.
- Magnetic sensor triggering.
- Buzzer alarm.
- Wi-Fi notifications.
- Optimize Power Consumption for longer battery life.
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
Post a Comment