/*
Project: Smart Traffic Light
Description:
This project focuses on designing a smart traffic light system that manages
normal traffic flow while enhancing accessibility and safety for visually
impaired or disabled pedestrians.
Objectives:
- Provide standard traffic light functionality for vehicle control.
- Use sensor to detect vehicles and optimize signal timing.
- Prioritize crossing for people with disabilities (especially the visually impaired)
through interaction.
---------------------------------
Note:
please be aware that you might experience delays, limited functionality, or slower performance
These issues are more common in free version , which may not fully
support real-time execution or advanced features.
For a smoother experience, consider using paid version or testing directly
on hardware whenever possible.
developed by Rababe Ben Abdelhadi
*/
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED Display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Define GPIO pins for lights
int redLightDriver = 12;
int yellowLightDriver = 14;
int greenLightDriver = 27;
int redLightPedestrian = 16;
int greenLightPedestrian = 17;
int buttonPin = 4;
// Ultrasonic Sensor (HC-SR04) Pins
int trigPin = 5;
int echoPin = 18;
// Timing variables
int defaultTrafficTime = 10; // Default countdown for traffic lights
int pedestrianTime = 10; // Countdown for pedestrian crossing
bool pedestrianRequested = false;
// Global distance variable
int distance = 0;
void setup() {
Serial.begin(115200);
// Pin Modes
pinMode(redLightDriver, OUTPUT);
pinMode(yellowLightDriver, OUTPUT);
pinMode(greenLightDriver, OUTPUT);
pinMode(redLightPedestrian, OUTPUT);
pinMode(greenLightPedestrian, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// OLED Initialization
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 initialization failed!");
for (;;);
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.display();
}
void prepare() {
for (int i = 0; i < 3; i++) {
digitalWrite(yellowLightDriver, HIGH);
delay(500);
digitalWrite(yellowLightDriver, LOW);
delay(500);
}
}
int getTrafficDuration() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2; // Update global distance variable
if (distance < 20) {
Serial.println("🚗 Vehicle detected! Extending green light.");
return defaultTrafficTime + 5;
}
return defaultTrafficTime;
}
void displayCountdown(String mode, int g,int timeLeft) {
display.clearDisplay();
display.setCursor(10, 10);
display.print(mode);
display.setCursor(10, 25);
display.print(g);
display.setCursor(10, 40);
display.print("Time: ");
display.print(timeLeft);
display.display();
}
void light() {
Serial.println("🚦 Normal Traffic Mode");
digitalWrite(greenLightDriver, HIGH);
digitalWrite(yellowLightDriver, LOW);
digitalWrite(redLightDriver, LOW);
digitalWrite(greenLightPedestrian, LOW);
digitalWrite(redLightPedestrian, HIGH);
int timeRemaining = getTrafficDuration();
for (int i = timeRemaining; i > 0; i--) {
displayCountdown("distance:",distance, i);
if (digitalRead(buttonPin) == LOW) {
Serial.println("🟢 Button Press Detected! Switching to Pedestrian Mode.");
pedestrianRequested = true;
return;
}
delay(1000);
}
digitalWrite(greenLightDriver, LOW);
prepare();
digitalWrite(redLightDriver, HIGH);
digitalWrite(greenLightPedestrian, HIGH);
digitalWrite(redLightPedestrian, LOW);
for (int i = pedestrianTime; i > 0; i--) {
displayCountdown("distance:",distance,i);
delay(1000);
}
digitalWrite(greenLightPedestrian, LOW);
digitalWrite(redLightPedestrian, HIGH);
}
void blindfeat() {
Serial.println("🔵 Pedestrian Mode Activated!");
digitalWrite(greenLightDriver, LOW);
prepare();
digitalWrite(redLightPedestrian, LOW);
digitalWrite(greenLightPedestrian, HIGH);
digitalWrite(redLightDriver, HIGH);
for (int i = pedestrianTime; i > 0; i--) {
displayCountdown( "distance:",distance,i);
delay(1000);
}
digitalWrite(redLightDriver, LOW);
prepare();
digitalWrite(greenLightDriver, HIGH);
digitalWrite(redLightPedestrian, HIGH);
digitalWrite(greenLightPedestrian, LOW);
pedestrianRequested = false;
}
void loop() {
if (digitalRead(buttonPin) == LOW) {
Serial.println("🟢 Button Press Detected! Switching to Pedestrian Mode.");
pedestrianRequested = true;
}
if (pedestrianRequested) {
blindfeat();
} else {
light();
}
}