Project 4.11: "Advanced Security System"
What you’ll learn
- Goal 1: Detect multiple intrusions using PIR, ultrasonic, and sound sensors together.
- Goal 2: Verify alarms by combining sensor readings to reduce false positives.
- Goal 3: Notify the operator via Bluetooth with short, clear messages.
- Goal 4: Activate countermeasures such as lights and sound alarms.
- Goal 5: Record time‑stamped events in the Serial log for later review.
Blocks glossary
- machine.Pin(pin, machine.Pin.IN).value(): Digital input for PIR and sound sensor.
- sonar.Sonar(TRIG,ECHO).checkdist(): Ultrasonic distance in cm for intrusion detection.
- music.MIDI(pin).play(…), .pitch_time(freq,ms): Sound alarm feedback.
- machine.Pin(pin, machine.Pin.OUT).value(v): Control actuators like LEDs or sirens.
- ble_peripheral.BLESimplePeripheral(name).send(msg): Send notification messages via Bluetooth.
- print(…): Serial log for event recording.
- time.sleep_ms(ms): Cadence control for monitoring loop.
What you need
| Part | How many? | Pin connection (R32) |
|---|---|---|
| D1 R32 | 1 | USB cable |
| PIR sensor | 1 | Signal → Pin 23 |
| Ultrasonic HC‑SR04 | 1 | TRIG → 26, ECHO → 5 |
| Sound sensor | 1 | Signal → Pin 32 (ADC) |
| LED (alarm light) | 1 | Pin 13 |
| Buzzer (MIDI) | 1 | Pin 26 |
| Bluetooth (built‑in) | 1 | Internal |
- Share GND across all sensors and actuators.
- Place PIR and ultrasonic facing monitored area; sound sensor near entry point.
Before you start
- Connect PIR to pin 23, ultrasonic TRIG/ECHO to 26/5, sound sensor to ADC pin 32, LED to pin 13, buzzer to pin 26.
- Open Serial monitor to see logs.
- Quick test:
print("Ready!") # Serial: confirm system is wired and alive
Microprojects 1–5
Microproject 4.11.1 – Multiple intrusion detection
import machine # Load hardware pins
import sonar # Load ultrasonic module
import time # Load time library
pir = machine.Pin(23, machine.Pin.IN) # PIR sensor input on pin 23
us = sonar.Sonar(26, 5) # Ultrasonic TRIG=26, ECHO=5
sound = machine.ADC(machine.Pin(32)) # Sound sensor ADC on pin 32
sound.atten(machine.ADC.ATTN_11DB) # Configure ADC attenuation
sound.width(machine.ADC.WIDTH_12BIT) # Configure ADC resolution
print("[Detect] Sensors ready") # Serial: confirm sensors
m = pir.value() # Read PIR (0/1)
d = us.checkdist() # Read ultrasonic distance
s = sound.read() # Read sound level (0–4095)
print("[Detect] PIR=", m, "Dist=", d, "Sound=", s) # Serial: show all readings
Reflection: You combined three sensors into one detection snapshot.
Challenge: Print “INTRUSION” if PIR=1 and distance < 30 cm and sound > 2500.
Microproject 4.11.2 – Alarm verification (multiple sensors)
import machine # Load pins
import sonar # Load ultrasonic
import time # Load time
pir = machine.Pin(23, machine.Pin.IN) # PIR input
us = sonar.Sonar(26, 5) # Ultrasonic
sound = machine.ADC(machine.Pin(32)) # Sound ADC
sound.atten(machine.ADC.ATTN_11DB) # ADC attenuation
sound.width(machine.ADC.WIDTH_12BIT) # ADC resolution
print("[Verify] Sensors ready") # Serial: confirm
m = pir.value() # PIR read
d = us.checkdist() # Distance read
s = sound.read() # Sound read
if (m==1) and (d<30) and (s>2500): # If all three triggered
print("ALERT:VERIFIED") # Serial: verified alarm
else: # Otherwise not verified
print("STATUS:OK") # Serial: safe status
Reflection: You reduced false alarms by requiring multiple sensors to agree.
Challenge: Try requiring only two sensors (PIR+sound) and compare sensitivity.
Microproject 4.11.3 – Notification to operator via Bluetooth
import ble_peripheral # Load BLE peripheral
import time # Load time
ble_p = ble_peripheral.BLESimplePeripheral("Sec-R32") # Create BLE peripheral
print("[Notify] BLE 'Sec-R32' ready") # Serial: confirm BLE
ble_p.send("STATUS:SECURE") # Send initial status
print("[Notify] TX STATUS:SECURE") # Serial: mirror message
time.sleep_ms(500) # Short pause
ble_p.send("ALERT:INTRUSION") # Send intrusion alert
print("[Notify] TX ALERT:INTRUSION") # Serial: mirror message
Reflection: Bluetooth messages keep the operator informed.
Challenge: Add “ALERT:VERIFIED” only when multiple sensors agree.
Microproject 4.11.4 – Activation of countermeasures (lights, sound)
import machine # Load pins
import music # Load MIDI for buzzer
import time # Load time
led = machine.Pin(13, machine.Pin.OUT) # LED alarm on pin 13
midi = music.MIDI(26) # Buzzer on pin 26
print("[Counter] LED=13 MIDI=26 ready") # Serial: confirm actuators
led.value(1) # Turn LED ON (alarm light)
print("[Counter] LED ON") # Serial: log LED
midi.pitch_time(880, 400) # Play loud tone
print("[Counter] Tone 880 Hz 400 ms") # Serial: log tone
time.sleep_ms(500) # Pause
led.value(0) # Turn LED OFF
print("[Counter] LED OFF") # Serial: log LED
Reflection: You activated light and sound countermeasures clearly.
Challenge: Blink LED three times and play three tones for stronger alarm.
Microproject 4.11.5 – Time‑stamped event log
import dhtx # Optional environment sensor
import machine # Load pins
import time # Load time
pir = machine.Pin(23, machine.Pin.IN) # PIR input
m = pir.value() # Read PIR
t = dhtx.DHT11(26).temperature() # Read temperature
h = dhtx.DHT11(26).humidity() # Read humidity
ts = time.ticks_ms() # Get current time in ms
print("LOG:TS=", ts, ";PIR=", m, ";T=", t, ";H=", h) # Serial: structured log line
Reflection: You created a simple time‑stamped log line with sensor values.
Challenge: Add sound sensor value to the log for complete intrusion context.
Blocks glossary
- machine.Pin(pin, machine.Pin.IN).value(): Digital input for PIR.
- machine.ADC(machine.Pin(pin)).read(): Analog sound sensor read (0–4095).
- machine.ADC.ATTN_11DB / WIDTH_12BIT: ADC configuration for stable reads.
- sonar.Sonar(TRIG,ECHO).checkdist(): Ultrasonic distance in cm for intrusion detection.
- music.MIDI(pin).pitch_time(freq,ms) / play(…): Sound alarm feedback.
- machine.Pin(pin, machine.Pin.OUT).value(v): Control actuators like LEDs/sirens.
- ble_peripheral.BLESimplePeripheral(name).send(msg): Bluetooth notifications.
- print(…): Serial log for event recording.
- time.sleep_ms(ms): Cadence control for monitoring loop.
Main project
Advanced security system combining multiple sensors, verification, Bluetooth alerts, countermeasures, and event logging
import machine # Load hardware pins and ADC
import sonar # Load ultrasonic distance module
import music # Load MIDI module for buzzer tones
import ble_peripheral # Load Bluetooth peripheral module
import time # Load time for delays and cadence
# --- Sensors setup ---
pir = machine.Pin(23, machine.Pin.IN) # PIR motion sensor on pin 23 (digital input)
sound = machine.ADC(machine.Pin(32)) # Sound sensor on ADC pin 32 (analog input)
sound.atten(machine.ADC.ATTN_11DB) # Configure ADC attenuation for wide voltage range
sound.width(machine.ADC.WIDTH_12BIT) # Configure ADC resolution to 12 bits (0–4095)
us = sonar.Sonar(26, 5) # Ultrasonic sensor with TRIG on 26 and ECHO on 5
print("[Main] Sensors ready PIR=23 SONAR(26,5) ADC=32") # Serial: confirm sensor initialization
# --- Actuators setup ---
led = machine.Pin(13, machine.Pin.OUT) # Alarm LED on pin 13 (digital output)
midi = music.MIDI(26) # Buzzer via MIDI on pin 26 (audio feedback)
print("[Main] Actuators ready LED=13 MIDI=26") # Serial: confirm actuator initialization
# --- Communication setup ---
ble_p = ble_peripheral.BLESimplePeripheral("Sec-R32") # Create BLE device named Sec-R32
print("[Main] BLE 'Sec-R32' ready") # Serial: confirm BLE advertising
# --- Thresholds ---
SAFE_CM = 30 # Distance threshold (cm) for intrusion proximity
TH_SOUND = 2500 # Sound level threshold for loud event (0–4095)
print("[Main] SAFE_CM=", SAFE_CM, " TH_SOUND=", TH_SOUND) # Serial: show thresholds to operator
# --- Monitoring loop ---
while True: # Continuous security monitoring loop
m = pir.value() # Read PIR motion (0 no motion, 1 motion detected)
d = us.checkdist() # Read ultrasonic distance in centimeters
s = sound.read() # Read sound level from ADC (0–4095)
ts = time.ticks_ms() # Read current timestamp in milliseconds
print("[Main] TS=", ts, " PIR=", m, " d=", d, " s=", s) # Serial: log raw sensor snapshot
# --- Verification logic: multiple sensors agree -> verified alert ---
env_close = (d is not None) and (d > 0) and (d < SAFE_CM) # True if distance is valid and close
loud_event = (s >= TH_SOUND) # True if sound exceeds threshold
motion_event = (m == 1) # True if PIR detects motion
verified = motion_event and env_close and loud_event # Verified alert only if all three agree
if verified: # If verified intrusion detected
print("ALERT:VERIFIED") # Serial: print verified alert tag
ble_p.send("ALERT:VERIFIED") # BLE: notify operator of verified alert
led.value(1) # LED: turn ON alarm light
midi.pitch_time(880, 400) # Buzzer: loud tone (880 Hz for 400 ms)
print("[Main] Countermeasures ON") # Serial: confirm countermeasures active
time.sleep_ms(500) # Short pause to avoid spam
led.value(0) # LED: turn OFF alarm light after tone
print("[Main] Countermeasures OFF") # Serial: confirm countermeasures off
else: # If not fully verified
# --- Partial alerts to inform operator without full countermeasures ---
if motion_event and env_close: # Motion + close distance (two sensors)
print("ALERT:PAIR PIR+DIST") # Serial: paired alert info
ble_p.send("ALERT:PAIR PIR+DIST") # BLE: notify paired alert (PIR + distance)
elif motion_event and loud_event: # Motion + loud sound (two sensors)
print("ALERT:PAIR PIR+SOUND") # Serial: paired alert info
ble_p.send("ALERT:PAIR PIR+SOUND") # BLE: notify paired alert (PIR + sound)
elif env_close or loud_event or motion_event: # Any single trigger (informational)
print("STATUS:WATCH") # Serial: watching due to single trigger
ble_p.send("STATUS:WATCH") # BLE: notify watch status
else: # No triggers at all
print("STATUS:SECURE") # Serial: environment secure
ble_p.send("STATUS:SECURE") # BLE: notify secure status
# --- Time-stamped event log line (compact) ---
print("LOG:TS="+str(ts)+";PIR="+str(m)+";D="+str(d)+";S="+str(s)) # Serial: structured log entry
time.sleep_ms(800) # Cadence: ~0.8 s loop to keep logs readable
External explanation
This main project reads three sensors (PIR, ultrasonic, sound) and verifies alerts by requiring agreement. It prints clear Serial logs, sends concise Bluetooth notifications, and activates countermeasures only on a verified intrusion. Simple thresholds and pacing keep behavior stable and understandable for students.
Story time
Imagine a calm guardian watching your space. It listens, looks, and senses movement. Only when everything points to “someone’s here” does it light up and sound the alarm—brief, clear, and confident.
Debugging (2)
Debugging 4.11.A – Sensors do not activate together
# Align sensor placement and add short confirmation before acting
print("[Debug] Reposition PIR toward entry; keep sonar front-centered") # Serial: placement tip
time.sleep_ms(200) # Brief confirmation delay
# Read again and compare to reduce timing mismatches
Debugging 4.11.B – False alarms due to noise
# Increase sound threshold or add a second short read before confirming loud_event
print("[Debug] Raise TH_SOUND or confirm with a second ADC read") # Serial: guidance
# Example confirmation flow:
# s1 = sound.read(); time.sleep_ms(200); s2 = sound.read()
# if (s1 >= TH_SOUND) and (s2 >= TH_SOUND): print("ALERT:SOUND_CONFIRMED")
Final checklist
- PIR (pin 23) reads motion 0/1 consistently.
- Ultrasonic (TRIG 26, ECHO 5) reports distance in cm.
- Sound ADC (pin 32) reads 0–4095 with stable configuration.
- Verified alerts require motion + close distance + loud sound.
- Bluetooth and Serial messages are short, frequent, and clear.
- Countermeasures (LED + buzzer) activate only on verified alerts.
Extras
- Student tip: Adjust SAFE_CM (25–40 cm) and TH_SOUND (2300–3000) to fit your room’s acoustics.
- Instructor tip: Ask students to design a message map (STATUS vs ALERT) and justify thresholds.
- Glossary:
- Verified alert: When multiple sensors agree, reducing false positives.
- Countermeasures: Actions like lights and tones to deter or notify.
- Cadence: Loop timing that keeps readings and logs stable.
- Mini tips:
- Keep wires short and sensors firmly mounted.
- Face PIR and ultrasonic toward the monitored area.
- Avoid flooding Serial with too many prints; pace at ~800–1000 ms.