// Структура для хранения состояния светофора
struct TrafficLightState
{
char red; // 'R' - красный, 'O' - выключен
char yellow; // 'Y' - желтый, 'O' - выключен
char green; // 'G' - зеленый, 'O' - выключен
int duration; // Продолжительность текущего состояния в секундах
bool flash; // признак моргания сигнала светофора (1 - моргает, 0 - горит постоянно)
};
// Массив для хранения состояний
TrafficLightState states[] = {
{'R', 'O', 'O', 5000, 0}, // Красный 5 сек
{'R', 'Y', 'O', 2000, 0}, // Красный+Желтый 2 сек
{'O', 'O', 'G', 3000, 0}, // Зеленый горит 3 сек
{'O', 'O', 'G', 2000, 1}, // Зеленый моргает 2 сек
{'O', 'Y', 'O', 2000, 0} // Желтый 2 сек
};
// количество шагов работы светофора
const size_t maxStates = sizeof(states) / sizeof(states[0]);
TrafficLightState currentState;
// Текущий индекс состояния светофора
int currentIndex = 0;
// переменные моргалки
bool flashState = false;
unsigned long previousFlashTimer = 0;
unsigned long currentFlashTimer = millis();
int flashPeriod = 250; // частота моргания сигнала светофора
// Таймер
unsigned long previousMillis = 0;
void setup()
{
// Настройка пинов
pinMode(2, OUTPUT); // Красный
pinMode(3, OUTPUT); // Желтый
pinMode(4, OUTPUT); // Зеленый
}
void loop()
{
// таймер моргалки постоянно крутится и перекидывает флаг моргалки flashState в противоположное
// состояние через время flashPeriod
if (currentFlashTimer - previousFlashTimer >= flashPeriod)
{
flashState = !flashState;
previousFlashTimer = millis();
}
currentFlashTimer = millis();
// таймер, по которому проверяем, не пора ли сменить состояние светофора
unsigned long currentMillis = millis();
currentState = states[currentIndex]; // Считать текущее состояние из массива
if (currentMillis - previousMillis >= currentState.duration) // Обновление состояния светофора
{
previousMillis = millis();
currentIndex++; // Переключить на следующее состояние
if (currentIndex >= maxStates)
{
currentIndex = 0; // Возврат в начало
}
}
// Обновить индикацию светофора
updateLightTraffic();
}
void updateLightTraffic()
{
digitalWrite(2, (currentState.red == 'R' & !(flashState & currentState.flash)) ? HIGH : LOW);
digitalWrite(3, (currentState.yellow == 'Y' & !(flashState & currentState.flash)) ? HIGH : LOW);
digitalWrite(4, (currentState.green == 'G' & !(flashState & currentState.flash)) ? HIGH : LOW);
}