/*
ЗАДАЧА : ПЕРЕКЛЮЧЕНИЕ РЕЖИМОВ С ПОМОЩЬЮ КНОПКИ ПО ПРЕРЫВАНИЮ И ОБРАБОТКОЙ ДРЕБЕЗГА.
РЕЖИМ 0. РАБОТАЕТ СВЕТОФОР.
РЕЖИМ 1. ПЕРЕМИГИВАЮТСЯ ОРАНЖЕВЫЙ И СИНИЙ СВЕТОДИОДЫ.
РЕЖИМ 2. МИГАЕТ БЕЛЫЙ СВЕТОДИОД.
*/
#define LED_Red 5
#define LED_Yellow 4
#define LED_Green 6
#define LED_Orange 7
#define LED_Blue 8
#define LED_White 9
#define button_Pin 2
#define DEBOUNCE 100 // Таймаут антидребезга
byte counter = 0; // Счётчик нажатий кнопки.
byte PINS[] = { LED_Red, LED_Yellow, LED_Green, LED_Orange, LED_Blue, LED_White };
volatile bool flagTick = false; // Флаг прерывания (flagTick = true -прерывание произошло)
void setup() {
pinMode(button_Pin, INPUT_PULLUP); // Используем внутреннюю подтяжку к U пит.
attachInterrupt(0, funk_Interrupt, CHANGE);
for (byte i = 0; i < 6; i++) { pinMode(PINS[i], OUTPUT); }
}
void loop() {
if (flagTick) { // Если прерывание произошло, сбрасываем флаг и запускаем функцию button_Control()
flagTick = false;
button_Control(); // Функция антидребезга и счётчика переключений кнопкой
}
switch (counter) {
case 0:
Traffic_Lights(); // Функция работы светофора
break;
case 1:
Blink_Orange_and_Blue(); // Функция попеременного мелькания двух светодиодов
break;
case 2:
Blink_White(); // Функция мелькания одного светодиода
break;
}
}
void funk_Interrupt() {
flagTick = true; // Если произошло прерывание, поднимаем флаг.
}
void button_Control() {
uint32_t debounceTimer = 0; // Таймер дребезга
if (millis() - debounceTimer >= DEBOUNCE && !digitalRead(button_Pin)) { // Если прошло время DEBOUNCE мс "И" сигнал на кнопке = HIGH, то увеличиваем счётчик переключений режимов:
debounceTimer = millis();
for (byte i = 0; i < 6; i++) digitalWrite(PINS[i], LOW); // Все выключаем, чтобы не светились с предыдущего режима.
if (++counter > 2) counter = 0;
}
}
void Traffic_Lights() {
static byte i = 0;
static uint32_t timer = 0;
switch (i) {
case 0:
digitalWrite(LED_Red, 1); // Включился красный
i++;
break;
case 1:
if (millis() - timer >= 5000) // 5000 ms. К красному добавляется жёлтый
{
digitalWrite(LED_Yellow, 1);
timer = millis();
i++;
}
break;
case 2:
if (millis() - timer >= 2000) { // 2000 ms. Загорается зелёный, остальные выключаются
digitalWrite(LED_Red, 0);
digitalWrite(LED_Yellow, 0);
digitalWrite(LED_Green, 1);
timer = millis();
i++;
}
break;
case 3:
if (millis() - timer >= 5000) { // После 5000 мс зелёный выключается
digitalWrite(LED_Green, 0);
timer = millis();
i++;
}
break;
case 4:
case 6:
case 8:
case 10:
case 12:
if (millis() - timer >= 500) { // Через 500 мс зелёный включается
digitalWrite(LED_Green, 1);
timer = millis();
i++;
}
break;
case 5:
case 7:
case 9:
case 11:
case 13:
if (millis() - timer >= 500) { // Через 500 мс зелёный отключается
digitalWrite(LED_Green, 0);
timer = millis();
i++;
}
break;
case 14:
digitalWrite(LED_Yellow, 1);
i++;
break;
case 15:
if (millis() - timer >= 2000) { // Жёлтый выключается
digitalWrite(LED_Yellow, 0);
timer = millis();
i = 0;
}
break;
default:
i = 0;
break;
}
}
void Blink_Orange_and_Blue() {
static uint32_t timer = 0;
static bool led_Flag_Bl_Orange = false; // Флаг состояния синего и оранжевого светодиодов
if (millis() - timer >= 300) {
timer = millis();
led_Flag_Bl_Orange = !led_Flag_Bl_Orange;
digitalWrite(LED_Orange, !led_Flag_Bl_Orange);
digitalWrite(LED_Blue, led_Flag_Bl_Orange);
}
}
void Blink_White() {
static uint32_t timer = 0;
static bool led_Flag_White = false; // Флаг состояния белого светодиода
if (millis() - timer >= 200) {
timer = millis();
led_Flag_White = !led_Flag_White;
digitalWrite(LED_White, led_Flag_White);
}
}