// Pin definitions for traffic lights
const int redPins[] = {2, 5, 8, 11}; // Red LEDs for North, South, East, West
const int amberPins[] = {3, 6, 9, 12}; // Amber LEDs
const int greenPins[] = {4, 7, 10, 13}; // Green LEDs
const int leftBlinkingWhitePins[] = {22, 23, 24, 25}; // Left turn blinking white LEDs
// Pedestrian crossing RGB LEDs (One for each direction)
const int redRGB[] = {30, 33, 36, 39}; // Red legs of the pedestrian RGB LEDs
const int greenRGB[] = {31, 34, 37, 40}; // Green legs of the pedestrian RGB LEDs
// Pedestrian button
const int pedestrianButton = 50;
volatile bool pedestrianRequest = false; // Flag to track button press
// Timing variables
const unsigned long greenDuration = 5000; // 5 seconds
const unsigned long amberDuration = 2000; // 2 seconds
const unsigned long transitionDelay = 2000; // Shorter transition delay
const unsigned long blinkInterval = 500; // 0.5 second blinking interval
const unsigned long pedestrianCrossingTime = 5000; // 5 seconds for crossing
// Debounce variables
unsigned long lastDebounceTime = 0; // Last time button was pressed
unsigned long debounceDelay = 50; // Debounce delay (milliseconds)
// Function prototypes
void blinkLeftTurnLights(int index1, int index2, unsigned long duration);
void activatePedestrianCrossing();
void pedestrianButtonISR();
void setup() {
Serial.begin(9600);
// Initialize all pins as outputs
for (int i = 0; i < 4; i++) {
pinMode(redPins[i], OUTPUT);
pinMode(amberPins[i], OUTPUT);
pinMode(greenPins[i], OUTPUT);
pinMode(leftBlinkingWhitePins[i], OUTPUT);
pinMode(redRGB[i], OUTPUT);
pinMode(greenRGB[i], OUTPUT);
}
// Set pedestrian button as input with interrupt
pinMode(pedestrianButton, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pedestrianButton), pedestrianButtonISR, FALLING);
// Default state at startup: North-South Red OFF, East-West Red ON
digitalWrite(redPins[0], LOW); // North Red OFF
digitalWrite(redPins[1], LOW); // South Red OFF
digitalWrite(redPins[2], HIGH); // East Red ON
digitalWrite(redPins[3], HIGH); // West Red ON
// Pedestrian lights default to RED (not safe to cross)
for (int i = 0; i < 4; i++) {
digitalWrite(redRGB[i], HIGH); // Red ON (Not safe)
digitalWrite(greenRGB[i], LOW); // Green OFF
}
}
void loop() {
Serial.println("Traffic sequence running...");
// Start with North-South sequence
setTrafficLightsNorthSouth();
blinkLeftTurnLights(0, 1, greenDuration);
setAmberLightsNorthSouth();
delay(amberDuration);
if (pedestrianRequest) {
activatePedestrianCrossing();
}
setRedLightsNorthSouth();
delay(transitionDelay);
// East-West sequence
setTrafficLightsEastWest();
blinkLeftTurnLights(2, 3, greenDuration);
setAmberLightsEastWest();
delay(amberDuration);
if (pedestrianRequest) {
activatePedestrianCrossing();
}
setRedLightsEastWest();
delay(transitionDelay);
}
// Interrupt function for pedestrian button press
void pedestrianButtonISR() {
// Check if enough time has passed for debouncing
if ((millis() - lastDebounceTime) > debounceDelay) {
pedestrianRequest = true;
Serial.println("Pedestrian button pressed");
}
lastDebounceTime = millis(); // Record the time of the press
}
// Function to handle pedestrian crossing
void activatePedestrianCrossing() {
Serial.println("Pedestrian crossing activated!");
// Turn all traffic lights red
for (int i = 0; i < 4; i++) {
digitalWrite(redPins[i], HIGH);
digitalWrite(amberPins[i], LOW);
digitalWrite(greenPins[i], LOW);
digitalWrite(leftBlinkingWhitePins[i], LOW);
}
// Turn pedestrian RGB LEDs GREEN (safe to cross)
for (int i = 0; i < 4; i++) {
digitalWrite(redRGB[i], LOW); // Red OFF
digitalWrite(greenRGB[i], HIGH); // Green ON
}
delay(pedestrianCrossingTime);
// Turn pedestrian RGB LEDs RED (not safe to cross)
for (int i = 0; i < 4; i++) {
digitalWrite(redRGB[i], HIGH); // Red ON
digitalWrite(greenRGB[i], LOW); // Green OFF
}
pedestrianRequest = false; // Reset flag
}
// Function to set traffic lights for North and South
void setTrafficLightsNorthSouth() {
digitalWrite(greenPins[0], HIGH);
digitalWrite(greenPins[1], HIGH);
digitalWrite(redPins[0], LOW);
digitalWrite(redPins[1], LOW);
digitalWrite(redPins[2], HIGH);
digitalWrite(redPins[3], HIGH);
digitalWrite(amberPins[0], LOW);
digitalWrite(amberPins[1], LOW);
}
// Function to set amber lights for North and South
void setAmberLightsNorthSouth() {
digitalWrite(amberPins[0], HIGH);
digitalWrite(amberPins[1], HIGH);
digitalWrite(greenPins[0], LOW);
digitalWrite(greenPins[1], LOW);
}
// Function to set red lights for North and South
void setRedLightsNorthSouth() {
digitalWrite(redPins[0], HIGH);
digitalWrite(redPins[1], HIGH);
digitalWrite(amberPins[0], LOW);
digitalWrite(amberPins[1], LOW);
}
// Function to set traffic lights for East and West
void setTrafficLightsEastWest() {
digitalWrite(greenPins[2], HIGH);
digitalWrite(greenPins[3], HIGH);
digitalWrite(redPins[2], LOW);
digitalWrite(redPins[3], LOW);
digitalWrite(redPins[0], HIGH);
digitalWrite(redPins[1], HIGH);
digitalWrite(amberPins[2], LOW);
digitalWrite(amberPins[3], LOW);
}
// Function to set amber lights for East and West
void setAmberLightsEastWest() {
digitalWrite(amberPins[2], HIGH);
digitalWrite(amberPins[3], HIGH);
digitalWrite(greenPins[2], LOW);
digitalWrite(greenPins[3], LOW);
}
// Function to set red lights for East and West
void setRedLightsEastWest() {
digitalWrite(redPins[2], HIGH);
digitalWrite(redPins[3], HIGH);
digitalWrite(amberPins[2], LOW);
digitalWrite(amberPins[3], LOW);
}
// Function to blink left turn lights while green light is on
void blinkLeftTurnLights(int index1, int index2, unsigned long duration) {
unsigned long startTime = millis();
while (millis() - startTime < duration) {
digitalWrite(leftBlinkingWhitePins[index1], HIGH);
digitalWrite(leftBlinkingWhitePins[index2], HIGH);
delay(blinkInterval);
digitalWrite(leftBlinkingWhitePins[index1], LOW);
digitalWrite(leftBlinkingWhitePins[index2], LOW);
delay(blinkInterval);
}
}