// NUCLEO-C031C6: светофор + пешеходный по кнопке
// Пины из задания:
#define LED_R 13 // машины: красный
#define LED_Y 12 // машины: жёлтый
#define LED_G 11 // машины: зелёный
#define LED_R_P 9 // пешеходы: красный
#define LED_G_P 8 // пешеходы: зелёный
#define BUT 4 // кнопка (INPUT_PULLUP)
#define POT A2 // потенциометр (длительность пешеходной фазы)
#define BUZZ A5 // зуммер
// --- сервисные функции ---
void cars(bool r, bool y, bool g) {
digitalWrite(LED_R, r);
digitalWrite(LED_Y, y);
digitalWrite(LED_G, g);
}
void peds(bool r, bool g) {
digitalWrite(LED_R_P, r);
digitalWrite(LED_G_P, g);
}
// ожидание с опросом кнопки (для дебаунса и «заказа» перехода)
bool requestCross = false;
void waitWithButton(uint32_t ms) {
const uint16_t step = 20; // мс
uint32_t t0 = millis();
while (millis() - t0 < ms) {
if (digitalRead(BUT) == LOW) { // нажали (кнопка к GND)
delay(20); // дебаунс
if (digitalRead(BUT) == LOW) {
requestCross = true; // запоминаем запрос
while (digitalRead(BUT) == LOW) {} // ждём отпускание
}
}
delay(step);
}
}
// мигание зелёного пешеходам в последние N миллисекунд
void pedestrianPhase(uint32_t cross_ms) {
// машины стоят, пешеходы идут
cars(true, false, false);
peds(false, true);
uint32_t t0 = millis();
while (millis() - t0 < cross_ms) {
uint32_t elapsed = millis() - t0;
uint32_t remain = (cross_ms > elapsed) ? (cross_ms - elapsed) : 0;
// короткие «пики» зуммера каждые 500 мс
if ((elapsed % 500) < 120) tone(BUZZ, 1000, 100);
// в последние 2 секунды мигаем зелёным для пешеходов
if (remain <= 2000) {
digitalWrite(LED_G_P, (millis() / 200) % 2); // 5 Гц/2=~2.5 Гц
} else {
digitalWrite(LED_G_P, HIGH);
}
delay(20);
}
// пешеходам — красный, готовим возврат к движению машин
peds(true, false);
}
// --- настройка ---
void setup() {
pinMode(LED_R, OUTPUT);
pinMode(LED_Y, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(LED_R_P, OUTPUT);
pinMode(LED_G_P, OUTPUT);
pinMode(BUZZ, OUTPUT);
pinMode(BUT, INPUT_PULLUP);
pinMode(POT, INPUT);
// стартовое состояние: машинам зелёный, пешеходам красный
cars(false, false, true);
peds(true, false);
}
// --- основной цикл ---
void loop() {
// Длительность пешеходной фазы с потенциометра: 3...10 с
uint32_t cross_ms = map(analogRead(POT), 0, 1023, 3000, 10000);
// 1) Машинам зелёный
cars(false, false, true);
peds(true, false);
waitWithButton(5000); // «обычный» проезд ~5 с
// 2) Жёлтый для машин
cars(false, true, false);
delay(1000);
// 3) Если просили переход — включаем пешеходную фазу
cars(true, false, false); // красный для машин
delay(300); // небольшая пауза безопасности
if (requestCross) {
pedestrianPhase(cross_ms);
requestCross = false;
} else {
// без пешеходов подержим красный 2 с
delay(2000);
}
// 4) Короткий жёлтый и снова зелёный для машин
cars(false, true, false);
delay(800);
cars(false, false, true);
// цикл повторяется
}