An energy-efficient embedded surveillance system that stays fully idle until a PIR motion sensor detects presence β then wakes up, sweeps a servo-mounted ultrasonic sensor across 180Β°, locks onto any target within range, and renders a live radar display on a connected PC.
Built as part of an Embedded Systems & Design course. Documented to IEEE project report standards.
Processing radar display showing active target detection (red dots) alongside the physical build: servo-mounted HC-SR04, Arduino Uno, and wiring. Tested in an electronics lab environment.
IDLE ββ[PIR triggers]βββΊ SCANNING ββ[object < 50cm]βββΊ ALERT
β² β β
βββββββ[sweep done]ββββββββββββββββ[dwell 2s]βββββββββββ
Radar visualization runs live in Processing on the host PC, showing the sweep arc, detected target position, and distance readout in real time.
- PIR-triggered wake-up β system draws near-zero active power at idle; servo and ultrasonic only activate on motion detection
- 180Β° servo sweep β bidirectional scan in 5Β° increments with HC-SR04 ranging at each step
- Target lock β servo halts and LED triggers when object detected within configurable threshold (default 50 cm)
- Live radar display β Processing sketch renders a sonar-style sweep with plotted hit points and distance labels
- Serial data protocol β lightweight text-based protocol (
angle,distance) streams data to host at 9600 baud - Finite State Machine architecture β clean IDLE β SCANNING β ALERT state model with defined transitions
| Component | Model | Role |
|---|---|---|
| Microcontroller | Arduino Uno (ATmega328P) | Main controller |
| Motion Sensor | HW-416-B (HC-SR501 based PIR) | Wake-up trigger |
| Ranging Sensor | HC-SR04 Ultrasonic | Distance measurement |
| Actuator | SG90 Micro Servo (9g) | 180Β° pan sweep |
| Indicator | 5mm LED + 330Ξ© resistor | Alert output |
| Host PC | Any OS | Radar visualization (Processing) |
| Component | Pin | Arduino Pin |
|---|---|---|
| HC-SR04 | VCC | 5V |
| HC-SR04 | GND | GND |
| HC-SR04 | TRIG | D10 |
| HC-SR04 | ECHO | D11 |
| SG90 Servo | Red (VCC) | 5V |
| SG90 Servo | Brown/Black (GND) | GND |
| SG90 Servo | Orange/Yellow (Signal) | D9 |
| HW-416-B PIR | VCC | 5V |
| HW-416-B PIR | GND | GND |
| HW-416-B PIR | OUT | D7 |
| LED (long leg +) | via 330Ξ© resistor | D6 |
| LED (short leg β) | β | GND |
Note: Mount the HC-SR04 on top of the SG90 servo horn using double-sided tape, with the two sensor "eyes" facing forward. Leave enough wire slack for a full 180Β° rotation.
- Arduino IDE (v1.8+ or v2.x)
- Processing (v4.x recommended)
- No external Arduino libraries required β
Servo.his bundled with the IDE
git clone https://github.com/HeyFang/security-turret.git
cd security-turret- Open
arduino/turret.inoin the Arduino IDE - Go to Tools β Board β select Arduino Uno
- Go to Tools β Port β select your COM port (e.g.
COM3on Windows,/dev/cu.usbmodem...on Mac) - Click Verify (β) to compile β confirm no errors
- Click Upload (β) to flash the sketch
Close the Arduino IDE Serial Monitor before this step. Both cannot use the serial port simultaneously.
- Open
processing/radar.pdein the Processing IDE - Run the sketch once β the console will print a list of available serial ports
- Find the index of your Arduino's port in that list
- In
radar.pde, update line:port = new Serial(this, Serial.list()[0], 9600); // β change this index if needed
- Run again β the radar window should appear and animate on PIR trigger
security-turret/
β
βββ arduino/
β βββ turret.ino # Main Arduino sketch (FSM + sensor control)
β
βββ processing/
β βββ radar.pde # Host-side radar visualization
β
βββ docs/
β βββ report.pdf # Full IEEE-format project report
β
βββ assets/
β βββ model.jpeg # Build photo (used in README)
β
βββ README.md
The following constants at the top of turret.ino can be adjusted without touching any other logic:
#define MAX_RANGE 50 // Alert threshold in cm (default: 50)
#define SCAN_STEP 5 // Degrees per servo step (default: 5Β°)
#define STEP_DELAY 80 // Milliseconds between steps (default: 80ms)Decrease SCAN_STEP for finer angular resolution (slower sweep). Increase MAX_RANGE for a longer detection zone.
The system runs a three-state Finite State Machine:
IDLE β PIR pin is polled continuously. Servo and ultrasonic are inactive. Minimal power draw.
SCANNING β Triggered by PIR HIGH. Servo steps from 0Β° to 180Β° bidirectionally. At each step, the HC-SR04 fires a 10 ΞΌs trigger pulse and measures the echo return time. Distance is computed as:
distance (cm) = pulseIn duration (ΞΌs) / 58
Each reading is serialized as angle,distance\n and sent over UART at 9600 baud to the Processing display. If a full sweep completes with no detection and PIR has gone LOW, system returns to IDLE.
ALERT β Triggered when distance < MAX_RANGE. Servo halts at detection angle, LED turns on, and ALERT,angle,distance\n is transmitted. System holds for 2 seconds then resumes scanning.
The Arduino outputs a simple newline-delimited text protocol:
| Message | Meaning |
|---|---|
WAKE |
PIR triggered, scan starting |
45,82 |
Servo at 45Β°, object at 82 cm |
ALERT,45,28 |
Object detected at 45Β°, 28 cm |
IDLE |
Sweep complete, returning to standby |
This makes the data easy to parse, log, or redirect to any serial terminal or custom application.
This project runs bare-metal (no RTOS). Key design decisions:
- PIR as wake-up: Polling is adequate here β PIR output stays HIGH for 2β3 seconds, so no events are missed. Avoids ISR complexity on a single-threaded system.
- PWM on D9 (Timer 1): Hardware PWM pin selected deliberately for jitter-free servo control, independent of software loop timing.
pulseIn()timeout: Set to 30 ms β slightly above the round-trip time for 400 cm range β to prevent indefinite blocking on no-return echoes.- Step delay of 80 ms: Chosen to allow full mechanical servo settling before ultrasonic trigger fires. Values below ~50 ms cause missed readings.
Primary limitation: pulseIn() is blocking, meaning no other processing occurs during echo measurement. An ISR-based timing approach (or RTOS migration to ESP32/FreeRTOS) would eliminate this constraint.
| Test | Method | Result |
|---|---|---|
| Ultrasonic accuracy | Measured at 10, 30, 50 cm with ruler | Β±2 cm variance β within datasheet spec |
| PIR reliability | Triggered after 60s warmup in static room | Consistent HIGH on motion, LOW at rest |
| Servo settling | Logged ultrasonic readings at 50ms vs 80ms delay | 80ms required for consistent readings |
| Serial throughput | Frame size ~12 bytes at 9600 baud | ~12.5ms/frame β well within 80ms step window |
| Full sweep time | Timed 36-step sweep (0Β°β180Β°) | ~3.96s worst-case (30ms timeout Γ 36 steps) |
- PIR sensor requires ~60 seconds of warmup after power-on before reliable detection
- Blocking
pulseIn()call prevents response to new PIR events mid-reading - Single horizontal axis only β no vertical (tilt) coverage
- Requires tethered PC for radar display β no standalone screen support in current version
- HC-SR04 beam angle (~15Β°) limits angular discrimination at longer ranges
- Migrate to ESP32 + FreeRTOS for true multitasking and non-blocking echo measurement
- Add pan-tilt second axis (vertical servo) for hemispheric coverage
- Replace Processing display with onboard SSD1306 OLED for standalone operation
- Add Wi-Fi alert via ESP8266 (push notification on detection)
- Integrate OV2640 camera module (ESP32-CAM) for image capture on alert
- TinyML motion classification to filter false positives (human vs animal vs environmental)
This project is licensed under the MIT License β see LICENSE for details.
Aryan Shete
LinkedIn Β· GitHub
Built for an Embedded Systems & Design course project. Documented to IEEE report standards.
