#include <LiquidCrystal.h>
enum TrafficLightState {
RED,
GREEN,
YELLOW
};
class TrafficLight {
private:
TrafficLightState state;
unsigned long lastChangeTime;
unsigned long interval;
public:
TrafficLight(unsigned long interval) {
this->interval = interval;
state = RED;
lastChangeTime = millis();
}
//for more projects : https://wokwi.com/makers/danibae
void update() {
unsigned long elapsedTime = millis() - lastChangeTime;
if (state == RED && elapsedTime >= interval) {
state = GREEN;
lastChangeTime = millis();
} else if (state == GREEN && elapsedTime >= interval) {
state = YELLOW;
lastChangeTime = millis();
} else if (state == YELLOW && elapsedTime >= interval / 2) {
state = RED;
lastChangeTime = millis();
}
}
TrafficLightState getState() {
return state;
}
};
const int redLedPin = 7;
const int yellowLedPin = 8;
const int greenLedPin = 9;
const int motionSensorPin = 10;
LiquidCrystal lcd(12, 11, 5, 4, 3, 6);
TrafficLight trafficLight(3000);
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(redLedPin, OUTPUT);
pinMode(yellowLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(motionSensorPin, INPUT);
}
void loop() {
bool motionDetected = digitalRead(motionSensorPin) == HIGH;
if (motionDetected) {
trafficLight = GREEN;
}
trafficLight.update();
TrafficLightState currentState = trafficLight.getState();
digitalWrite(redLedPin, currentState == RED ? HIGH : LOW);
digitalWrite(yellowLedPin, currentState == YELLOW ? HIGH : LOW);
digitalWrite(greenLedPin, currentState == GREEN ? HIGH : LOW);
lcd.clear();
lcd.setCursor(0, 0);
switch (currentState) {
case RED:
lcd.print("RED");
break;
case GREEN:
lcd.print("GREEN");
break;
case YELLOW:
lcd.print("YELLOW");
break;
}
lcd.setCursor(0, 1);
lcd.print("Emergency: ");
lcd.print(motionDetected ? "Yes" : "No");
if (motionDetected) {
lcd.setCursor(0, 2);
lcd.print("Ambulance! Wait!");
}
delay(1000);
}