Skip to content

VisaiCyber/Smart-Traffic-Light-System-Using-Real-Time-Object-Detection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TRAFFICOS: Smart Traffic Light System Using Real-Time Object Detection

IoT Final Project | School of Digital Technologies Team 10: HOEUN Visai Β· CHHOEUN Sovorthanak Β· KEAN Youhorng Β· EK Panhawath


Table of Contents

  1. Project Overview
  2. System Architecture
  3. Hardware Components
  4. Wiring Diagram
  5. Decision Logic
  6. Object Detection Model: YOLO11
  7. Software Stack
  8. Setup & Installation
  9. How to Run
  10. Web Dashboard
  11. Demo Video
  12. Project Structure

Project Overview

TRAFFICOS is an IoT-based smart traffic light system that combines computer vision, embedded systems, and real-time communication to intelligently control traffic signals at a simulated 2-road intersection.

Unlike traditional fixed-timer traffic lights, TRAFFICOS:

  • Detects vehicles in real time using YOLO11 AI object detection
  • Confirms vehicle presence physically using an ultrasonic distance sensor
  • Prioritizes the road with more waiting vehicles
  • Adapts green time based on traffic density
  • Provides a live web dashboard for remote monitoring and manual override

The system uses toy cars on a model intersection to simulate real-world traffic conditions.

Key Features

Feature Description
Live YOLO detection YOLO11n running on PC, fed by 2 ESP32-CAM streams
Ultrasonic confirmation Road A verifies car is within 10cm before opening green
Priority algorithm Higher car count wins; tie broken by waiting time
Environment sensing DHT11 reads temperature and humidity
Buzzer alerts Warns drivers during yellow transition
TM1637 display Shows current time (HH:MM) on the physical model
Web dashboard Real-time monitoring, manual override, ultrasonic toggle

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        SENSING LAYER                            β”‚
β”‚                                                                 β”‚
β”‚   ESP32-CAM A           ESP32-CAM B                             β”‚
β”‚   (Road A feed)         (Road B feed)                           β”‚
β”‚        β”‚                     β”‚                                  β”‚
β”‚        └──── Wi-Fi β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ MJPEG stream (:81/stream)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      PROCESSING LAYER                           β”‚
β”‚                                                                 β”‚
β”‚              Computer (Python β€” server.py)                      β”‚
β”‚        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”‚
β”‚        β”‚  YOLO11n   β†’   Count vehicles/road   β”‚                 β”‚
β”‚        β”‚  Flask     β†’   Serve web dashboard   β”‚                 β”‚
β”‚        β”‚  Serial    β†’   Send JSON to ESP32    β”‚                 β”‚
β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ USB Serial: {"countA":2,"countB":1}
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CONTROL LAYER                              β”‚
β”‚                                                                 β”‚
β”‚        ESP32-WROOM-32 (traffic_controller_v10.ino)              β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚   β”‚  Priority Algorithm  β†’  State Machine  β†’  GPIO pins  β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚        β”‚           β”‚           β”‚           β”‚                    β”‚
β”‚      LEDs A      LEDs B     Buzzer      TM1637                  β”‚
β”‚      R/Y/G       R/Y/G      (warn)    (clock)                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MONITORING LAYER                             β”‚
β”‚         Web Dashboard β†’ http://localhost:5000                   β”‚
β”‚    Live streams Β· Vehicle counts Β· Signal status Β· Sensors      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Communication Flow

ESP32-CAM A/B  ──[Wi-Fi MJPEG]──▢  PC (YOLO11)  ──[USB Serial JSON]──▢  ESP32 Controller
                                        β”‚
                                        β–Ό
                                   Web Dashboard
                                  (http://localhost:5000)

Hardware Components

ESP32 Controller (traffic_controller_v10.ino)

Component Purpose Quantity
ESP32-WROOM-32 Main controller 1
Red LED + 220Ξ© resistor Traffic light β€” Road A 1
Yellow LED + 220Ξ© resistor Traffic light β€” Road A 1
Green LED + 220Ξ© resistor Traffic light β€” Road A 1
Red LED + 220Ξ© resistor Traffic light β€” Road B 1
Yellow LED + 220Ξ© resistor Traffic light β€” Road B 1
Green LED + 220Ξ© resistor Traffic light β€” Road B 1
HC-SR04 Ultrasonic sensor Vehicle distance β€” Road A 1
DHT11 Temperature sensor Environment monitoring 1
Active buzzer module Yellow phase warning 1
TM1637 4-digit display Current time (HH:MM) 1

Camera System

Component Purpose Quantity
ESP32-WROOM-32 Camera host 2
OV3660 / compatible camera Video capture per road 2

Computer (Processing)

  • Any laptop/PC with Python 3.10+
  • USB cable to ESP32 controller

Wiring Diagram

ESP32 Controller Pin Assignment

Component Pin ESP32 GPIO
Road A β€” Red LED Anode β†’ 220Ξ© GPIO 2
Road A β€” Yellow LED Anode β†’ 220Ξ© GPIO 4
Road A β€” Green LED Anode β†’ 220Ξ© GPIO 5
Road B β€” Red LED Anode β†’ 220Ξ© GPIO 22
Road B β€” Yellow LED Anode β†’ 220Ξ© GPIO 23
Road B β€” Green LED Anode β†’ 220Ξ© GPIO 25
Buzzer (active module) S pin GPIO 26
Buzzer + 5V (VIN)
Buzzer βˆ’ GND
HC-SR04 VCC 5V (VIN)
HC-SR04 TRIG GPIO 32
HC-SR04 ECHO GPIO 33
HC-SR04 GND GND
DHT11 VCC 3.3V
DHT11 DATA + 10kΞ© to 3.3V GPIO 15
DHT11 GND GND
TM1637 CLK GPIO 18
TM1637 DIO GPIO 19
TM1637 VCC 3.3V
TM1637 GND GND
All LEDs (cathode) Short leg GND (shared rail)

Note: All LEDs use 220Ξ© current-limiting resistors. DHT11 requires a 10kΞ© pull-up resistor on DATA to 3.3V.


Decision Logic

This is the core logic that satisfies the "combined camera + sensor" requirement.

Priority Algorithm

Step 1 β€” Pick priority road:
  IF only Road A has cars  β†’ A wins
  IF only Road B has cars  β†’ B wins
  IF both have cars        β†’ road with MORE cars wins
  IF equal count           β†’ road that waited LONGER wins
  IF nobody has cars       β†’ ALL RED (keep checking)

Step 2 β€” Confirm with ultrasonic (Road A only):
  IF winner is A AND distance < 10cm  β†’ open GREEN
  IF winner is A AND distance >= 10cm β†’ car not at line yet, wait
  IF winner is B                      β†’ open GREEN (camera only)

State Machine

ALL RED ──[car detected + confirmed]──▢ GREEN (direct, no yellow)
  GREEN ──[car still present]─────────▢ GREEN (stays indefinitely)
  GREEN ──[car gone Γ— 5 frames]───────▢ YELLOW (2s warning + buzzer)
 YELLOW ──[2s elapsed]───────────────▢ ALL RED (0.8s safety gap)
ALL RED ──[evaluate priority again]──▢ next road GREEN

Green Time Formula

green_time = 5s + (vehicle_count Γ— 2s)
min: 5 seconds | max: 30 seconds

Miss Counter (Anti-Flicker)

To prevent a single missed YOLO detection frame from triggering yellow, the system requires 5 consecutive missed detections before acting. This makes the system robust against momentary occlusion or camera angle issues.

Decision Logic Flowchart

YOLO detects car on Road A?
        β”‚
    YES β”œβ”€β”€β–Ά Ultrasonic < 10cm?
        β”‚         β”‚
        β”‚     YES β”œβ”€β”€β–Ά Road A GREEN 
        β”‚         β”‚
        β”‚      NO └──▢ Wait (car approaching)
        β”‚
     NO └──▢ YOLO detects car on Road B?
                 β”‚
             YES └──▢ Road B GREEN (no distance check)
                 β”‚
              NO └──▢ ALL RED (no cars anywhere)

Object Detection Model: YOLOv11

Overview

TRAFFICOS uses YOLO11 (You Only Look Once, version 11) developed by Ultralytics, the latest generation of the YOLO family. The model is loaded via the ultralytics Python library and runs entirely on the host PC β€” no GPU required for real-time inference at reduced resolution.

Two model weight files are included in the project to allow easy switching:

Model File Variant Parameters Size mAP50-95 Best For
yolo11n.pt Nano (default) ~2.6M ~5.4 MB 39.5 Low-latency, CPU inference
yolo11s.pt Small ~9.4M ~18.4 MB 47.0 Better accuracy on front-facing/partial vehicles

The default model used is yolo11n.pt (Nano), selected for its sub-2ms inference speed which allows real-time detection at 15 FPS across two simultaneous camera streams on a standard laptop CPU.

Model Architecture

YOLO11 introduces several architectural improvements over its predecessors:

Component Description
C3k2 Blocks Lightweight cross-stage partial bottleneck with two smaller kernels for efficient feature extraction
SPPF Spatial Pyramid Pooling – Fast, aggregates multi-scale spatial features in the backbone
C2PSA Convolutional block with Parallel Spatial Attention, improves localization of small/distant objects

This architecture achieves higher accuracy per parameter than YOLOv8 and earlier models, making it ideal for embedded and near-edge deployment.

Training Dataset β€” MS COCO

The pre-trained yolo11n.pt model was trained on the MS COCO (Microsoft Common Objects in Context) dataset:

  • 80 object classes covering everyday scenes (people, animals, vehicles, furniture, etc.)
  • 118,000+ training images with 1.5M labeled object instances
  • Standard benchmark for object detection research and deployment

Vehicle Classification

TRAFFICOS uses a class-ID filter to count only vehicle-type objects from YOLO's 80-class output:

COCO Class ID Label Included Reason
2 car Yes Primary vehicle type
3 motorcycle Yes Two-wheelers counted as vehicles
5 bus Yes Large public transit vehicles
7 truck Yes Commercial/heavy vehicles
0 person No Pedestrians excluded
9 traffic light No Infrastructure, not traffic

In code (server.py):

VEHICLE_CLASSES = {2, 3, 5, 7}  # car, motorcycle, bus, truck

Inference Configuration

Parameter Value Rationale
Confidence threshold 0.25 Lower than default (0.5) to catch partial, front-facing, and toy vehicle detections
Detection resolution 320Γ—240 px Frame downscaled before inference to reduce latency without significant accuracy loss
Inference frequency Every 3rd frame YOLO_EVERY_N_FRAMES = 3 β€” balances CPU load vs. detection responsiveness
Stream FPS cap 15 FPS STREAM_INTERVAL = 1/15 β€” limits bandwidth and processing overhead
JPEG quality 60% Compressed dashboard stream to reduce network bandwidth

Switching to the Small Model

To improve detection accuracy (at a slight speed cost), change the model path in server.py:

# In server.py β€” line 30
MODEL_PATH = "yolo11s.pt"   # Switch from nano β†’ small for better accuracy

The yolo11s.pt file is already included in the repository. The small model is especially recommended if the camera angle captures vehicles head-on (front-facing), which the nano model can sometimes miss.


Software Stack

Layer Technology File
Object Detection YOLO11n (Ultralytics) server.py
Web Server Flask (Python) server.py
Camera Streaming OpenCV + MJPEG server.py
ESP32 Firmware Arduino C++ traffic_controller_v10/traffic_controller_v10.ino
Web Dashboard HTML + CSS + Chart.js dashboard/index.html
Serial Protocol JSON over USB (9600 baud) both sides

Libraries Required

Python (pip install):

pip install flask ultralytics opencv-python pyserial

Arduino IDE (Manage Libraries):

  • ArduinoJson by Benoit Blanchon
  • DHT sensor library by Adafruit
  • Adafruit Unified Sensor by Adafruit
  • TM1637 by Avishay Orpaz

Setup & Installation

1. Clone the repository

git clone https://github.com/YOUR_USERNAME/trafficos.git
cd trafficos

2. Install Python dependencies

pip install flask ultralytics opencv-python pyserial

3. Flash ESP32-CAM firmware

  • Open Arduino IDE
  • Board: ESP32 Dev Module or AI Thinker ESP32-CAM
  • Flash the CameraWebServer example (built into Arduino IDE)
  • Set your Wi-Fi SSID and password in the sketch
  • Note the IP address printed on Serial Monitor after boot

4. Flash the traffic controller

  • Open traffic_controller_v10/traffic_controller_v10.ino in Arduino IDE
  • Board: ESP32 Dev Module
  • Port: your ESP32 controller COM port (e.g. COM6)
  • Upload

5. Configure server

Edit server.py:

CAMERA_A    = "http://YOUR_CAM_A_IP:81/stream"
CAMERA_B    = "http://YOUR_CAM_B_IP:81/stream"
SERIAL_PORT = "COM6"   # your controller ESP32 port

How to Run

Step 1 β€” Power on hardware

  • Plug ESP32 controller into PC via USB
  • Power on both ESP32-CAMs (USB or power bank)
  • Confirm camera IPs by opening http://CAMERA_IP/ in browser

Step 2 β€” Run the server

python server.py

Expected output:

[INFO] Loading YOLO model...
[INFO] Model ready! conf=0.25
[INFO] Serial on COM6
[INFO] Time synced: 14:30
[Cam A] Connected!
[Cam B] Connected!

[INFO] Dashboard β†’ http://localhost:5000

Step 3 β€” Open dashboard

Navigate to http://localhost:5000 in any browser on the same network.


Web Dashboard

The TRAFFICOS dashboard (http://localhost:5000) provides:

Panel Description
Live Detection Feed Side-by-side YOLO detection streams for Road A and Road B
Signal Status Animated traffic light showing current state (RED/YELLOW/GREEN)
AUTO / MANUAL toggle Switch between automatic AI control and manual override
Road A / Road B controls Independent RED / YELLOW / GREEN buttons per road
Ultrasonic toggle Enable/disable distance verification for Road A
Live Stats Vehicle count per road, active road, current mode
Sensor Data Temperature (Β°C), humidity (%), distance (cm)
Vehicle Count Chart 60-second history graph for both roads
Event Log Timestamped log of all state changes

Demo Video

Watch on YouTube

Video covers:

  • Team introduction and system name
  • System architecture walkthrough
  • Decision logic explanation
  • Live demonstration with toy cars
  • Behind the scenes (wiring, code, dashboard)

Project Structure

trafficos/
β”‚
β”œβ”€β”€ server.py                            # Flask server: YOLO detection + serial + API
β”‚
β”œβ”€β”€ dashboard/
β”‚   └── index.html                       # Web dashboard (single file)
β”‚
β”œβ”€β”€ traffic_controller_v10/
β”‚   └── traffic_controller_v10.ino       # ESP32 Arduino firmware (final version)
β”‚
β”œβ”€β”€ yolo11n.pt                           # YOLO11 nano model weights (default, ~5.4 MB)
β”œβ”€β”€ yolo11s.pt                           # YOLO11 small model weights (higher accuracy, ~18.4 MB)
β”‚
└── README.md                            # This file

Evaluation Criteria Met

Criterion Weight Status
Camera / Vision System 20% YOLO11n + 2Γ— ESP32-CAM
Sensor & Actuator Integration 20% DHT11 + HC-SR04 + LEDs + Buzzer + TM1637
Decision Logic 10% Camera AND ultrasonic combined
Code Quality 10% Clean, commented, modular
Video Explanation 15% See demo video above
In-Class Presentation 20% Live demo ready
Creativity 5% Web dashboard + AI + real-time
Total 100% All criteria addressed

πŸ“„ License

This project was developed for academic purposes at the American University of Phnom Penh. All rights reserved by the authors.


ICT-360 - Introduction to Internet of Things | American University of Phnom Penh | May 30, 2026

About

🚦 Smart traffic light system using YOLO11 real-time vehicle detection, ESP32 control, HC-SR04 ultrasonic sensor, and a live web dashboard β€” built for intelligent intersection management.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors