МНОГОРЕЖИМНЫЙ СВЕТОФОР 🚦
БАЗОВАЯ РЕАЛИЗАЦИЯ
Логика работы:
Основные режимы:
- НОРМАЛЬНЫЙ: стандартные циклы (красный → зеленый → желтый)
- НОЧНОЙ: мигающий желтый для экономии энергии
- АВАРИЙНЫЙ: мигающий красный при экстренной ситуации
- ПИКОВЫЙ: укороченные циклы для интенсивного движения
Управление:
Потенциометр → выбор режима (4 позиции)
Кнопка → экстренное переключение в аварийный режим
Компоненты:
- ✅ Светодиоды: красный (x2), желтый (x2), зеленый (x2) - для 2 направлений
- ✅ Потенциометр 10кОм
- ✅ Кнопка тактовая (экстренная)
- ✅ Резисторы: 220 Ом (6 шт), 10кОм (1 шт)
- ✅ Arduino Uno + макетка
- ✅ ✅ Дополнительно: LCD дисплей для отображения режима
Схема подключения:
Светодиоды (Направление 1):
Красный1 → pin 2 → резистор → GND
Желтый1 → pin 3 → резистор → GND
Зеленый1 → pin 4 → резистор → GND
Светодиоды (Направление 2):
Красный2 → pin 5 → резистор → GND
Желтый2 → pin 6 → резистор → GND
Зеленый2 → pin 7 → резистор → GND
Потенциометр (режимы):
GND → GND, Сигнал → A0, VCC → 5V
Кнопка (экстренная):
один вывод → 5V
другой вывод → pin 8 + резистор 10кОм → GND
ЛОГИКА РАБОТЫ 🔄
Псевдокод для обсуждения:
// ИЕРАРХИЯ СОСТОЯНИЙ:
ГЛАВНЫЙ_РЕЖИМ = [НОРМАЛЬНЫЙ, НОЧНОЙ, АВАРИЙНЫЙ, ПИКОВЫЙ]
СОСТОЯНИЕ_СВЕТОФОРА = [КРАСНЫЙ, КРАСНЫЙ_ЖЕЛТЫЙ, ЗЕЛЕНЫЙ, ЖЕЛТЫЙ]
// ОСНОВНОЙ ЦИКЛ:
определяем_текущий_режим_из_потенциометра()
обрабатываем_экстренную_кнопку() // имеет высший приоритет!
в_зависимости_от_режима:
случай НОРМАЛЬНЫЙ:
выполняем_стандартный_цикл_светофора()
случай НОЧНОЙ:
мигаем_желтым_с_интервалом()
случай АВАРИЙНЫЙ:
мигаем_красным_с_интервалом()
случай ПИКОВЫЙ:
выполняем_укороченный_цикл_светофора()
ДЕТАЛЬНАЯ РЕАЛИЗАЦИЯ АЛГОРИТМОВ ⚡
Структура данных состояний:
enum MainMode { MODE_NORMAL, MODE_NIGHT, MODE_EMERGENCY, MODE_PEAK };
enum TrafficState { STATE_RED, STATE_RED_YELLOW, STATE_GREEN, STATE_YELLOW };
struct TrafficSystem {
MainMode currentMode;
TrafficState currentState;
unsigned long stateStartTime;
bool emergencyRequested;
int modeFromPot; // запомненный режим до экстренной ситуации
};
TrafficSystem system;
Управление режимами:
void updateMainMode() {
int potValue = analogRead(POT_PIN);
int newMode = map(potValue, 0, 1023, 0, 3);
// Если не в аварийном режиме - разрешаем смену
if (system.currentMode != MODE_EMERGENCY) {
system.currentMode = (MainMode)newMode;
} else {
// В аварийном режиме запоминаем выбранный режим для восстановления
system.modeFromPot = newMode;
}
}
Обработка экстренной кнопки:
void handleEmergencyButton() {
if (digitalRead(EMERGENCY_BUTTON_PIN) == LOW) {
delay(50); // антидребезг
if (digitalRead(EMERGENCY_BUTTON_PIN) == LOW) {
if (system.currentMode != MODE_EMERGENCY) {
// Входим в аварийный режим
system.modeFromPot = system.currentMode;
system.currentMode = MODE_EMERGENCY;
system.emergencyRequested = true;
} else {
// Выходим из аварийного режима
system.currentMode = (MainMode)system.modeFromPot;
system.emergencyRequested = false;
}
// Ждем отпускания кнопки
while (digitalRead(EMERGENCY_BUTTON_PIN) == LOW) {
delay(10);
}
}
}
}
Реализация режимов светофора:
void runNormalMode() {
unsigned long currentTime = millis();
unsigned long stateDuration = getStateDuration(system.currentState);
if (currentTime - system.stateStartTime > stateDuration) {
// Переход к следующему состоянию
switch(system.currentState) {
case STATE_RED:
system.currentState = STATE_RED_YELLOW;
break;
case STATE_RED_YELLOW:
system.currentState = STATE_GREEN;
break;
case STATE_GREEN:
system.currentState = STATE_YELLOW;
break;
case STATE_YELLOW:
system.currentState = STATE_RED;
break;
}
system.stateStartTime = currentTime;
}
updateLights();
}
void runNightMode() {
// Мигающий желтый - оба направления
unsigned long currentTime = millis();
bool yellowOn = ((currentTime / 500) % 2) == 0; // мигание каждые 500ms
digitalWrite(YELLOW1_PIN, yellowOn ? HIGH : LOW);
digitalWrite(YELLOW2_PIN, yellowOn ? HIGH : LOW);
digitalWrite(RED1_PIN, LOW);
digitalWrite(GREEN1_PIN, LOW);
digitalWrite(RED2_PIN, LOW);
digitalWrite(GREEN2_PIN, LOW);
}
void runEmergencyMode() {
// Мигающий красный - оба направления
unsigned long currentTime = millis();
bool redOn = ((currentTime / 500) % 2) == 0; // мигание каждые 500ms
digitalWrite(RED1_PIN, redOn ? HIGH : LOW);
digitalWrite(RED2_PIN, redOn ? HIGH : LOW);
digitalWrite(YELLOW1_PIN, LOW);
digitalWrite(GREEN1_PIN, LOW);
digitalWrite(YELLOW2_PIN, LOW);
digitalWrite(GREEN2_PIN, LOW);
}
Функция длительностей состояний:
unsigned long getStateDuration(TrafficState state) {
switch(state) {
case STATE_RED:
return (system.currentMode == MODE_PEAK) ? 5000 : 10000; // 5сек в пике, 10сек норма
case STATE_RED_YELLOW:
return 2000; // всегда 2 секунды
case STATE_GREEN:
return (system.currentMode == MODE_PEAK) ? 5000 : 15000; // 5сек в пике, 15сек норма
case STATE_YELLOW:
return 3000; // всегда 3 секунды
default:
return 5000;
}
}
УСЛОЖНЕНИЯ И ВАРИАЦИИ 🎛️
1. Режим “Согласованные светофоры”:
// Несколько светофоров работают согласованно
void coordinatedMode() {
// Светофор 1: зеленый, когда светофор 2: красный
if (system.currentState == STATE_GREEN) {
setLightsDirection1(GREEN);
setLightsDirection2(RED);
} else {
setLightsDirection1(RED);
setLightsDirection2(GREEN);
}
}
2. Адаптивный режим по датчикам:
// Добавляем датчики движения для адаптивного управления
void adaptiveMode() {
int carsDirection1 = countCars(CAR_SENSOR_1);
int carsDirection2 = countCars(CAR_SENSOR_2);
// Динамически调整 длительность зеленого света
if (carsDirection1 > carsDirection2 * 2) {
greenDurationDirection1 = 20000; // больше машин - дольше зеленый
greenDurationDirection2 = 5000;
} else {
greenDurationDirection1 = 10000;
greenDurationDirection2 = 10000;
}
}
3. Режим “Пешеходный переход”:
// Добавляем пешеходную кнопку и режим
void pedestrianMode() {
if (pedestrianButtonPressed) {
// Прерываем текущий цикл для пешеходов
system.currentState = STATE_PEDESTRIAN;
system.stateStartTime = millis();
// Красный для машин, зеленый для пешеходов
setAllCarLights(RED);
setPedestrianLight(GREEN);
}
}
ОЛИМПИАДНАЯ СВЯЗЬ 🏆
СВЯЗЬ С РЕАЛЬНЫМИ ОЛИМПИАДНЫМИ ЗАДАНИЯМИ:
// Аналогично системе контроля стаканов из 7-8 классов:
"Устройство должно иметь multiple состояния и режимы работы"
// Аналогично визуализатору битовых операций из 9-11 классов:
"Сложные конечные автоматы с приоритетами событий и временными ограничениями"
Критерии успеха в олимпиадах:
- ✅ Четкая иерархия состояний - понятная структура автомата
- ✅ Корректные приоритеты - экстренные события обрабатываются правильно
- ✅ Стабильные временные циклы - нет дрифта времени
- ✅ Восстановление состояния - система возвращается к прерванным процессам
Типичные олимпиадные ошибки:
- ❌ Глобальные переменные вместо структур - трудно отслеживать состояние
- ❌ Отсутствие антидребезга - multiple срабатывания кнопок
- ❌ Жесткие тайминги - вместо millis() используют delay()
- ❌ Путаница в приоритетах - события обрабатываются в неправильном порядке
МЕТОДИЧЕСКИЕ СОВЕТЫ 👨🏫
Поэтапная реализация:
// ЭТАП 1: Простой светофор с 3 состояниями
runBasicTrafficLight();
// ЭТАП 2: Добавляем второй направление
runTwoDirectionTrafficLight();
// ЭТАП 3: Вводим главные режимы
updateMainMode();
switch(system.currentMode) {
case MODE_NORMAL: runNormalMode(); break;
case MODE_NIGHT: runNightMode(); break;
}
// ЭТАП 4: Добавляем экстренные прерывания
handleEmergencyButton();
if (system.emergencyRequested) {
runEmergencyMode();
}
Визуализация для понимания:
🎯 Иерархия состояний:
ГЛАВНЫЙ РЕЖИМ → ПОДСОСТОЯНИЯ
├── НОРМАЛЬНЫЙ → [КРАСНЫЙ] → [КРАСНЫЙ+ЖЕЛТЫЙ] → [ЗЕЛЕНЫЙ] → [ЖЕЛТЫЙ]
├── НОЧНОЙ → [МИГАЮЩИЙ_ЖЕЛТЫЙ]
├── АВАРИЙНЫЙ → [МИГАЮЩИЙ_КРАСНЫЙ]
└── ПИКОВЫЙ → [КОРОТКИЙ_КРАСНЫЙ] → [КОРОТКИЙ_ЗЕЛЕНЫЙ]
🎮 Управление:
Потенциометр: Выбор главного режима (4 позиции)
Кнопка: Экстренное переключение (высший приоритет)
Практические упражнения:
Упражнение 1: “Диаграмма состояний”
- Нарисовать полную диаграмму состояний системы
- Определить все возможные переходы между состояниями
- Выявить “зависшие” состояния и циклы
Упражнение 2: “Тестирование переходов”
- Протестировать все возможные переходы между режимами
- Проверить приоритеты экстренных событий
- Убедиться в корректном восстановлении состояний
Упражнение 3: “Расширение автомата”
- Добавить новые режимы (строительный, праздничный)
- Реализовать сложные переходы с условиями
- Создать систему логирования изменений состояний
Диагностика проблем:
- Система “зависает” в состоянии → проверьте условия выхода из состояний
- Некорректные переходы → убедитесь в правильности проверки времени
- Кнопка не работает в аварийном режиме → проверьте приоритеты обработки
- Мерцание светодиодов → оптимизируйте временные интервалы
Критерии оценки проекта:
- 4 балла - стабильная работа 4 основных режимов
- +2 балла - корректная обработка экстренных прерываний
- +2 балла - сложная иерархия состояний с временными ограничениями
- +2 балла - дополнительные режимы и диагностика
РЕАЛЬНОЕ ПРИМЕНЕНИЕ 🏙️
Где это используется:
- Умные транспортные системы - адаптивное управление светофорами
- Промышленная автоматика - сложные технологические процессы
- Медицинское оборудование - многорежимные устройства жизнеобеспечения
- Авионика - системы управления полетом с multiple режимами
Профессиональные аналоги:
- SCADA системы - управление сложными производственными процессами
- Автопилоты - многорежимные системы навигации
- Сетевые коммутаторы - сложные конечные автоматы маршрутизации
- Банкоматы - многоуровневые автоматы обработки транзакций