// Smart Traffic Light — Arduino Uno
// Vehicle sensor: HC-SR04
// Pedestrian: push button (INPUT_PULLUP)
// Pin definitions
const int VEH_RED_PIN = 2;
const int VEH_YEL_PIN = 4;
const int VEH_GRE_PIN = 16;
const int PED_RED_PIN = 5;
const int PED_GRE_PIN = 19;
const int TRIG_PIN = 12;
const int ECHO_PIN = 14;
const int PED_BUTTON = 13;
const int BUZZER = 10; // optional
// Timing (ms)
unsigned long GREEN_TIME = 10000UL; // 10s default
unsigned long YELLOW_TIME = 3000UL; // 3s
unsigned long PED_GREEN_TIME = 8000UL; // 8s pedestrian crossing
unsigned long MIN_GREEN_EXTEND = 3000UL; // minimal perpanjangan
unsigned long MAX_GREEN_EXTEND = 8000UL; // maksimal perpanjangan
// Vehicle detection threshold (cm)
const long VEHICLE_DIST_THRESHOLD = 100; // deteksi kendaraan jika objek < 100 cm
// FSM states (ubah nama biar tidak tabrakan)
enum State { ST_VEH_GREEN, ST_VEH_YELLOW, ST_PED_GREEN };
State state = ST_VEH_GREEN;
unsigned long stateStart = 0;
unsigned long requestedGreenExtend = 0;
bool pedRequest = false;
// helper to measure distance
long measureDistanceCM() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // timeout 30ms
if (duration == 0) return 9999; // no echo
long dist = duration * 0.034 / 2; // cm
return dist;
}
void setup() {
// pins
pinMode(VEH_RED_PIN, OUTPUT);
pinMode(VEH_YEL_PIN, OUTPUT);
pinMode(VEH_GRE_PIN, OUTPUT);
pinMode(PED_RED_PIN, OUTPUT);
pinMode(PED_GRE_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PED_BUTTON, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
// initial
digitalWrite(VEH_RED_PIN, LOW);
digitalWrite(VEH_YEL_PIN, LOW);
digitalWrite(VEH_GRE_PIN, HIGH); // start with green vehicle
digitalWrite(PED_RED_PIN, HIGH);
digitalWrite(PED_GRE_PIN, LOW);
state = ST_VEH_GREEN;
stateStart = millis();
}
void setVehicleLights(bool r, bool y, bool g) {
digitalWrite(VEH_RED_PIN, r);
digitalWrite(VEH_YEL_PIN, y);
digitalWrite(VEH_GRE_PIN, g);
}
void setPedLights(bool r, bool g) {
digitalWrite(PED_RED_PIN, r);
digitalWrite(PED_GRE_PIN, g);
}
void loop() {
unsigned long now = millis();
// read pedestrian button (active LOW because INPUT_PULLUP)
if (digitalRead(PED_BUTTON) == LOW) {
delay(30); // debounce
if (digitalRead(PED_BUTTON) == LOW) {
pedRequest = true;
}
}
switch (state) {
case ST_VEH_GREEN: {
unsigned long elapsed = now - stateStart;
long dist = measureDistanceCM();
bool vehiclePresent = (dist > 0 && dist < VEHICLE_DIST_THRESHOLD);
if (vehiclePresent && elapsed >= GREEN_TIME - MIN_GREEN_EXTEND && requestedGreenExtend == 0) {
requestedGreenExtend = MIN_GREEN_EXTEND;
}
if (vehiclePresent && requestedGreenExtend > 0 && requestedGreenExtend < MAX_GREEN_EXTEND) {
requestedGreenExtend += 1000;
if (requestedGreenExtend > MAX_GREEN_EXTEND) requestedGreenExtend = MAX_GREEN_EXTEND;
}
unsigned long effectiveGreen = GREEN_TIME + requestedGreenExtend;
if (elapsed >= effectiveGreen || pedRequest) {
state = ST_VEH_YELLOW;
setVehicleLights(false, true, false);
setPedLights(true, false);
stateStart = now;
requestedGreenExtend = 0;
} else {
setVehicleLights(false, false, true);
setPedLights(true, false);
}
break;
}
case ST_VEH_YELLOW: {
unsigned long elapsed = now - stateStart;
if (elapsed >= YELLOW_TIME) {
if (pedRequest) {
state = ST_PED_GREEN;
setVehicleLights(true, false, false);
setPedLights(false, true);
tone(BUZZER, 1000, 200);
stateStart = now;
pedRequest = false;
} else {
state = ST_VEH_GREEN;
setVehicleLights(false, false, true);
setPedLights(true, false);
stateStart = now;
}
}
break;
}
case ST_PED_GREEN: {
unsigned long elapsed = now - stateStart;
if (elapsed >= PED_GREEN_TIME) {
state = ST_VEH_GREEN;
setVehicleLights(false, false, true);
setPedLights(true, false);
stateStart = now;
}
break;
}
}
delay(50);
}