Back to projects
Case study · 2025 · Shipped

Cloud-Enhanced IoT Smart Speed Breaker

Two-tier IoT pipeline with ResNet50 edge inference and dynamic servo actuation.

PythonEmbedded COpenCVTensorFlowRaspberry Pi 4ArduinoUARTMQTT
Cloud-Enhanced IoT Smart Speed Breaker cover
Role
Lead engineer — vision, firmware, integration
Timeline
Jan 2025 – Jun 2025 (6 months)
Team
Solo build with 2 collaborators on hardware
Status
Shipped
TL;DR

An adaptive speed breaker that classifies approaching vehicles with ResNet50 on a Raspberry Pi 4 and actuates a servo via an Arduino Nano in under a second — staying flat for emergency vehicles while rising for speeders. Won the institute-level Avishkar competition.

97%
Classification accuracy
0.97
F1-score
< 1 s
End-to-end latency
Avishkar Winner
Recognition
Institute-level technical competition
/ Overview

Problem & motivation

Problem

Fixed-height speed breakers slow every vehicle equally — including ambulances, fire trucks, and small cars that don't need the deterrent. They damage vehicles, waste fuel, and delay emergency response in the name of traffic calming.

Motivation

A speed breaker should adapt to what's actually approaching. If a traffic camera and an embedded controller can together classify the vehicle in under a second, the breaker can stay flat for emergency vehicles and lift for speeders — without any human in the loop.

Objectives
  • 01Classify approaching vehicles in real time with high accuracy.
  • 02Trigger physical actuation within sub-second end-to-end latency.
  • 03Stream telemetry to the cloud for monitoring and analytics.
  • 04Harvest passive energy from each crossing to extend battery life.
/ System architecture

How the pieces fit together

Two-tier IoT pipeline: a Raspberry Pi 4 handles vision + classification at the edge and delegates actuation to an Arduino Nano over UART. Sensor telemetry streams to the cloud over MQTT in parallel.

  1. Step 01
    Camera captures frame (Pi 4, OpenCV)
  2. Step 02
    ResNet50 classifies vehicle class
  3. Step 03
    Pi 4 sends action token to Arduino over UART
  4. Step 04
    Arduino drives servo PWM → speed-breaker height
  5. Step 05
    Piezo / BMS harvests vibration energy
  6. Step 06
    Pi 4 publishes telemetry to MQTT broker
  7. Step 07
    Dashboard consumes for analytics
/ Technologies used

Hardware, software & frameworks

Hardware
  • Raspberry Pi 4
  • Arduino Nano
  • USB camera
  • SG90 servo
  • PVDF piezo elements
  • BMS
Software
  • Python 3
  • Embedded C
  • OpenCV
  • PySerial
  • Mosquitto MQTT
Frameworks & libs
  • TensorFlow / Keras (ResNet50)
  • NumPy
  • scikit-learn (eval)
/ Development process

How it was built

Phase 01
Planning

Mapped the failure modes of conventional speed breakers, scoped the vehicle classes that matter (emergency, heavy, light, two-wheeler), and chose a two-MCU split so the safety-critical actuation never blocks on Python.

Phase 02
Design

Picked ResNet50 for its proven accuracy on small vehicle datasets, UART for its determinism over USB-CDC, and MQTT for low-overhead telemetry. Sketched the servo geometry and chose PWM duty cycles for each target height.

Phase 03
Development

Built the vision pipeline in OpenCV, wrapped inference behind a single classify(frame) call, defined a tight 3-byte UART protocol, and wrote the Arduino firmware as a small interrupt-driven state machine.

Phase 04
Testing

Validated end-to-end latency on bench, ran the model against a held-out vehicle set, and stress-tested the UART link with malformed frames. Logged confusion matrix and F1 per class before declaring the system shipping-ready.

/ Features

What it does

  • Real-time vehicle classification at the edge
  • Sub-second actuation latency
  • Emergency-vehicle bypass (always-flat for ambulances)
  • MQTT telemetry to cloud dashboard
  • Passive piezo energy harvesting + BMS
  • Resilient UART protocol with retry / checksum
/ Challenges

Problems faced & how I solved them

Problem 01

Python GIL stalls on inference caused jitter on the actuation command.

Solution

Moved the serial write to a separate thread and switched the Arduino to an interrupt-driven receive — actuation latency stayed flat regardless of Pi load.

Problem 02

Outdoor lighting variance dropped accuracy by 6–8 percentage points.

Solution

Added an OpenCV preprocessing stage (histogram equalisation + adaptive thresholding) before inference; recovered accuracy to within 1pp of the lab baseline.

Problem 03

Servo brown-out on simultaneous lift + Pi inference.

Solution

Split the rail: Pi on 5V/3A, servo on its own buck regulator from the harvester bank. Decoupled the failure mode entirely.

/ Learnings

What I'd take into the next build

  • 01A two-MCU architecture pays for itself the moment you put a real workload on the smart node.
  • 02OpenCV preprocessing is cheaper than collecting more data for lighting robustness.
  • 03Hardware decoupling (rails, not just code) is what survives field deployment.
Future roadmap
  • Quantise ResNet50 to TFLite for 3–4× inference speedup on the Pi.
  • Add a second camera for stereo speed estimation.
  • Move telemetry to MQTT-over-TLS for production deployment.

Like what you see?

I'm open to embedded, IoT, and edge-AI roles — full-time, internship, or freelance.