Top 5 Arduino Security & Alarm Projects (With Code & Circuit)
Security projects are some of the most satisfying things to build with Arduino — they solve a real problem you can demonstrate to anyone. These 5 projects cover the full spectrum from a simple PIR burglar alarm to a GSM-based intruder alert that texts your phone. All are buildable in a day and make excellent portfolio pieces.
Project 1 — PIR Burglar Alarm with Siren
Project Description
A PIR motion sensor watches a room or doorway. When motion is detected the system enters a 10-second grace period (time for the owner to disarm with a keypad), then triggers a 120dB piezo siren. A green LED shows armed status; a red LED flashes during alarm. A single button arms/disarms the system.
Components: Arduino Uno, HC-SR501 PIR sensor, 120dB active buzzer, green LED, red LED, push button, 2 × 220Ω resistors, 10kΩ resistor, breadboard, jumper wires.
Circuit Description
| Component | Pin | Arduino Pin |
|---|---|---|
| PIR sensor | OUT | Pin 2 |
| Buzzer | + | Pin 8 |
| Green LED | + | Pin 12 (armed) |
| Red LED | + | Pin 13 (alarm) |
| Arm/Disarm button | one side | Pin 4 (INPUT_PULLUP) |
Code
#define PIR_PIN 2
#define BUZZER_PIN 8
#define GREEN_LED 12
#define RED_LED 13
#define ARM_BTN 4
enum State { DISARMED, ARMED, GRACE, ALARM };
State state = DISARMED;
unsigned long graceStart = 0;
const unsigned long GRACE_TIME = 10000; // 10 seconds
void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(BUZZER_PIN,OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(ARM_BTN, INPUT_PULLUP);
}
void loop() {
bool btnPressed = (digitalRead(ARM_BTN) == LOW);
switch (state) {
case DISARMED:
digitalWrite(GREEN_LED, LOW);
if (btnPressed) {
state = ARMED;
Serial.println("System ARMED.");
delay(500);
}
break;
case ARMED:
digitalWrite(GREEN_LED, HIGH);
if (btnPressed) { state = DISARMED; Serial.println("Disarmed."); delay(500); break; }
if (digitalRead(PIR_PIN) == HIGH) {
Serial.println("Motion! Grace period...");
state = GRACE; graceStart = millis();
}
break;
case GRACE:
digitalWrite(RED_LED, (millis() / 500) % 2); // flash
if (btnPressed) { state = DISARMED; digitalWrite(RED_LED, LOW); Serial.println("Disarmed in grace."); delay(500); break; }
if (millis() - graceStart > GRACE_TIME) {
state = ALARM; Serial.println("ALARM TRIGGERED!");
}
break;
case ALARM:
digitalWrite(RED_LED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
if (btnPressed) {
state = DISARMED;
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RED_LED, LOW);
Serial.println("Alarm silenced."); delay(500);
}
break;
}
}
Conclusion
State machines are the right tool for alarm logic — the code is predictable and easy to extend. Next step: replace the arm button with a 4-digit keypad PIN, or add an ESP8266 to send a push notification on alarm trigger.
Project 2 — RFID Access Control System
Project Description
An RC522 RFID reader grants or denies access based on a list of registered card UIDs. Authorised cards get a green LED + unlock signal (servo or relay); unknown cards get a red LED + alarm beep. All access events are logged to the serial monitor with a timestamp. Simple, expandable, and works with any RFID key card or fob.
Components: Arduino Uno, RC522 RFID module, servo motor (or relay), green LED, red LED, buzzer, 2 × 220Ω resistors, breadboard, jumper wires.
Circuit Description
| RC522 | Arduino Pin |
|---|---|
| SDA (SS) | Pin 10 |
| SCK | Pin 13 |
| MOSI | Pin 11 |
| MISO | Pin 12 |
| RST | Pin 9 |
| 3.3V | 3.3V |
| GND | GND |
Green LED on pin 6, red LED on pin 5, buzzer on pin 4, servo signal on pin 3.
Code
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN);
Servo lockServo;
#define GREEN 6
#define RED 5
#define BUZZER 4
// Add your card UIDs here (run with Serial.print first to get them)
String allowedUIDs[] = {"A1B2C3D4", "11223344"};
int totalAllowed = 2;
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
lockServo.attach(3);
lockServo.write(0); // locked
pinMode(GREEN, OUTPUT); pinMode(RED, OUTPUT); pinMode(BUZZER, OUTPUT);
Serial.println("RFID Access Control Ready. Scan a card...");
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
String uid = "";
for (byte i = 0; i < rfid.uid.size; i++) uid += String(rfid.uid.uidByte[i], HEX);
uid.toUpperCase();
Serial.print("Card UID: " + uid + " -> ");
bool granted = false;
for (int i = 0; i < totalAllowed; i++) {
if (uid == allowedUIDs[i]) { granted = true; break; }
}
if (granted) {
Serial.println("ACCESS GRANTED");
digitalWrite(GREEN, HIGH);
lockServo.write(90); delay(3000); lockServo.write(0);
digitalWrite(GREEN, LOW);
} else {
Serial.println("ACCESS DENIED");
digitalWrite(RED, HIGH);
for (int i = 0; i < 3; i++) { digitalWrite(BUZZER, HIGH); delay(150); digitalWrite(BUZZER, LOW); delay(100); }
delay(500); digitalWrite(RED, LOW);
}
rfid.PICC_HaltA();
}
Conclusion
This is the exact architecture of commercial RFID access panels. Next step: store allowed UIDs in EEPROM so they survive power loss, or add an admin card that can enrol new cards without reprogramming.
Project 3 — Laser Tripwire Alarm
Project Description
A laser module aimed at an LDR (light-dependent resistor) creates an invisible tripwire. When something breaks the beam the alarm triggers instantly. The detection is faster than a PIR sensor, making it ideal for doorways, windows, or narrow corridors. A relay output can trigger a siren, camera, or notification system.
Components: Arduino Uno, 5mW laser module (650nm red), LDR, 10kΩ resistor, buzzer, red LED, 220Ω resistor, breadboard, jumper wires.
Circuit Description
| Component | Connection | Arduino Pin |
|---|---|---|
| Laser module | + | Pin 7 (switched) |
| LDR + 10kΩ divider | midpoint | A0 (analog) |
| Buzzer | + | Pin 8 |
| Red LED | + | Pin 13 |
Code
#define LASER_PIN 7
#define LDR_PIN A0
#define BUZZER 8
#define RED_LED 13
int baseline = 0;
int THRESHOLD = 200; // how much drop triggers alarm
void setup() {
Serial.begin(9600);
pinMode(LASER_PIN, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(RED_LED, OUTPUT);
digitalWrite(LASER_PIN, HIGH); // turn laser on
delay(1000);
// Calibrate: read the baseline LDR value with laser shining on it
baseline = analogRead(LDR_PIN);
Serial.println("Baseline (laser on LDR): " + String(baseline));
Serial.println("Tripwire armed.");
}
void loop() {
int ldrValue = analogRead(LDR_PIN);
int drop = baseline - ldrValue;
Serial.println("LDR: " + String(ldrValue) + " | Drop: " + String(drop));
if (drop > THRESHOLD) {
Serial.println("!!! BEAM BROKEN — ALARM !!!");
for (int i = 0; i < 10; i++) {
digitalWrite(RED_LED, HIGH); digitalWrite(BUZZER, HIGH); delay(200);
digitalWrite(RED_LED, LOW); digitalWrite(BUZZER, LOW); delay(100);
}
}
delay(50);
}
Conclusion
Tripwire detection using a light-dependent resistor is a classic analog sensing technique. Next step: add a relay to trigger a camera or door solenoid, or connect the alarm output to an ESP8266 for instant phone notifications.
Project 4 — Fingerprint Safe Lock
Project Description
An AS608 optical fingerprint sensor controls a solenoid or servo lock. Register up to 127 fingerprints; only registered fingers unlock the device. Unknown fingers trigger a buzzer alert. Used in real laptop locks, gun safes, and attendance systems — this is not a toy project.
Components: Arduino Uno, AS608 fingerprint sensor, servo motor, green LED, red LED, buzzer, 2 × 220Ω resistors, breadboard, jumper wires.
Circuit Description
| AS608 | Arduino Pin |
|---|---|
| TX | Pin 2 (SoftwareSerial) |
| RX | Pin 3 (SoftwareSerial) |
| VCC | 3.3V |
| GND | GND |
Servo signal on pin 9. Green LED pin 12. Red LED pin 11. Buzzer pin 10.
Code
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
#include <Servo.h>
SoftwareSerial mySerial(2, 3);
Adafruit_Fingerprint finger(&mySerial);
Servo lockServo;
#define GREEN 12
#define RED 11
#define BUZZ 10
void setup() {
Serial.begin(9600);
finger.begin(57600);
lockServo.attach(9); lockServo.write(0); // locked
pinMode(GREEN, OUTPUT); pinMode(RED, OUTPUT); pinMode(BUZZ, OUTPUT);
if (finger.verifyPassword()) Serial.println("Fingerprint sensor found.");
else { Serial.println("Sensor not found!"); while(1); }
Serial.println("Place finger to unlock...");
}
void loop() {
int id = getFingerprintID();
if (id > 0) {
Serial.println("Fingerprint matched! ID: " + String(id));
digitalWrite(GREEN, HIGH);
lockServo.write(90); delay(5000); lockServo.write(0);
digitalWrite(GREEN, LOW);
} else if (id == FINGERPRINT_NOTFOUND) {
Serial.println("Unknown fingerprint.");
digitalWrite(RED, HIGH);
digitalWrite(BUZZ, HIGH); delay(500); digitalWrite(BUZZ, LOW);
delay(500); digitalWrite(RED, LOW);
}
delay(200);
}
int getFingerprintID() {
if (finger.getImage() != FINGERPRINT_OK) return -1;
if (finger.image2Tz() != FINGERPRINT_OK) return -1;
if (finger.fingerFastSearch() != FINGERPRINT_OK) return FINGERPRINT_NOTFOUND;
return finger.fingerID;
}
Conclusion
Biometric authentication on a $5 microcontroller is genuinely impressive. Next step: run the enrolment sketch (included with the Adafruit Fingerprint library) to register your own fingerprints, or add a log that records each unlock event with a timestamp to an SD card.
Project 5 — GSM Intruder SMS Alert
Project Description
When a PIR sensor detects an intruder, a SIM800L GSM module sends an SMS alert to your phone — no WiFi required. Works anywhere with a mobile signal, making it perfect for sheds, garages, or remote properties. An optional camera module snapshot can be attached for a complete security package.
Components: Arduino Uno, SIM800L GSM module, HC-SR501 PIR sensor, 18650 LiPo battery (SIM800L needs 3.7–4.2V), buzzer.
Circuit Description
| SIM800L | Arduino |
|---|---|
| TX | Pin 7 (SoftwareSerial RX) |
| RX | Pin 8 (SoftwareSerial TX) |
| VCC | 3.7–4.2V (LiPo, NOT 5V) |
| GND | GND |
| PIR OUT | Pin 2 |
Important: The SIM800L draws up to 2A during transmission. Power it from a LiPo battery or a beefy 4V regulator — Arduino's 5V pin cannot handle it and the module will brown out.
Code
#include <SoftwareSerial.h>
SoftwareSerial gsm(7, 8); // RX, TX
#define PIR_PIN 2
#define BUZZER 4
const char* phoneNumber = "+447911123456"; // replace with your number
bool alarmSent = false;
void sendSMS(const char* number, String message) {
gsm.println("AT+CMGF=1"); delay(1000);
gsm.println(String("AT+CMGS=\"") + number + "\""); delay(1000);
gsm.println(message);
delay(100);
gsm.write(26); // Ctrl+Z to send
delay(5000);
Serial.println("SMS sent.");
}
void setup() {
Serial.begin(9600);
gsm.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(BUZZER, OUTPUT);
delay(3000); // GSM module startup
gsm.println("AT"); delay(500);
gsm.println("AT+CMGF=1"); delay(500);
Serial.println("GSM Alarm Ready.");
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH && !alarmSent) {
Serial.println("Intruder detected! Sending SMS...");
digitalWrite(BUZZER, HIGH);
sendSMS(phoneNumber, "🚨 INTRUDER ALERT! Motion detected at your property.");
alarmSent = true;
delay(2000);
digitalWrite(BUZZER, LOW);
}
// Reset after 5 minutes to allow re-alerting
static unsigned long lastTrigger = 0;
if (alarmSent && millis() - lastTrigger > 300000UL) {
alarmSent = false;
lastTrigger = millis();
}
}
Conclusion
GSM-based alerting works anywhere on the planet with a mobile signal — no router, no cloud, no app. Next step: add GPS (NEO-6M module) to include your exact location in the SMS, or use the SIM800L's GPRS to upload a photo from a camera module when triggered.
0 Comments