#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialize LCD (Address 0x27 is standard for Wokwi I2C LCDs)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --- Pin Definitions ---
// Lane 1
const int green1 = 2, yellow1 = 3, red1 = 4;
const int trig1 = 8, echo1 = 9;
// Lane 2
const int green2 = 5, yellow2 = 6, red2 = 7;
const int trig2 = 10, echo2 = 11;
// Base timing
const int baseGreenTime = 10;
const int yellowTime = 3;
void setup() {
Serial.begin(9600);
// Setup LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Smart Traffic");
lcd.setCursor(0, 1);
lcd.print("System Loading..");
delay(2000);
// Setup LED Pins
pinMode(green1, OUTPUT); pinMode(yellow1, OUTPUT); pinMode(red1, OUTPUT);
pinMode(green2, OUTPUT); pinMode(yellow2, OUTPUT); pinMode(red2, OUTPUT);
// Setup Ultrasonic Pins
pinMode(trig1, OUTPUT); pinMode(echo1, INPUT);
pinMode(trig2, OUTPUT); pinMode(echo2, INPUT);
// Initial State: Both Red momentarily
digitalWrite(red1, HIGH);
digitalWrite(red2, HIGH);
}
// Function to read distance from ultrasonic sensor
long readDistance(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Timeout of 30ms to prevent code freezing if no echo is received
long duration = pulseIn(echoPin, HIGH, 30000);
if (duration == 0) return 999; // Return high distance if no ping
long distance = duration * 0.034 / 2; // Convert to cm
return distance;
}
// Function to run a traffic cycle with countdown display
void runCycle(int grnPin, int ylwPin, int rdPin, int otherRdPin, int duration, String lane) {
digitalWrite(otherRdPin, HIGH); // Ensure other lane is stopped
digitalWrite(rdPin, LOW);
digitalWrite(grnPin, HIGH);
// Green Light Countdown
for (int i = duration; i > 0; i--) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(lane + " GO: " + String(i) + "s");
lcd.setCursor(0, 1);
lcd.print("Traffic Flowing ");
delay(1000);
}
// Yellow Light Transition
digitalWrite(grnPin, LOW);
digitalWrite(ylwPin, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(lane + " SLOW DOWN");
for (int i = yellowTime; i > 0; i--) {
lcd.setCursor(0, 1);
lcd.print("Wait: " + String(i) + "s ");
delay(1000);
}
digitalWrite(ylwPin, LOW);
digitalWrite(rdPin, HIGH);
}
void loop() {
// 1. Read real-time traffic presence
long dist1 = readDistance(trig1, echo1);
long dist2 = readDistance(trig2, echo2);
int time1 = baseGreenTime;
int time2 = baseGreenTime;
// 2. Prioritize lanes with higher traffic
// (In this logic, if a vehicle is within 100cm, it's considered heavy traffic)
bool trafficLane1 = (dist1 < 100);
bool trafficLane2 = (dist2 < 100);
if (trafficLane1 && !trafficLane2) {
time1 = 15; // Extend Lane 1 time
time2 = 5; // Shorten Lane 2 time
}
else if (!trafficLane1 && trafficLane2) {
time1 = 5; // Shorten Lane 1 time
time2 = 15; // Extend Lane 2 time
}
else if (trafficLane1 && trafficLane2) {
// Both lanes busy, give equal extended time
time1 = 12;
time2 = 12;
}
// 3. Execute Traffic Lights
runCycle(green1, yellow1, red1, red2, time1, "Lane 1");
runCycle(green2, yellow2, red2, red1, time2, "Lane 2");
}(click to edit)
(click to edit)