/*
==== Task 6 - Miniature Traffic-Light System ====
Author: Roberto Palozzo
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
const int buzzerPin = 4; // active buzzer, warns on colour change
const int redledPin = 5; // pedestrian LED (lit = safe to cross)
const int oledsdaPin = 8; // OLED I2C data pin
const int oledsclPin = 9; // OLED I2C clock pin
const int rgbPin_R = 14; // RGB LED - red channel
const int rgbPin_B = 17; // RGB LED - blue channel (unused, always LOW)
const int rgbPin_G = 18; // RGB LED - green channel
bool isRed = false; // global flag: true while the traffic light is red
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // OLED display object
void setup() {
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
pinMode(buzzerPin, OUTPUT);
pinMode(redledPin, OUTPUT);
pinMode(rgbPin_R, OUTPUT);
pinMode(rgbPin_B, OUTPUT);
pinMode(rgbPin_G, OUTPUT);
Wire.begin(oledsdaPin, oledsclPin); // start I2C on custom pins
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize OLED at I2C address 0x3C
display.clearDisplay(); // clear display buffer
display.setTextColor(SSD1306_WHITE); // set text color
display.display(); // apply initial blank screen
}
// ===== Function WITHOUT parameters =====
// Flashes the pedestrian LED and beeps the buzzer 4 times
void warnChange() {
for (int i = 0; i < 4; i++) {
digitalWrite(redledPin, HIGH); // LED on
tone(buzzerPin, 400); // beep on
delay(200);
digitalWrite(redledPin, LOW); // LED off
noTone(buzzerPin); // beep off
delay(200);
}
}
// ===== Function WITH parameters =====
// Turns on only the requested RGB colour(s) for onTime ms, then turns them off
void setTrafficLight(int redPin, int bluePin, int greenPin, int onTime) {
isRed = redPin; // remember if red is on during this call
digitalWrite(rgbPin_R, redPin);
digitalWrite(rgbPin_B, bluePin);
digitalWrite(rgbPin_G, greenPin);
delay(onTime); // keep the colour on for onTime ms
digitalWrite(rgbPin_R, LOW); // turn everything off before returning
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; // reads the global flag set by setTrafficLight()
}
void loop() {
// ---- GREEN (traffic) ----
Serial.println("Phase: GREEN");
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 20);
display.println("Stop!"); // pedestrians must wait, cars are moving
display.display();
digitalWrite(redledPin, LOW); // pedestrian LED off (not safe yet)
setTrafficLight(LOW, LOW, HIGH, 5000); // green on for 5s
delay(10);
warnChange(); // warn: light is about to change
// ---- YELLOW (traffic) ----
setTrafficLight(HIGH, LOW, HIGH, 1500); // red+green = yellow, 1.5s
warnChange(); // warn: about to turn red
// ---- RED (traffic) ----
Serial.println("Phase: RED");
bool canCross = pedestrianCanCross(); // check if it's safe to cross
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 20);
display.println(canCross ? "Go !" : "Stop!"); // show GO only when true
display.display();
digitalWrite(redledPin, canCross); // pedestrian LED on (safe to cross)
setTrafficLight(HIGH, LOW, LOW, 5000); // red on for 5s
delay(10);
}