Библиотека Arduino для мигания светодиодами

Казалось бы – зачем нужна какая-то библиотека для мигания светодиодом на ESP? Мигание светодиодом сложности особой не представляет. Делов-то – “дергай” соответствующий вывод микроконтроллера, вот светодиод и мигает. Мало того – все “демки” для микроконтроллеров с этого начинаются, своеобразный “Hello, world” для ардуинщиков.
Однако всё меняется, когда хочется “выжать” из единственного светодиода максимум полезной информации. Видели как работает светодиод на автосигнализации? Когда все “спокойно” – мигнет кратенько один раз в несколько секунд и все. Если тревога – по количеству вспышек уже можно определить, что случилось. Этот же метод обозначения неисправностей используется и на множестве других устройств – смарткассах, принтерах и т.д.
Да еще при этом как бы не особо хочется отвлекаться от основной задачи. Конечно, описанный выше алгоритм можно реализовать на циклах и задержках, но это муторно и долго. И нужно постоянно помнить о светодиодах и текущих режимах мигания. Вот бы сделать так, что бы “отправил светодиоду команду, как мигать – и забыл”.
Описанная в данной статье библиотека как раз и решает обе задачи.

Данная версия библиотеки может быть использована на любом микроконтроллере, в том числе и на ESP32. Для ESP32 есть более оптимальный вариант, реализованный в виде задачи FreeRTOS. Сия библиотека написана и отлажена на PlatformIO, но на Arduino IDE так же будет работать, пример вложен в архив с исходниками. Ссылки на скачивание в конце статьи

 

Возможности и описание работы:

  • Управление светодиодами по принципу “вызвал команду и забыл”. Для управления каждым отдельным светодиодом создается свой экземпляр класса rLed. Но не забудьте добавить вызов ledLoop() в функцию loop() Вашего скетча, иначе чуда не произойдет.
  • Возможные режимы работы:
    • ledOff(); – светодиод выключен постоянно
    • ledOn(); – светодиод включен постоянно
    • flashSet(quantity, duration, interval) – мигнуть заданное количество раз с заданными длительностью и периодом, а затем выключить
    • blinkSet (quantity, duration, period) – мигать постоянно с заданными длительностью и периодом. Если указано количество quantity > 1, то светодиод будет мигать сериями вспышек. Для равномерного мигания (меандром) необходимо указать длительность равной периоду и quantity = 1
    • blinkOff – отключить мигание
  • Имеется возможность принудительно подавить вспышки светодиода на какое-то время. Например, можно гасить светодиоды на устройствах в ночное время, дабы не мешать сну. 
  • Возможно включение светодиода как с помощью установки высокого уровня, так и низкого (в зависимости от схемы подключения светодиода). Кроме того, поддерживается работа не только с GPIO микроконтроллера, но и управление светодиодами через I2C платы расширения типа PCF8574 с помощью пользовательской функции обратного вызова.
  • “Системный” светодиод для отображения состояния устройства. Системный светодиод удобен тем, что “о нем заранее известно” другим библиотекам, и можно отправлять команды из библиотеки подключения к WiFi, MQTT, Telegram и т.д. Управление светодиодом можно как по аналогии с “обычными” светодиодами, так и с помощью установки специальных статусов (заранее предустановленные режимы мигания):
    • SYSLED_ERROR – “общая” ошибка
    • SYSLED_WARNING – предупреждение
    • SYSLED_WIFI_CONNECTED – подключение к WiFi точке доступа установлено
    • SYSLED_WIFI_INET_AVAILABLE – интернет доступен (можно определить с помощью ping-а)
    • SYSLED_WIFI_ERROR – ошибка подключения к WiFi (точка доступа не доступна или авторизация не проходит)
    • SYSLED_MQTT_ERROR – не удается подключиться к MQTT-брокеру или отправить данные
    • SYSLED_TELEGRAM_ERROR – не удается отправить данные в telegram-канал
    • SYSLED_OTHER_PUB_ERROR – не удается отправить данные на другие ресурсы (ThingSpeak и т.д.)

Режим мигания является “запоминаемым”. Достаточно отправить светодиоду команду blinkSet, и этот режим мигания будет автоматически восстанавливаться после любых ledOn+ledOff и (или) flashSetавтоматически. Это позволяет не задумываться о том, какой режим мигания был установлен, если возникает необходимость срочно помигать светодиодиком для индикации каких либо событий. Чтобы отключить мигание совсем – необходимо отправить команду blinkOff. Например, у меня “нормальный” режим работы обозначается редкими одиночными вспышками один раз в 3 секунды. В случае какого-либо сбоя в работе (нет wifi, например) – режим мигания меняется. Если необходимо “обозначить” отправку данных на mqtt-брокер я просто отправляю ledOn в начале передачи пакета, и ledOff в конце. Можно также использовать команду на серию вспышек flashSet для большей заметности. Когда задача получит команду ledOff (либо серия будет завершена), она автоматически восстановит последний режим мигания, если он был активирован.

Пример:

ledOn():                светодиод включен
ledOff():               светодиод выключен
flashSet(3, 100, 500):  светодиод мигнет три раза с длительностью 100 мс с паузой между вспышками по 500 мс, после чего погаснет
blinkSet(2, 100, 5000): светодиод начинает мигать сериями из 2 вспышек с длительностью 100 мс и паузой между сериями 5000 мс
ledOn():                светодиод включен, мигание временно приостановлено
ledOff():               возвращаемся к последнему режим мигания (сериями из 2-х миганий по 100 мс через 5 секунд)
flashSet(30, 100, 500): светодиод мигнет 30 раз с длительностью 100 мс с паузой между вспышками 500 мс
                        после чего снова автоматически возвращаемся в последний режим мигания (сериями из 2-х миганий по 100 мс через 5 секунд)
ledOff():               ничего не изменится ;-)
blinkSet(1, 500, 500):  изменение режима мигания - непрерывное равномерное мигание 0,5 с горит / 0,5 с не горит
blinkOff():             отключить режим мигания, светодиод выключен

Разумеется, между командами должны быть какие-нибудь промежутки времени, чтобы светодиод успел отработать команды. Без этих пауз светодиод сразу выполнит их все и выключится (последняя команда).


Видео, демонстрирующее работу библиотеки:

Видео было записано на версии для ESP32, но на других контроллерах все выглядит точно также

  • Красный светодиод на видео – “системный”. Он отображает “общее” состояние устройства. При включении имитирует подключение к WiFi (равномерное мигание). После соединения с WiFi (через 10 секунд) переходит в режим “проверка интернета / нет интернета” (две вспышки – пауза, две вспышки – пауза и т.д.). Еще через 5 секунд переходит в нормальный режим (редкие вспышки). Еще через некоторое время светодиод мигнет однократной серией для отображения передачи данных в эфир и вернется в “нормальный” режим.
  • Синий светодиод просто мигает с частотой 1 Гц (0,5 секунды вспышка + 0,5 секунды пауза)
  • Желтый светодиод тоже мигает постоянно, но уже длительность паузы в 4 раза больше длительности вспышки.
  • Зеленый светодиод мигает сериями по 3 коротких (100 мс) вспышки через каждые 2 секунды.


Демонстрационный проект

Подходит как для PlatfromIO, так и для Arduino IDE (скачать архив вместе с вложенной библиотекой можно в конце статьи)

#include "rLed.h"
#include "rLedSys.h"

rLed ledBlue(D3, true);
int step = 0;

void setup() {
  Serial.begin(74880);

  Serial.println("ledSystem: Connect to WiFi...");
  ledSysInit(D4, false, false, NULL);
  ledSysBlinkAuto();

  Serial.println("ledBlue: Init LED & turn on");
  ledBlue.initGPIO();
  ledBlue.ledOn();
}

