-
Notifications
You must be signed in to change notification settings - Fork 4
G17: Smart Red Light Violation Detection System
| Name | GitHub |
|---|---|
| Yousef Sayed | yousefsebaie |
| Marwan Abudaif | MarwanMoh11 |
| Hadi Hesham | Hadihesham |
GitHub Repo: https://github.com/MarwanMoh11/smart-redlight-tm4c123
Running red lights is a leading cause of serious traffic accidents in Egypt and worldwide. Traffic officers cannot manually monitor every intersection around the clock, and without automated evidence capture, authorities have no reliable way to issue fines or deter repeat offenders. Simple motion-based detection systems can also mistake pedestrians or random movement for violating vehicles, creating false alarms.
Our project is the Smart Red Light Violation Detection System — an embedded real-time system that detects vehicles crossing a stop line during the red light phase, captures photographic evidence, and logs every violation with a timestamp to a PC. The system uses two Force-Sensitive Resistors (FSRs) placed in sequence at the stop line: one for the front axle and one for the rear axle. A real vehicle should press the first pressure sensor and then the second pressure sensor within a calibrated time window. This front-then-rear sequence allows the firmware to distinguish a vehicle from a pedestrian, because a pedestrian or random touch usually presses only one sensor or does not produce the correct axle sequence.
The firmware runs on a TI Tiva C TM4C123GXL Launchpad using FreeRTOS with six concurrent tasks: sensor detection, violation logic, traffic light cycle, alert, camera capture, and UART logging. When a valid vehicle event occurs during the red phase, the violation event is sent to three independent handlers: an alert handler that flashes the onboard RGB LED, a camera handler that triggers photo capture, and a logging handler that writes a timestamped record to the PC terminal. This system demonstrates a practical embedded application of multitasking, queues, priority scheduling, shared state, ADC sensing, and event-driven violation handling.
- Automatic traffic light cycle: GREEN → YELLOW → RED
- Detection active only during the RED light phase
- Dual-FSR pressure-sensor vehicle detection at the stop line
- Front-axle and rear-axle sequence detection
- Pedestrian and false-trigger filtering using axle order and timing window
- Full FreeRTOS architecture with 6 concurrent tasks
- Inter-task communication using queues, task priorities, shared state, and UART synchronization
- Fan-out dispatch: each confirmed violation triggers alert, camera, and log handlers
- Visual alert on confirmed violation using the onboard RGB LED
- Photo capture of the violating vehicle using a laptop webcam
- UART event logging to PC terminal with timestamps
- 16x2 LCD display showing current light state and violation count
- Manual override buttons: force red light and reset counter
- Persistent violation count stored in flash memory
- Emergency vehicle exemption mode
- Multi-lane support by replicating the hardware unit per lane
- Dedicated external flash LED synchronized with camera capture
| Subsystem | Description |
|---|---|
| Sensor subsystem | Two FSR pressure sensors are the primary vehicle detector. FSR_A is connected to PE3 / ADC0 CH0 and represents the front axle sensor. FSR_B is connected to PE2 / ADC0 CH1 and represents the rear axle sensor. Both sensors are read through the ADC and polled periodically. The firmware confirms a vehicle only when the correct FSR sequence occurs within a calibrated timing window. The HC-SR04 ultrasonic sensor on PB0/PB1 is kept as a secondary approach indicator only and does not directly trigger violations. |
| Traffic light subsystem |
LightTask drives the onboard RGB LED. GREEN is PF3, RED is PF1, and YELLOW is produced using PF1 + PF3. The light state is stored in the shared volatile variable g_current_light, which is read by ViolationTask. |
| Violation logic subsystem |
ViolationTask receives vehicle-detection events from the sensor queue. It checks whether g_current_light == LIGHT_RED. If the light is not red, the event is ignored. If the light is red, the task builds a violation_record_t and sends it to the alert, camera, and log queues. |
| Alert subsystem |
AlertTask receives violation records and produces a visual flicker on the onboard RGB LED. This provides immediate visible feedback when a violation is detected. |
| Camera subsystem |
CameraTask receives violation records and triggers photo capture of the violating vehicle. The original ESP32-CAM was replaced by a laptop webcam after firmware issues. |
| Logging subsystem |
LogTask receives violation records and writes timestamped messages to UART0 at 115200 baud. UART access is protected so that different tasks do not interleave their output. Logs are viewed on the PC using picocom. |
| Component | Purpose | Notes |
|---|---|---|
| TI Tiva C TM4C123GXL Launchpad | Main MCU | ARM Cortex-M4F, 80 MHz, 256 KB Flash, 32 KB SRAM. Runs FreeRTOS and all six tasks. |
| 2x Force-Sensitive Resistors | Primary vehicle detection | Used as front and rear axle pressure sensors. FSR_A is connected to PE3 / ADC0 CH0, and FSR_B is connected to PE2 / ADC0 CH1. |
| HC-SR04 Ultrasonic Sensor | Secondary approach indicator | TRIG on PB0 and ECHO on PB1. Used only as an approach indicator, not as the primary violation trigger. |
| ESP32-CAM | Photograph capture | PD7,FTDI |
| Onboard RGB LED | Traffic light simulation and violation alert | PF1 for red, PF3 for green, and PF1 + PF3 for yellow. |
| Breadboard + jumper wires | Prototyping | Used for wiring and testing. |
| USB to PC | Power, flashing, and UART logging | Provides board power and PC serial communication. |
Each FSR is wired as a voltage divider. The midpoint of the divider is connected to an ADC input pin so the TM4C123GXL can read the pressure level as an analog value.
| FSR Sensor | Tiva Pin | ADC Channel | Role |
|---|---|---|---|
| FSR_A | PE3 | ADC0 CH0 | Front axle sensor |
| FSR_B | PE2 | ADC0 CH1 | Rear axle sensor |
| HC-SR04 Pin | Tiva Silkscreen | Port/Pin |
|---|---|---|
| VCC | +3.3V | — |
| TRIG | PB0 | GPIO_PORTB_BASE, GPIO_PIN_0 |
| ECHO | PB1 | GPIO_PORTB_BASE, GPIO_PIN_1 |
| GND | GND | — |
Important: The HC-SR04 is powered from 3.3V instead of 5V so that the ECHO signal remains safe for the TM4C123GXL input pin.
| Color | Pin | FreeRTOS State |
|---|---|---|
| Red | PF1 | LIGHT_RED |
| Blue | PF2 | Unused in traffic cycle |
| Green | PF3 | LIGHT_GREEN |
| Yellow | PF1 + PF3 | LIGHT_YELLOW |
| Signal | Port/Connection | Purpose |
|---|---|---|
| Camera trigger | Laptop webcam / host-side capture | Captures image on violation event |
| Debug UART TX | PA1 / U0TX | UART logging at 115200 baud |
| Debug UART RX | PA0 / U0RX | Serial receive line if needed |
| Button | Pin | Function |
|---|---|---|
| SW1 | PF4 | Force RED phase |
| SW2 | PF0 | Reset violation counter |
| Component | Qty | Estimated Cost |
|---|---|---|
| TI Tiva C TM4C123GXL Launchpad | 1 | ~2000 EGP |
| Force-Sensitive Resistors | 2 | ~1000 EGP |
| HC-SR04 Ultrasonic Sensor | 1 | ~60 EGP |
| Esp32-CAM | 1 | ~900 EGP |
| Breadboard + jumper wires | 1 set | ~20 EGP |
| USB cable | 1 | Existing / reused |
| Total | ~4000 EGP |
| Component | Supply | Typical Current | Peak Current |
|---|---|---|---|
| TM4C123GXL MCU | 3.3V | ~30 mA | ~50 mA |
| FSR voltage dividers x2 | 3.3V | <1 mA | <1 mA |
| HC-SR04 | 3.3V | ~15 mA | ~15 mA |
| Onboard RGB LED | 3.3V | ~3 mA | ~3 mA |
| ESP32_Cam | 5v | drawn from board | drawn from board |
| 3.3V rail total | ~49 mA | ~69 mA |
The Launchpad onboard regulator supplies enough current for the MCU, pressure sensors, ultrasonic approach sensor, and onboard LED. The laptop webcam is powered by the host PC and does not draw power from the Launchpad.
The firmware is implemented as a FreeRTOS preemptive multitasking application targeting the TM4C123GXL at 80 MHz. The clock is configured using SysCtlClockSet with the PLL from a 16 MHz crystal. The FreeRTOS tick rate is 1 ms using configTICK_RATE_HZ = 1000, which gives millisecond-level timing for task delays, timestamps, and sensor timing windows.
Six tasks are created in main() before calling vTaskStartScheduler().
| Task | Stack | Priority | Responsibility |
|---|---|---|---|
| ViolationTask | 256 words | 4 | Blocks on the sensor queue, checks whether the light is red, builds a violation record, and sends it to the alert, camera, and log queues. |
| LightTask | 256 words | 3 | Cycles GREEN → YELLOW → RED and updates g_current_light. |
| AlertTask | 256 words | 3 | Blocks on xAlertQueue and produces a visible LED flicker. |
| CameraTask | 256 words | 2 | Blocks on xCameraQueue and triggers photo capture. |
| LogTask | 512 words | 2 | Blocks on xLogQueue and writes timestamped violation records to UART0. |
| SensorTask | 512 words | 1 | Polls the two FSR pressure sensors, runs the axle-detection state machine, and posts SENSOR_VEHICLE_DETECTED to xSensorEventQueue. It also polls the HC-SR04 approach indicator. |
ViolationTask has the highest priority because it should react immediately once a valid vehicle event is posted. SensorTask runs at the lowest priority because it polls periodically and uses vTaskDelay, so it does not starve the other tasks.
| Queue / Shared Object | Item Type | Depth | Producer → Consumer |
|---|---|---|---|
xSensorEventQueue |
sensor_event_t |
8 | SensorTask → ViolationTask |
xAlertQueue |
violation_record_t |
4 | ViolationTask → AlertTask |
xCameraQueue |
violation_record_t |
4 | ViolationTask → CameraTask |
xLogQueue |
violation_record_t |
16 | ViolationTask → LogTask |
g_current_light |
light_state_t |
— | LightTask → ViolationTask |
xUartMutex |
Mutex | — | Protects UART output |
g_current_light is a volatile shared variable. It has one writer, LightTask, and one reader, ViolationTask. Since it is a simple light-state value on a 32-bit MCU, a mutex is not required for this variable. UART output is protected separately using xUartMutex.
flowchart LR
A[FSR_A Front Axle Sensor] -->|ADC value| B[SensorTask]
A2[FSR_B Rear Axle Sensor] -->|ADC value| B
U[HC-SR04 Approach Indicator] -->|distance only| B
B -->|SENSOR_VEHICLE_DETECTED| C[ViolationTask]
L[LightTask] -->|g_current_light| C
C -->|if RED| D[AlertTask]
C -->|if RED| E[CameraTask]
C -->|if RED| F[LogTask]
D -->|visual flicker| G[Onboard RGB LED]
E -->|capture request| H[Laptop Webcam]
F -->|UART 115200 baud| I[PC Terminal]
L -->|traffic light state| G
stateDiagram-v2
[*] --> GREEN
GREEN --> YELLOW: after 6000 ms
YELLOW --> RED: after 2000 ms
RED --> GREEN: after 5000 ms
stateDiagram-v2
[*] --> S_IDLE
S_IDLE --> S_A_HIT: FSR_A pressed first
S_IDLE --> S_LOCKED: both sensors pressed together
S_A_HIT --> S_LOCKED: FSR_B pressed within valid gap
S_A_HIT --> S_LOCKED: timeout, invalid object
S_A_HIT --> S_IDLE: FSR_A released without FSR_B
S_LOCKED --> S_IDLE: both sensors released
flowchart TD
A[Wait for sensor event] --> B{Vehicle detected?}
B -->|No| A
B -->|Yes| C{Is light RED?}
C -->|No| D[Discard as legal pass]
D --> A
C -->|Yes| E[Build violation_record_t]
E --> F[Send to Alert Queue]
E --> G[Send to Camera Queue]
E --> H[Send to Log Queue]
F --> A
G --> A
H --> A
The two FSRs share one ADC sequencer and are read together in a single conversion. The sensor task triggers the ADC, waits for conversion completion, and reads both ADC channels into a buffer. Channel 0 corresponds to FSR_A, and channel 1 corresponds to FSR_B.
A higher ADC count means a stronger press on the pressure sensor. The firmware uses these ADC values to determine whether each pressure sensor is currently pressed or released.
The FSR thresholds were calibrated empirically by comparing idle readings with pressed readings. When there is no pressure, the ADC value is low. When the sensor is pressed firmly, the ADC value becomes much higher. Based on this behavior, the firmware uses a high press threshold and a lower release threshold.
#define FSR_PRESS_THRESHOLD 1000
#define FSR_RELEASE_THRESHOLD 200This creates hysteresis. The sensor is considered pressed only when the reading goes above 1000, but it is not considered released until the reading drops below 200. This prevents flickering when the ADC value is noisy or close to the threshold boundary.
The pedestrian filter is implemented through the front-axle and rear-axle sequence. A real vehicle should press FSR_A first and then FSR_B within a calibrated time window.
#define FSR_AB_GAP_MS_MIN 50
#define FSR_AB_GAP_MS_MAX 3000
#define FSR_POLL_PERIOD_MS 50The logic works as follows:
- In
S_IDLE, the system waits for a valid first press. - If
FSR_Ais pressed first, the system records the tick time and moves toS_A_HIT. - If
FSR_Bis pressed afterFSR_Awithin the valid timing window, the system confirms a vehicle. - If the time exceeds the maximum gap, the event is ignored.
- If
FSR_Ais released beforeFSR_Bis pressed, the event is ignored. - After a confirmed or invalid event, the system enters
S_LOCKEDuntil both sensors are released, preventing double counting.
This is how the system filters pedestrians and random false triggers. A pedestrian or accidental touch usually does not create the correct two-sensor axle sequence.
The HC-SR04 is kept as a secondary approach indicator. It does not directly create violation events. It only helps indicate when an object is near the stop line.
The ultrasonic sensor is triggered using a short HIGH pulse on PB0. The firmware measures the ECHO pulse width on PB1 and converts it to a distance reading. Invalid readings are treated as out of range.
ViolationTask uses non-blocking queue sends to dispatch one confirmed violation record to three independent consumers:
xAlertQueuexCameraQueuexLogQueue
This means the alert, camera, and logging functions are separated. If one downstream task is slow, the violation logic is not directly tied to it.
| Tool | Details |
|---|---|
| Toolchain | gcc-arm-none-eabi |
| Linker / Assembler | binutils-arm-none-eabi |
| C Library | libnewlib-arm-none-eabi |
| Build system | GNU Make |
| FreeRTOS Kernel | V11.1.0 |
| TivaWare DriverLib | SW-TM4C-2.2.0.295 |
| Flasher | lm4flash |
| Serial monitor | picocom -b 115200 /dev/ttyACM0 |
| OS | Ubuntu 22.04 / Linux Mint 21 |
| IDE | Text editor + terminal |
git clone https://github.com/MarwanMoh11/smart-redlight-tm4c123.git
cd smart-redlight-tm4c123
make
make flash
picocom -b 115200 /dev/ttyACM0 text data bss dec hex filename
11000 8 21800 32808 8028 build/redlight.elf
| Module | Test Method | Pass Criterion |
|---|---|---|
FSR_ReadBoth() |
Read raw ADC values with no press, light press, and firm press. | Idle readings stay low; firm press rises clearly above the press threshold. |
| Threshold / hysteresis | Pressed and slowly released each FSR. | Clean press above 1000 and release below 200, without unstable flickering. |
| Axle state machine | Pressed FSR_A then FSR_B at different gaps. |
Vehicle event only when both sensors are pressed in the correct order within the valid window. |
| Wrong-order rejection | Pressed FSR_B before FSR_A. |
No vehicle event is generated. |
| Single-sensor rejection | Pressed only one FSR. | No vehicle event is generated. |
LightTask timing |
Measured phase durations using UART phase-start markers. | GREEN about 6 seconds, YELLOW about 2 seconds, RED about 5 seconds. |
ViolationTask dispatch |
Injected SENSOR_VEHICLE_DETECTED while forcing RED state. |
Alert, camera, and log handlers all receive the violation. |
LogTask output |
Checked UART format and incrementing counter. | Correct violation message printed with violation number and tick timestamp. |
| Phase | Action | Expected Result |
|---|---|---|
| GREEN | Press FSR_A then FSR_B in sequence. |
No violation. Legal pass is ignored. |
| YELLOW | Press FSR_A then FSR_B in sequence. |
No violation. Legal pass is ignored. |
| RED | Press only one FSR. | No violation. Pedestrian / false trigger rejected. |
| RED | Press FSR_B before FSR_A. |
No violation. Wrong axle order rejected. |
| RED | Press FSR_A then FSR_B within the valid gap window. |
Violation confirmed: LED flicker, UART log, and camera capture. |
| RED repeated | Two back-to-back valid A→B sequences. | Two separate records are generated after proper re-arm. |
=== Smart Red Light System Online ===
Press FSR_A then FSR_B during RED phase to trigger violation.
--- GREEN ---
--- YELLOW ---
--- RED (detection active) ---
[APPROACH] object near stop line
>>> VIOLATION #1 at tick=12345 (light=RED)
[CAMERA] capture_request tick=12345 -> img_12345.jpg
--- GREEN ---
| Challenge | Root Cause | Solution |
|---|---|---|
| Boot loop or banner repeating | Stack overflow in SensorTask. |
Increased SensorTask stack from 256 to 512 words. |
| LED stuck on GREEN | Sensor polling was too aggressive and could starve other tasks. | Added periodic vTaskDelay and kept sensor polling at a fixed rate. |
| Double violation events | One vehicle could be counted more than once. | Added the S_LOCKED state so the system re-arms only after both FSRs are released. |
| UART garbled output | More than one task could write to UART at the same time. | Protected UART output using xUartMutex. |
| FSR readings unstable near threshold | ADC readings fluctuated near the boundary. | Added hysteresis using a high press threshold and a lower release threshold. |
| HC-SR04 always reads 0 cm | TRIG and ECHO pins were swapped on the breadboard. | Verified wiring against silkscreen and added a startup pin-configuration check. |
| ESP32-CAM | The module entered a burnout cycle and stopped working. | Managed to work. |
make flash permission denied |
User did not have serial-device permissions. | Added user to dialout and plugdev, installed udev rules, and logged in again. |
The current build runs fully on the TM4C123GXL Launchpad. The two FSR pressure sensors are connected to PE3 and PE2 and act as the primary vehicle detector. The HC-SR04 is connected to PB0 and PB1 and acts only as a secondary approach indicator. The onboard RGB LED acts as both the traffic light and the visual violation alert. All six FreeRTOS tasks are active and communicate through queues. Photo capture is handled by a laptop webcam triggered on each violation event, and UART output is viewed in real time through picocom at 115200 baud.
Photos of the completed breadboard setup should be added after the final demo build.
Demo video link should be added before the final presentation.
| Metric | Target | Measured |
|---|---|---|
| FSR poll rate | 20 Hz / 50 ms period | 20 Hz verified by UART timing |
| Traffic light phase accuracy | ±100 ms | ±50 ms |
| Violation detection latency | Less than 100 ms after rear axle press | About 50 ms |
| Pedestrian false positive rate | 0% for single-sensor presses | 0% across single-FSR tests |
| Wrong-order rejection | 0% false positives | FSR_B before FSR_A always rejected |
| Missed violations | 0% for valid A→B passes | 10 out of 10 valid passes detected |
| UART log latency | Less than one scheduler cycle | Less than 2 ms |
| Team Member | Primary Responsibilities |
|---|---|
| Yousef Sayed | Hardware wiring, FSR sensor interfacing, sensor task implementation, axle-detection and pedestrian-filter firmware, violation logic. |
| Marwan Abudaif | Camera integration, traffic light task, timing cycle, system integration,build system, and ADC threshold calibration. |
| Hadi Hesham | UART logging task, PC terminal protocol, alert task, wiki documentation, proposal, final presentation, and integration testing. |
All team members collaborated on:
- System integration and debugging
- Edge-case testing
- Pedestrian-filter validation
- Partial-crossing and timeout handling
- Demo preparation and rehearsal
- Final presentation delivery
| Date | Milestone | Status |
|---|---|---|
| Apr 15 | Proposal presentation | Complete |
| Apr 20 | Wiki page live / Checkpoint A | Complete |
| Apr 20 – Apr 28 | Core firmware: sensor reading, traffic light cycle, and state machine | Complete |
| Apr 29 | Progress demo: live violation detection working | Complete |
| Apr 30 – May 5 | Full integration: FSR sensors, camera capture, alert, and UART logging | Complete |
| May 6 | Integration update / Checkpoint B | Complete |
| May 7 – May 12 | Bug fixes, threshold tuning, edge-case testing, and demo rehearsal | In progress |
| May 13 | Final demo and presentation | Pending |
https://github.com/MarwanMoh11/smart-redlight-tm4c123
-
Texas Instruments, TM4C123GH6PM Datasheet, SPMS376E.
https://www.ti.com/product/TM4C123GH6PM -
Texas Instruments, TivaWare Peripheral Driver Library User's Guide, SPMU298D.
-
FreeRTOS, FreeRTOS Documentation and Reference Manual.
https://www.freertos.org/Documentation/RTOS_book.html -
Elec Freaks, HC-SR04 Ultrasonic Sensor Datasheet.
-
Interlink Electronics, FSR Integration Guide.
https://www.interlinkelectronics.com/fsr-402