Добрый день, уважаемый читатель! В данной статье я хочу представить вам одну из своих библиотек: reLed - задача для мигания светодиодами по команде.
Казалось бы – зачем нужна какая-то библиотека для мигания светодиодом на ESP? Мигание светодиодом сложности особой не представляет. Делов-то – “дергай” соответствующий вывод микроконтроллера, вот светодиод и мигает. Мало того – все “демки” для микроконтроллеров с этого начинаются, своеобразный “Hello, world” для ардуинщиков.
Однако всё меняется, когда хочется “выжать” из единственного светодиода максимум полезной информации. Видели как работает светодиод на автосигнализации? Когда все “спокойно” – мигнет кратенько один раз в несколько секунд и все. Если тревога – по количеству вспышек уже можно определить, что случилось. Этот же метод обозначения неисправностей используется и на множестве других устройств – смарткассах, принтерах и т.д.
Да еще при этом как бы не особо хочется отвлекаться от основной задачи. Конечно, описанный выше алгоритм можно реализовать на циклах и задержках, но это муторно и долго. И нужно постоянно помнить о светодиодах и текущих режимах мигания. Вот бы сделать так, что бы “отправил светодиоду команду, как мигать – и забыл”.
Описанная в данной статье библиотека как раз и решает обе задачи.
Возможности и описание работы
Асинхронное управление светодиодами по принципу “отправил команду и забыл”. Для управления каждым отдельным светодиодом создается отдельная задача FreeRTOS с минимально возможным стеком, у меня это всего 1024 байт. При этом потребление ресурсов процессора происходит в основном только в момент переключения светодиода или обработки команды, в остальное время задача игнорируется менеджером задач FreeRTOS. То есть нагрузка на процессор для десятка светодиодов не намного отличается от одного.
Поддерживается включение светодиода как путем установки высокого уровня, так и низкого (в зависимости от схемы подключения светодиода). Кроме того, имеется возможность работы не только с выводами GPIO самого микроконтроллера, но и управление светодиодами через плату расширения I2C (например PCF8574 или MCP23017) с помощью пользовательской функции обратного вызова.
Есть возможность принудительно подавить вспышки светодиодов на некоторое время (например, можно отключать светодиоды на устройствах на ночь, чтобы не мешать сну).
Эту же библиотеку можно использовать не только для светодиодов, но и для подачи серии звуковых сигналов, например. Только в качестве полезной нагрузки следует использовать активный зуммер.
Поддерживаемые режимы:
- lmOff – светодиод выключен постоянно
- lmOn – светодиод включен постоянно
- lmFlash (quantity, duration, interval) – одиночная серия вспышек: мигнуть заданное количество раз с заданными длительностью и периодом, а затем выключить
- lmBlinkOn (quantity, duration, period) – повторяющиеся серии вспышек: мигать постоянно с заданными длительностью и периодом. Если указано количество quantity > 1, то светодиод будет мигать сериями вспышек. Для равномерного мигания (меандром) необходимо указать длительность равной периоду и quantity = 1
- lmBlinkOff – отключить мигание
- lmEnable - разрешить или запретить мигание вообще. При отправленном значении равном 0, все внутренние процессы в задаче проходят по прежнему, но сигнал до ножки микросхемы не доходит. Используется для включения тихого режима
Режим мигания lmBlinkOn может являться “приоритетным” (но не обязательно). Достаточно отправить светодиоду команду lmBlinkOn, и этот режим мигания будет автоматически восстанавливаться после любых lmOn+lmOff и (или) lmFlash автоматически. Это позволяет не задумываться о том, какой режим мигания был установлен, если возникает необходимость срочно помигать светодиодиком для индикации каких либо событий. Чтобы отключить мигание совсем – необходимо отправить команду lmBlinkOff. Например, у меня “нормальный” режим работы обозначается редкими одиночными вспышками один раз в 3 секунды. В случае какого-либо сбоя в работе (нет wifi, например) – режим мигания меняется. Если необходимо “обозначить” отправку данных на mqtt-брокер я просто отправляю lmOn в начале передачи пакета, и lmOff в конце. Можно также использовать команду на серию вспышек lmFlash для большей заметности. Когда задача получит команду lmOff (либо серия будет завершена), она автоматически восстановит последний режим мигания, если он был активирован.
Пример:
Видео, демонстрирующее работу библиотеки:
- Красный светодиод на видео – “системный”. Он отображает “общее” состояние устройства. При включении имитирует подключение к WiFi (равномерное мигание). После соединения с WiFi (через 10 секунд) переходит в режим “проверка интернета / нет интернета” (две вспышки – пауза, две вспышки – пауза и т.д.). Еще через 5 секунд переходит в нормальный режим (редкие вспышки). Еще через некоторое время светодиод мигнет однократной серией для отображения передачи данных в эфир и вернется в “нормальный” режим.
- Синий светодиод просто мигает с частотой 1 Гц (0,5 секунды вспышка + 0,5 секунды пауза)
- Желтый светодиод тоже мигает постоянно, но уже длительность паузы в 4 раза больше длительности вспышки.
- Зеленый светодиод мигает сериями по 3 коротких (100 мс) вспышки через каждые 2 секунды.
Пример работы на реальном устройстве:
Использование библиотеки
Для создания задачи управления светодиодом используйте функцию ledTaskCreate:
ledQueue_t ledTaskCreate(int8_t ledGPIO, bool ledHigh, bool blinkPriority, const char* taskName, const uint32_t taskStackSize, ledCustomControl_t customControl);
Параметры:
- int8_t ledGPIO - номер вывода GPIO или PCF8574
- bool ledHigh - логический уровень (0 или 1) для включения светодиода
- bool blinkPriority - приоритет режима мигания. Если true, то будет запоминаться последний режим мигания; если false - то нет.
- const char* taskName - наименование задачи управления светодиодом
- const uint32_t taskStackSize - размер стека задачи управления светодиодом, для встроенных GPIO достаточно 1024 байт. При использовании PCF8574 нужно уже как минимум 2048 байт
- ledCustomControl_t customControl - функция обратного вызова при использовании PCF8574 или аналогичных микросхем, для встроенных GPIO передайте NULL
Функция вернет указатель на очередь задачи, в которую потом мы будет отправлять наши команды. Поэтому сохраните эти данные в глобальной или статической переменной.
После этого, можно отправлять команды на переключение режима работы в созданную очередь, используя функцию ledTaskSend:
bool ledTaskSend(ledQueue_t ledQueue, const ledMode_t msgMode, const uint16_t msgValue1, const uint16_t msgValue2, const uint16_t msgValue3);
Параметры:
- ledQueue_t ledQueue – указатель на очередь, созданную в ledTaskCreate(…).
- const ledMode_t msgMode – устанавливаемый режим работы (или команда): lmEnable / lmOff / lmOn / lmFlash / lmBlinkOn / lmBlinkOff (описание см. выше)
- const uint16_t msgValue1 – количество вспышек для lmFlash и lmBlink. Для команды lmEnable в этом параметре передается доступность светодиода.
- const uint16_t msgValue2 – длительность вспышек для lmFlash и lmBlink в миллисекундах. Для остальных режимов игнорируется
- const uint16_t msgValue3 – длительность паузы между вспышками для lmFlash или длительность паузы между сериями вспышек lmBlink в миллисекундах. Для остальных режимов игнорируется
Инициализация встроенного GPIO при запуске задачи будет выполнена автоматически. Для PCF8574 или аналогов вы должны сделать это самостоятельно.
Как видите, ничего сложно тут нет...
Вопрос к читателям: нужен ли более подробный пример для работы с данной библиотекой? Если да, то жду ваших комментариев...
Ещё раз оставлю ссылку на библиотеку, дабы не прокручивать статью вверх:
_______________
На этом пока всё, до встречи на сайте и на dzen-канале!
👍 Понравилась статья? Поддержите канал лайком или комментарием! Каналы на Дзене "живут" только за счет ваших лайков.
📌Подпишитесь на канал и вы всегда будете в курсе новых статей.
🔶 Полный архив статей вы найдете здесь
Благодарю за вашу поддержку! 🙏