void loop() {
  ledSysLoop();
  ledBlue.ledLoop();

  if (step == 0 && millis() > 5000) {
    step = 1;
    Serial.println("ledSystem: Connected to WiFi, retrive SNTP time...");
    ledSysStateSet(SYSLED_WIFI_CONNECTED);

    Serial.println("ledBlue: Set blink mode");
    ledBlue.blinkSet(3, 100, 1000);  
  };
  
  if (step == 1 && millis() > 25000) {
    step = 2;
    Serial.println("ledSystem: Connected to WiFi, all OK...");
    ledSysStateSet(SYSLED_WIFI_INET_AVAILABLE);

    Serial.println("ledBlue: Set flash mode");
    ledBlue.flashSet(10, 100, 300);  
  };
  
  if (step == 2 && millis() > 60000) {
    step = 3;

    Serial.println("ledSystem: set error...");
    ledSysStateSet(SYSLED_ERROR);

    Serial.println("ledBlue: Disable LED");
    ledBlue.ledEnabled(false);  
  };
  
  if (step == 3 && millis() > 90000) {
    Serial.println("ledSystem: clear error...");
    ledSysStateClear(SYSLED_ERROR);

    Serial.println("ledBlue: Enable LED");
    step = 4;
    ledBlue.ledEnabled(true);  
  };
}

Описание функций

Для создания экземпляра класса rLed используйте конструктор:

rLed(const int8_t ledGPIO, const bool ledHigh);

где:
ledGPIO – номер вывода, к которому подключен светодиод.
ledHigh – true = включение с помощью установки на GPIO высокого уровня, false = с помощью установки на GPIO низкого уровня.

Если необходимо использовать функцию обратного вызова, укажите ее дополнительно через setCustomControl(const ledCustomControl_t customControl).

Для инициализации GPIO на вывод используйте функцию initGPIO(). Но можно этого не делать, она будет вызвана автоматически при первом обращении к светодиоду. При использовании customControl инициализация порта не производится, Вы должны сделать это самостоятельно.

После этого можно использовать остальные публичные методы для изменения режимов:

void ledEnabled(const bool newEnabled);
void ledOn();
void ledOff();
void blinkOn(const ledMode_t newMode, const uint16_t blinkQuantity, const uint16_t blinkDuration, const uint16_t blinkInterval);
void blinkSet(const uint16_t blinkQuantity, const uint16_t blinkDuration, const uint16_t blinkInterval);
void flashSet(const uint16_t flashQuantity, const uint16_t flashDuration, const uint16_t flashInterval);
void blinkOff();

Самое главное – не забудьте добавить ledLoop() в Вашу главную функцию loop()!

Изменение режимов мигания для системного светодиода может быть осуществлено с помощью макросов предпроцессора, определенных в файле project_config.h. Файл project_config.h может отсутствовать, в этом случае будут использованы значения по умолчанию.
Необходимо, чтобы этот файл при компиляции был доступен не только из главного скетча, но и из библиотек.

В PlatformIO можно указать компилятору, где искать файл project_config.h, с помощью опции build_flags = -Iкаталог в platformio.ini.
Например, я поместил project_config.h в подкаталог src (там же, где и основной файл проекта). В этом случае я добавлю в platformio.ini следующие строки:

[env]
build_flags = -Isrc

В Arduino IDE я пока не нашел другого способа, кроме как скопировать исходники библиотек и project_config.h в тот же каталог, где и располагается сам скетч. Это не очень удобно, но Arduino IDE и сама по себе не самый удобный инструмент.


Скачать библиотеку можно с помощью кнопки:

В архиве Вы также найдете примеры скетча для Arduino IDE и PlatformIO – загляните в папку examples

Значок
rLed :: библиотека и демо-проекты для ArduinoIDE & PlatformIO

Библиотека асинхронного управления светодиодами + демонстрационные проекты для PlatformIO и ArduinoIDE.


Версия для ESP32:

То же самое, но реализовано в виде задачи FreeRTOS. Читать здесь.

Значок
rLed32 :: библиотека для ESP32 и демо-проекты для ArduinoIDE & PlatformIO

Библиотека асинхронного управления светодиодами для ESP32 + демонстрационные проекты для PlatformIO и ArduinoIDE.


✳️ Другие мои библиотеки для PlatformIO и ArduinoIDE

Благодарю за внимание.


Метки:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *