/*
==== Task 6 - Miniature Traffic-Light System ====
Author: AI
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
const int buzzerPin = 4;
const int redledPin = 5; // pedestrian LED - RED (stop)
const int greenledPin = 7; // pedestrian LED - GREEN (go)
const int oledsdaPin = 8;
const int oledsclPin = 9;
const int rgbPin_R = 14;
const int rgbPin_B = 17;
const int rgbPin_G = 18;
bool isRed = false; // global: remembers whether the traffic light is currently red
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
pinMode(buzzerPin, OUTPUT);
pinMode(redledPin, OUTPUT);
pinMode(greenledPin, OUTPUT);
pinMode(rgbPin_R, OUTPUT);
pinMode(rgbPin_B, OUTPUT);
pinMode(rgbPin_G, OUTPUT);
Wire.begin(oledsdaPin, oledsclPin);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.display();
}
// ===== Function WITHOUT parameters =====
// Beeps the buzzer once and briefly flashes the pedestrian RED LED
void warnChange() {
for (int i = 0; i < 4; i++) {
digitalWrite(redledPin, HIGH);
delay(200);
digitalWrite(redledPin, LOW);
delay(200);
}
tone(buzzerPin, 400);
delay(1000);
noTone(buzzerPin);
}
// ===== New function WITHOUT parameters =====
// Blinks the pedestrian RED LED and shows "WARNING" on the OLED,
// used once at the start of each cycle before the traffic light turns green
void warningAlert() {
for (int i = 0; i < 4; i++) {
digitalWrite(redledPin, HIGH);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20, 20);
display.println("Warning!");
display.display();
delay(200);
digitalWrite(redledPin, LOW);
display.clearDisplay();
display.display();
delay(200);
}
}
// ===== Function WITH parameters =====
// Turns on only the correct RGB pin(s) for onTime ms, then turns them off
void setTrafficLight(int redPin, int bluePin, int greenPin, int onTime) {
digitalWrite(rgbPin_R, redPin);
digitalWrite(rgbPin_B, bluePin);
digitalWrite(rgbPin_G, greenPin);
delay(onTime);
digitalWrite(rgbPin_R, LOW);
digitalWrite(rgbPin_B, LOW);
digitalWrite(rgbPin_G, LOW);
}
// ===== Function WITH a return value (no parameters) =====
// Returns true while the traffic light is red (safe to cross)
bool pedestrianCanCross() {
return isRed;
}
void loop() {
// ---- WARNING (once, before the cycle starts) ----
warningAlert();
// ---- GREEN (traffic) ----
isRed = false;
digitalWrite(redledPin, HIGH); // pedestrian: STOP
digitalWrite(greenledPin, LOW);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(25, 20);
display.println("STOP!");
display.display();
setTrafficLight(LOW, LOW, HIGH, 5000); // green on for 5s
delay(10);
// ---- YELLOW (traffic) ----
setTrafficLight(HIGH, LOW, HIGH, 1500); // red+green (yellow) for 1.5s
delay(10);
digitalWrite(rgbPin_R, HIGH); // keep yellow visible during the warning
digitalWrite(rgbPin_G, HIGH);
warnChange();
digitalWrite(rgbPin_R, LOW);
digitalWrite(rgbPin_G, LOW);
digitalWrite(redledPin, HIGH);
// ---- RED (traffic) ----
isRed = true; // set BEFORE turning the light red
bool canCross = pedestrianCanCross();
digitalWrite(redledPin, !canCross); // red pedestrian LED off (safe to cross)
digitalWrite(greenledPin, canCross); // green pedestrian LED on
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20, 20);
display.println(canCross ? "Go!" : "STOP!");
display.display();
setTrafficLight(HIGH, LOW, LOW, 5000); // red on for 5s (pedestrian green + "GO" already showing)
delay(10);
}