Перейти к содержимому

Добрый день, уважаемые читатели!

Если вы читали мои статьи про термостат, теплицу, и другие устройства на базе этой же прошивки, то наверное заметили, что в любой такой конструкции присутствует так называемый “системный” светодиод, с помощью которого можно навскидку определить состояние устройства. Многие, наверняка, уже залезли в недра моего г…кода и выяснили, как он мигает в различных случаях и где это просмотреть и изменить. Сам я пока об этом не рассказывал, что ж, исправляю эту оплошность.

 


Что такое системный светодиод, и зачем он нужен

Устройство на базе ESP32 – штука сложная. К контроллеру, как правило, подключены датчики и исполнительные устройства (реле, ключи и т.д.). Сам контроллер в нормальном состоянии подключен к WiFi, MQTT-брокеру и другим сервисам. Любой из перечисленных компонентов системы в любой момент времени может “отвалиться” по любой причине. Если вы подключены к ESP32 кабелем и смотрите с неё логи с в терминале – то вы без труда определите причину проблем и по возможности сможете устранить её. А что, если устройство давно покинуло рабочий стол и находится в коробочке на месте постоянной дислокации? Конечно, при наличии в устройстве дисплея – можно решить этот вопрос выводом ошибки на дисплей, но – далеко не в каждом устройстве нужен дисплей, да и место на экране “не резиновое”.

Если у вас есть автомобиль, а на этом автомобиле у вас установлена сигнализация, то вы наверное заметили, что индикаторный светодиод мигает не всегда одинаково. Когда охрана отключена – он “молчит”, когда авто просто “на охране” – один режим мигания, когда авто “на автозапуске” – другой режим. Похожие методы часто используют производители и других устройств. 

Что-то похожее воспроизвел и я. С помощью одного единственного светодиода можно отображать различные проблемы в работе устройства. Ниже будет рассказано какие именно последовательности что отображают, а также где это можно изменить при необходимости. 

 


Отображаемые состояния

Системный светодиод отображает следующие состояния:

  • Нормальное состояние – wifi подключен, mqtt подключен, все службы и датчики работают нормально. В этом случае светодиод вспыхивает один раз в 5 секунд, длительность вспышки – 75 мс.
  • Отправка данных – обмен данными с внешним миром может дополнительно индицироваться с помощью внеочередной серии из 3 вспышек длительностью 50 и интервалом между ними 75 мс. После окончания передачи режим мигания будет восстановлен на предыдущий (например нормальный).
  • OTA – обновление прошивки – при обновлении прошивки светодиод непрерывно мигает сериями по 3 вспышки длительностью 75 мс с интервалом 250 мс между сериями
  • Что-то пошло не так – общая ошибка, где и что – не совсем понятно, берем молоток и зубило для исследования. В этом случае светодиод непрерывно мигает с частотой 2 Гц – вспышка 1с, пауза 1с.
  • Подключение к WiFi – пока соединение с WiFi не установлено, светодиод непрерывно мигает с частотой 20 Гц и скважностью 0,5, то есть 100 мс вспышка и 100 мс – пауза.
  • Обновление системного времени – после подключения к сети интернет производится проверка доступа к сети (с помощью ping-а) и получение системного времени с серверов NTP. В этот период светодиод мигает сериями по две вспышки 100 мс с паузой 0,5 с между сериями.
  • Нет доступа к сети интернет – если в процессе ping-а выяснится, что подключение к сети сеть, но “интернет кончился”, то светодиод мигает сериями уже по 3 вспышки 100 мс с паузой 0,5 с между сериями.
  • Сбой сенсора – если вдруг не удалось пообщаться с каким-либо из сенсоров, который важен для нормального функционирования устройства, то это может быть отображено двумя вспышками длительностью 250 мс с паузой 3 секунды. Увеличенная длительность вспышек позволяет легко отличить их от других режимов.
  • Сбой MQTT – при невозможности подключения к MQTT-брокеру (основному и резервному) светодиод мигает сериями по 3 вспышки длительностью 250 мс с паузой 3 секунды.
  • Сбой внешних сервисов накопления данных – при невозможности отправки данных на внешние сервисы (ThingSpeak, Народный мониторинг, Open Monitoring и другие) светодиод мигает сериями по 4 вспышки длительностью 250 мс с паузой 3 секунды.
  • Сбой telegram – при невозможности отправки сообщения в telegram светодиод мигает сериями по 5 вспышек длительностью 250 мс с паузой 3 секунды.
  • Сбой SMTP – при невозможности отправки сообщения электронной почты светодиод мигает сериями по 5 вспышек длительностью 250 мс с паузой 3 секунды. Зарезервировано.

В текущей версии системный светодиод не умеет отображать сразу несколько проблем, поэтому используется некая приоритезация:

  • ОТА update
  • General error
  • Sensors failure
  • WiFi state
  • Inet available
  • Time error
  • MQTT error
  • OpenMon / NarodMon / ThingSpeak error
  • Telegram error
  • SMTP error

И только если все это в порядке, то отображается режим Normal mode. После устранения проблемы режим мигания возвращается к предыдущему состоянию – в идеале к нормальному режиму. 

 


Как изменить режимы мигания

Если вас не устраивают перечисленные выше режимы, то вы можете их изменить. Для этого откройте папку C:\PlatformIO\libs\consts и найдите файл def_led_modes.h. В нем, с помощью макросов препроцессора, обозначены все вышеперечисленные режимы мигания – изменяйте как хотите, но имена макросов должны остаться точно такими, какие они есть:

  • #define CONFIG_LEDSYS_xxx_QUANTITY – количество миганий в серии
  • #define CONFIG_LEDSYS_xxx_DURATION –  длительность вспышки в миллисекундах
  • #define CONFIG_LEDSYS_xxx_INTERVAL – длительность паузы между сериями в миллисекундах

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

#define CONFIG_SYSLED_SEND_ACTIVITY 1

Можно, конечно, и в def_led_modes.h этот макрос запихнуть – тогда он будет действовать для всех ваших проектов сразу.

Ссылка на файл: https://github.com/kotyara12/consts/blob/master/def_led_modes.h

 


Как использовать SysLed в своих корыстных целях

Вы также можете использовать системный светодиод и в своем коде – например добавить “свои” режимы мигания или просто включать светодиод на время выполнения каких-либо операций. Только следует делать это достаточно аккуратно, чтобы не сломать логику основной системы.

Итак, в первую очередь следует добавить #include “reStates.h” –  сейчас все функции управления системным светодиодом пока находятся здесь (в будущей версии прошивки они вероятнее всего переедут в другой модуль). Далее вы можете воспользоваться одной из следующих функций:

  • void ledSysOn(const bool fixed); – включить системный светодиод в постоянном режиме
  • void ledSysOff(const bool fixed); – отменить постоянный режим
  • void ledSysSet(const bool newState); – переключить постоянный режим (по сути это универсальная замена ledSysOn и ledSysOff)
  • void ledSysSetEnabled(const bool newEnabled); – разрешить или запретить работу системного светодиода. Используется при переключении тихого режима
  • void ledSysActivity(); – обозначить активность устройства (быстренько-шустренько помигать три раза)
  • void ledSysFlashOn(const uint16_t quantity, const uint16_t duration, const uint16_t interval); – помигать заданное количество раз и успокоиться, интервал задает интервал между импульсами
  • void ledSysBlinkOn(const uint16_t quantity, const uint16_t duration, const uint16_t interval); – включить режим постоянного мигания с заданным количеством импульсов в серии и паузой между сериями
  • void ledSysBlinkOff(); – отключить режим постоянного мигания

Более подробно про все эти режимы я когда-то писал здесь, можете ознакомиться более подробно. Стоит только помнить, что для системного светодиода режим постоянного мигания в приоритете, и библиотека всегда запоминает последний режим мигания. Поэтому ledSysOn + ledSysOff вызовет не гашение светодиода, а возврат к последнему режиму мигания. Для того, чтобы полностью погасить светодиод, нужно дополнительно вызвать ledSysBlinkOff() еще раз – вот тогда будет отменен последний сохраненный режим мигания.

Ссылка на библиотеку reLed: https://github.com/kotyara12/reLed

Ссылка на библиотеку reStates: https://github.com/kotyara12/reStates

 


Ночной (тихий) режим

Если устройство установлено в жилом помещении, то вспышки светодиода могут мешать сну и раздражать в ночное время. Дабы устранить это недоразумение, предусмотрен “тихий” режим, который отключает индикацию и звуки в ночное время. По умолчанию эта опция гасит только системных светодиод, но можно отключать и другие светодиоды и экраны, а также, например, звуки.

Ночной режим определяется с помощью макросов CONFIG_SILENT_MODE_ENABLE и CONFIG_SILENT_MODE_INTERVAL, первый определяет доступность данной опции в прошивке, второй – интервал времени суток для тихого режима в ЧЧММ-ЧЧММ, по умолчанию это 22000600UL или 22:00-06:00 в нормальном представлении. После запуска устройства это значение записывается в память, и в дальнейшем им можно управлять через MQTT (как любым параметром устройства), для этого используется пара топиков %location%/%device%/config/silent_mode/timespan и %location%/%device%/confirm/silent_mode/timespan. При этом вы можете спокойно использовать интервалы “с переходом через 0”. Для отключения опции можно установить интервал 00:00-00:00, для включения на все время 00:00-24:00 (да, да, именно так).

В случае использования только одного единственного системного светодиода больше ничего, собственно, и не требуется. В прошивке уже есть весь необходимый код. А вот если вам необходимо “погасить” дополнительные экран или светодиод, то нужно поймать специальные сообщения о переключении тихого режима.

Делается это так. В начале необходимо написать обработчик событий для RE_TIME_SILENT_MODE_ON и RE_TIME_SILENT_MODE_OFF:

static void sensorsTimeEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
  if (event_id == RE_TIME_SILENT_MODE_ON) {
    // Начало тихого режима - отключаем звуки через активный зуммер
    ledTaskSend(buzzer, lmEnable, 0, 0, 0);
  } else if (event_id == RE_TIME_SILENT_MODE_OFF) {
    // Окончание тихого режима - разрешаем звуки через активный зуммер
    ledTaskSend(buzzer, lmEnable, 1, 0, 0);
  };
  ...
}

Здесь в качестве примера использовано “гашение” звуков активного зуммера, но для светодиода всё выглядит в точности так же. Очень походим образом можно погасить подсветку экрана, например. В данном конкретном случае все довольно просто, потому как функция ledTaskSend сама по себе своя собственная потокобезопасна, и поэтому не трубется дополнительных ухищрений и синхронизаций.

Затем необходимо зарегистрировать наш обработчик (один раз, разумеется):

eventHandlerRegister(RE_TIME_EVENTS, ESP_EVENT_ANY_ID, &sensorsTimeEventHandler, nullptr)

Вот, собственно и всё. Когда наступит время начала или окончания системный шедулер разошлет системное оповещение, наша функция его прочитает и выполнит всё, что требуется. 

 


На этом разрешите откланяться, надеюсь материал был вам полезен. С сами был Александр aka kotyara12. Благодарю за внимание.

💠 Полный архив статей вы найдете здесь


Пожалуйста, оцените статью:
[ 5 из 5, всего 5 оценок ]

2 комментария для “Прошивка K12 для ESP32. Системный светодиод”

  1. Аркадий

    Самое сложное (для меня, во всяком случае) – запомнить и не забыть через неделю, какой режим мигания что означает. Я бы предложил индицировать двумя цифрами по азбуке Морзе, а рядом с устройством – памятка с описанием

    1. Это да, согласен ?
      Но поверьте – запомнить сложно только первое время. Потом привыкаешь. Особенно когда устройств в доме перевалило за десяток

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

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