Случайно попал на сайт https://роботехника18.рф/светофор-ардуино/, на статейку про Светофор с кнопкой...
, посмотрел и увидел, что как бы не очень логично у них написано, тем более для детей или начинающих. Решил высказать свой взгляд на эту тему .
На сайте оригинала говорится:
Данный пример позволит детям понять работу светофоров на пешеходных переходах, где переключение режима работы происходит при нажатии кнопки. При данном алгоритме работы, необходимо использовать цикл while в программе. В схему следует добавить тактовую кнопку и переключать режим светофора при высоком уровне сигнала на цифровом (аналоговом) пине к которому была подключена кнопка.
Однако на мой взгляд разумнее заменить конструкцию с while (digitalRead(10) == LOW) на if (digitalRead(KNP) == LOW), тогда по нажатию на кнопку будет последовательное переключение светофора по фазам с возвращением к первой фазе, а вначале loop() первую фазу перенести в конец функции setup() и конец конструкции if().
Фазу переключения светофора выделить в функцию... получается изящно и логика работы светофора по нажатию на кнопку соответствует реальным светофорам для пешеходов.
Ниже публикую небольшой скетч этого светофора. Делал на Arduino Uno.
Какие преимущества моего подхода по сравнению с оригиналом?
Во-первых, чтобы происходило автоматическое переключение не нужно постоянно держать нажатой кнопку. Достаточно раз нажать и далее ждать переключения светофора – как в жизни.
Во-вторых, само переключение светодиодов выделено в функцию fnFazaLED() и эта функция вызывается по ходу программы с нужными аргументами.
В-третьих, в оригинальном скетче сразу после loop() идёт первая фаза
, до цикла while(), что приводит к тому, что программа всегда возвращается на эту фазу и постоянно включает пины светодиодов, даже если они и были уже до этого установлены в нужную позицию – как бы не нужно это делать... совсем.
Мигание зелёным управляется через функцию fnFazaLED() и если последний аргумент не задан, то мигания не происходит, а если указан пин для зелёного светодиода, то на этом пине при смене цвета можно выполнить мигание, в данном случае зелёного света.
В настроечной функции setup(), в момент конфигурации пинов для светодиодов, провожу их проверку, т.к. перед работой любого индикаторного устройства, по моему мнению, необходимо всегда проверять работоспособность хоть светодиодов, хоть светодиодных индикаторов.
/**************************************************** Источник: Светофор на Arduino Uno с кнопкой https://роботехника18.рф/светофор-ардуино/ 2022-07-03 Mr.ALB улучшение исходника СОЕДИНЕНИЯ: Светодиоды катод - GND анод - R 1k R 1k - на пин светодиода Кнопка 1 - GND 2 - пин кнопки 10 Скетч использует 1456 байт (3%) памяти устройства. ***************************************************/ // Присваиваем имена для пинов со светодиодами #define RED1 2 #define ORG1 3 #define GRN1 4 #define RED2 5 #define ORG2 6 #define GRN2 7 #define KNP 10 // Задержки переключения светофора unsigned int pause = 3000, miganie = 500; // Прототип функции void fnFazaLED(bool, bool, bool, bool, bool, bool, byte grnX=0); void setup() { // Конфигурирование пинов и проверка // работоспособности светодиодов for (byte i = 2; i < 8; i++) { pinMode(i, OUTPUT); digitalWrite(i, HIGH); delay(miganie); } // Пин на кнопку pinMode(KNP, INPUT_PULLUP); // Подтяжка к +5В // Первая фаза // Запрет пешеходам fnFazaLED(HIGH, LOW, LOW, LOW, LOW, HIGH); } void loop() { // Переключения не будет, пока не будет нажата кнопка if (digitalRead(KNP) == LOW) { // Первая фаза // Запрет пешеходам fnFazaLED(HIGH, LOW, LOW, LOW, LOW, HIGH, GRN2); // Вторая фаза fnFazaLED( HIGH, HIGH, LOW, LOW, HIGH, LOW); // Третья фаза // Переход пешеходов fnFazaLED( LOW, LOW, HIGH, HIGH, LOW, LOW); fnFazaLED( LOW, LOW, HIGH, HIGH, LOW, LOW, GRN1); // Четвертая фаза fnFazaLED( LOW, HIGH, LOW, HIGH, HIGH, LOW); // Первая фаза // Запрет пешеходам fnFazaLED(HIGH, LOW, LOW, LOW, LOW, HIGH); } } /*********************************** Функция управления светодиодами 2022-07-03 Mr.ALB Параметры: b1...6 = HIGH | LOW grnX = GRN1 | GRN2 *********************************/ void fnFazaLED ( bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, byte grnX = 0 ) { digitalWrite(RED1, b1); digitalWrite(ORG1, b2); digitalWrite(GRN1, b3); digitalWrite(RED2, b4); digitalWrite(ORG2, b5); digitalWrite(GRN2, b6); // мигание зеленого сигнала if (grnX == GRN1 || grnX == GRN2) { digitalWrite(grnX, LOW); delay(miganie); digitalWrite(grnX, HIGH); delay(miganie); digitalWrite(grnX, LOW); delay(miganie); digitalWrite(grnX, HIGH); delay(miganie); digitalWrite(grnX, LOW); delay(miganie); digitalWrite(grnX, HIGH); delay(miganie); } else delay(pause); }
Скетч достаточно закомментирован и надеюсь любому понятно как он работает. Далее небольшое видео для иллюстрации работы светофора.
Светофора для пешеходов
Вначале, по нажатию на кнопку RESET на Arduino или при включении светофора идёт проверка работоспособности всех светодиодов. Далее время ожидания нажатия кнопки пешеходом. По нажатии кнопки переключения светофора, происходит смена цвета и машинам светит запрещающий, а пешеходам зелёный. После происходит автоматическое возвращение в начальное состояние: разрешение машинам и запрет пешеходам.
Используемые программы: