An Arduino security alarm that detects motion with a PIR sensor, flashes an LED, sounds a buzzer, and prints an alert to the Serial Monitor — all with 20 lines of code.
PIR (Passive Infrared) sensors detect the infrared radiation emitted by warm bodies. The HC-SR501 outputs HIGH when motion is detected, LOW when clear.
// HC-SR501 PIR Sensor Wiring:
//
// PIR Sensor Arduino Uno
// ────────── ───────────
// VCC ─────── 5V
// OUT ─────── Digital Pin 7
// GND ─────── GND
//
// LED wiring:
// Anode (+, long leg) → 220Ω resistor → Digital Pin 13
// Cathode (-, short leg) → GND
//
// Buzzer wiring (optional):
// Positive (+) → Digital Pin 8
// Negative (-) → GND
//
// PIR calibration: let the sensor sit powered for 60 seconds before
// using it — it needs time to stabilise to the ambient IR level.
Read the PIR pin — HIGH means motion detected, LOW means clear.
#define PIR_PIN 7
#define LED_PIN 13
void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
Serial.println("PIR sensor warming up — please wait 10 seconds...");
delay(10000); // Give PIR time to calibrate
Serial.println("Ready! Watching for motion...");
}
void loop() {
int motion = digitalRead(PIR_PIN);
if (motion == HIGH) {
digitalWrite(LED_PIN, HIGH);
Serial.println("⚠️ MOTION DETECTED!");
} else {
digitalWrite(LED_PIN, LOW);
}
delay(100);
}
PIR sensor warming up — please wait 10 seconds... Ready! Watching for motion... ⚠️ MOTION DETECTED! ⚠️ MOTION DETECTED! ⚠️ MOTION DETECTED!
Sound a buzzer when motion is detected and log the time with millis().
#define PIR_PIN 7
#define LED_PIN 13
#define BUZZ_PIN 8
bool lastState = false;
unsigned long alarmCount = 0;
void beep(int times) {
for (int i = 0; i < times; i++) {
digitalWrite(BUZZ_PIN, HIGH); delay(100);
digitalWrite(BUZZ_PIN, LOW); delay(80);
}
}
void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZ_PIN, OUTPUT);
Serial.println("Motion Alarm — warming up (10s)...");
delay(10000);
Serial.println("Ready.\n");
}
void loop() {
bool motion = digitalRead(PIR_PIN);
unsigned long seconds = millis() / 1000;
if (motion && !lastState) {
alarmCount++;
String time = String(seconds / 60) + "m " + String(seconds % 60) + "s";
Serial.print("[" + time + "] ALARM #");
Serial.print(alarmCount);
Serial.println(" — Motion detected!");
digitalWrite(LED_PIN, HIGH);
beep(2);
}
if (!motion && lastState) {
digitalWrite(LED_PIN, LOW);
Serial.println(" — All clear.");
}
lastState = motion;
delay(100);
}
Motion Alarm — warming up (10s)...
Ready.
[0m 15s] ALARM #1 — Motion detected!
— All clear.
[0m 43s] ALARM #2 — Motion detected!
[0m 45s] ALARM #3 — Motion detected!
— All clear.Read the serial port from Python to save a log of all motion events with real timestamps.
# Run this on your computer while the Arduino is connected via USB
# pip install pyserial
import serial
import datetime
PORT = 'COM3' # Windows: COM3, COM4, etc.
# Mac/Linux: /dev/ttyUSB0 or /dev/ttyACM0
BAUD = 9600
ser = serial.Serial(PORT, BAUD, timeout=1)
print(f"Listening on {PORT}...")
with open('motion_log.txt', 'a') as log:
while True:
line = ser.readline().decode('utf-8', errors='ignore').strip()
if line:
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
entry = f"[{timestamp}] {line}"
print(entry)
log.write(entry + '\n')
log.flush()
Listening on COM3... [2026-08-09 14:32:15] [0m 15s] ALARM #1 — Motion detected! [2026-08-09 14:32:22] — All clear. [2026-08-09 14:33:01] [0m 43s] ALARM #2 — Motion detected!
You built a working security sensor with under 30 lines of Arduino code. Add a 16x2 LCD display to show the alarm count without a computer. The same PIR + buzzer pattern is used in commercial alarm systems, automatic lights, and parking sensors.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.