#define PIN_CAR_RED 12
#define PIN_CAR_YELLOW 13
#define PIN_CAR_GREEN 14
#define PIN_PED_RED 25
#define PIN_PED_GREEN 26
#define PIN_BUTTON 0
#define PIN_TRIG 17
#define PIN_ECHO 16
const unsigned long TIME_CAR_GREEN_NORMAL = 10000;
const unsigned long TIME_CAR_GREEN_HEAVY = 20000;
const unsigned long TIME_CAR_YELLOW = 2000;
const unsigned long TIME_CAR_RED = 8000;
const unsigned long TIME_PED_GREEN_NORMAL = 8000;
const unsigned long TIME_PED_GREEN_HEAVY = 4000;
const unsigned long TIME_ALL_RED = 1000;
const int DISTANCE_HEAVY_TRAFFIC = 50; // см
bool pedestrianRequest = false;
bool heavyTraffic = false;
String currentMode = "NORMAL";
enum State { ST_CAR_GREEN, ST_CAR_YELLOW, ST_CAR_RED_PED_GREEN, ST_CAR_RED_PED_RED };
State currentState = ST_CAR_GREEN;
void setup() {
Serial.begin(115200);
pinMode(PIN_CAR_RED, OUTPUT);
pinMode(PIN_CAR_YELLOW, OUTPUT);
pinMode(PIN_CAR_GREEN, OUTPUT);
pinMode(PIN_PED_RED, OUTPUT);
pinMode(PIN_PED_GREEN, OUTPUT);
pinMode(PIN_BUTTON, INPUT_PULLUP);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
setCarLights(LOW, LOW, HIGH);
setPedLights(HIGH, LOW);
Serial.println(" Светофор запущен!");
printStatus();
}
void loop() {
checkButton();
checkTraffic();
runStateMachine();
delay(100);
}
void checkButton() {
if (digitalRead(PIN_BUTTON) == LOW) {
delay(50);
if (digitalRead(PIN_BUTTON) == LOW && !pedestrianRequest) {
pedestrianRequest = true;
Serial.println(" Pedestrian button: PRESSED");
while (digitalRead(PIN_BUTTON) == LOW) delay(10);
}
}
}
int measureDistance() {
digitalWrite(PIN_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
long duration = pulseIn(PIN_ECHO, HIGH, 30000);
if (duration == 0) return 999;
return duration * 0.034 / 2;
}
void checkTraffic() {
int d = measureDistance();
bool newHeavy = (d < DISTANCE_HEAVY_TRAFFIC);
if (newHeavy != heavyTraffic) {
heavyTraffic = newHeavy;
Serial.println(String(" Cars: ") + (heavyTraffic ? "HEAVY TRAFFIC" : "LIGHT TRAFFIC"));
currentMode = heavyTraffic ? "EXTENDED GREEN" : "NORMAL";
printStatus();
}
}
void runStateMachine() {
unsigned long tGreen = heavyTraffic ? TIME_CAR_GREEN_HEAVY : TIME_CAR_GREEN_NORMAL;
unsigned long tPed = heavyTraffic ? TIME_PED_GREEN_HEAVY : TIME_PED_GREEN_NORMAL;
switch (currentState) {
case ST_CAR_GREEN: {
setCarLights(LOW, LOW, HIGH);
setPedLights(HIGH, LOW);
unsigned long startGreen = millis();
while (millis() - startGreen < tGreen) {
checkButton();
delay(100);
}
Serial.println(" Car: YELLOW");
currentState = ST_CAR_YELLOW;
break;
}
case ST_CAR_YELLOW: {
setCarLights(LOW, HIGH, LOW);
setPedLights(HIGH, LOW);
delay(TIME_CAR_YELLOW);
Serial.println(" Car: RED / Ped: GREEN");
currentState = ST_CAR_RED_PED_GREEN;
break;
}
case ST_CAR_RED_PED_GREEN: {
setCarLights(HIGH, LOW, LOW);
if (pedestrianRequest || heavyTraffic) {
setPedLights(LOW, HIGH);
delay(tPed);
pedestrianRequest = false;
Serial.println(" Pedestrian: GREEN (served)");
} else {
setPedLights(HIGH, LOW);
Serial.println(" Pedestrian: skipped");
}
currentState = ST_CAR_RED_PED_RED;
break;
}
case ST_CAR_RED_PED_RED: {
setCarLights(HIGH, LOW, LOW);
setPedLights(HIGH, LOW);
delay(TIME_ALL_RED);
Serial.println(" Cycle restart: Car GREEN");
printStatus();
currentState = ST_CAR_GREEN;
break;
}
}
}
void setCarLights(bool r, bool y, bool g) {
digitalWrite(PIN_CAR_RED, r ? HIGH : LOW);
digitalWrite(PIN_CAR_YELLOW, y ? HIGH : LOW);
digitalWrite(PIN_CAR_GREEN, g ? HIGH : LOW);
}
void setPedLights(bool r, bool g) {
digitalWrite(PIN_PED_RED, r ? HIGH : LOW);
digitalWrite(PIN_PED_GREEN, g ? HIGH : LOW);
}
void printStatus() {
Serial.println("═══════════════════════════");
Serial.print("Cars: ");
Serial.println(heavyTraffic ? "HEAVY TRAFFIC" : "LIGHT TRAFFIC");
Serial.print("Pedestrian button: ");
Serial.println(pedestrianRequest ? "PRESSED" : "NOT PRESSED");
Serial.print("Mode: ");
Serial.println(currentMode);
Serial.println("═══════════════════════════");
}