Raspberry Pi Simple Alarm Project
This project wires a motion sensor and arm/disarm buttons into a small alarm system that sounds a buzzer and flashing LED, showing how to combine sensor input and actuator output around a clear state machine.
What This Project Builds
The alarm combines the concepts from earlier lessons: a button as an input trigger, a PIR (passive infrared) motion sensor as a second input, and an LED plus a buzzer as outputs. Two buttons control whether the system is watching for motion at all - one arms it, the other disarms it - so a false trigger, or simply walking past your own project, does not immediately set it off. The system only reacts to the motion sensor while it is in the armed state.
The Alarm Logic
- Start in a DISARMED state, where motion from the PIR sensor is ignored entirely.
- When the arm button is pressed, switch to ARMED and begin reacting to the motion sensor.
- While ARMED, if the sensor reports motion, switch to ALERT: flash the LED and sound the buzzer continuously.
- Stay in ALERT until the disarm button is pressed, which silences the outputs and returns the system to DISARMED.
- Ignore additional motion events while already in ALERT, since the alarm is already sounding and there is nothing more to trigger.
Wiring Overview
Event-Driven Alarm With gpiozero
from gpiozero import Button, LED, Buzzer, MotionSensor
from signal import pause
arm_button = Button(2, bounce_time=0.1)
disarm_button = Button(3, bounce_time=0.1)
pir = MotionSensor(4)
siren_led = LED(17)
buzzer = Buzzer(27)
armed = False
def arm_system():
global armed
armed = True
print('Alarm armed')
def disarm_system():
global armed
armed = False
siren_led.off()
buzzer.off()
print('Alarm disarmed')
def motion_detected():
if armed:
siren_led.blink(on_time=0.1, off_time=0.1)
buzzer.on()
print('Intruder detected!')
arm_button.when_pressed = arm_system
disarm_button.when_pressed = disarm_system
pir.when_motion = motion_detected
pause()Notice that the whole program never sits in a busy loop polling pins - each device's when_pressed or when_motion attribute is simply assigned a function, and gpiozero calls that function automatically the moment the matching event occurs. The final pause() call just keeps the program alive so those event callbacks can keep firing in the background; without it, the script would immediately reach its end and exit.
Extending the Alarm
- Add a numeric keypad so disarming requires entering a correct code, not just pressing a button.
- Log every trigger with a timestamp to a file so activity can be reviewed later.
- Send a notification - email, SMS, or a chat webhook - the moment the ALERT state begins.
- Add a short entry delay after arming so you have a few seconds to leave the room before the sensor starts reacting.