Добрый день, уважаемые читатели!
В этой статье перечислены все имеющиеся на момент написания статьи модули, классы и прочие библиотеки, которые входят в состав моей прошивки на основе ESP-IDF, их назначение и основные свойства. Эту статью, пожалуй, нужно было бы написать уже довольно давно, когда ещё я только начал публиковать описание термостата на esp32. Что ж, лучше поздно чем никогда.
Что это за прошивка такая?
В этой статье описывается заготовка прошивки для ESP32 на основе фреймворка ESP-IDF (Espressif IOT Development Framework), то есть без использования Arduino. Назовем её условно “прошивка k12”, просто по названию данного сайта. Это не официальное название и не торговая марка. На основе этой прошивки созданы термостат, автоматическая теплица, устройство автоматического полива, которые описаны на данном сайте, а также несколько других устройств, которые уже несколько лет подряд успешно функционируют в моем доме с зачатками разума.
Зачем я принялся изобретать велосипед и не использовал что-то готовое? На это есть несколько причин.
- Во-первых, когда-то использовал несколько вариантов готовых прошивок, но сталкивался с невозможностью реализации всех моих хотелок. Ну прямо как в том анекдоте – “весь город устраивает, а его нет“…
- Во-вторых – свои ошибки я могу исправить сам и сравнительно быстро, если таковые обнаружены. А вот добиться исправления проблемы в open source проекте, которое поддерживается комьюнити – зачастую сложно и долго. Сталкивался с исправлением проблем в официальных фреймворках esp-idf и arduino-esp32.
- Ну и самое главное – мне интересно разбираться в коде и писать код. Мне абсолютно не интересен путь “не важно как, лишь бы как-то и хоть иногда работало, и побыстрей”. Когда костыль на костыле и костылем подпёрто.
Данная прошивка идеальна и подходит абсолютно всем? Конечно же нет! В первую очередь я создавал её для себя и для своих задач. А ваши задачи могут существенно отличаться от моих. Например, я выбрал в качество основы основ протокол MQTT, и все построено вокруг него. Кому-то это не подходит. Но вы можете взять только нужные вам библиотеки для своих разработок. И эта статья как раз и создана для того, чтобы помочь вам в этом.
В написанных мной библиотеках совершенно точно есть проблемы и ошибки. Я в этом абсолютно уверен. Про некоторые я знаю, но пока не исправил; какие-то я просто ещё не нашел. Но они не мешают устройствам нормально функционировать по 120 дней подряд без паник, вылетов и перезагрузок по непонятным причинам. И я все ещё работаю над их исправлением. Некоторые модули переписаны уже по нескольку раз. Буду благодарен, если вы мне укажите на них, когда обнаружите.
Мне часто ставят в упрек, что “Arduino поддерживается миллионным комьюнити” и вылизан как котовьи фаберже, а мои поделки создаю только я сам. Совершенно верно подмечено, но увы, это не является гарантией полной защиты от проблем. Даже простой скетч вентиляции для погреба, написанный когда-то в Arduino, никогда не работал дольше месяца без сбоя и аварийной перезагрузки. Arduino очень хорош для начала, он прост и понятен каждому, и именно эта его ключевая особенность. Но вы же не пытаетесь принимать аспирин от всех болезней? Так почему же до сих пор Arduino IDE позиционируется как затычка для всего?
В настоящий момент прошивка разделена на множество вроде бы отдельных частей – библиотек, которые вы можете найти и скачать с GitHub. На самом деле большинство из них все-таки не могут функционировать отдельно от других библиотек. Все-таки у меня получился не набор независимых модулей, а одна прошивка. Поэтому в настоящее время понемногу идет работа на следующей версией библиотек, где все они будут оптимизированы и собраны в единое целое. По аналогии с самой ESP-IDF и esp-idf-lib от UncleRus. Тем не менее, большинство составных частей останутся прежними, поэтому данная статья все равно останется актуальной.
Основные функции и возможности
Основное назначение данной прошивки – создание устройств автоматики с удаленным управлением и контролем через сеть интернет. Обязательное условие – бесперебойная работа автоматики в любых условиях, в том числе и при отсутствии доступа в сеть интернет (разумеется без удаленного контроля).
- Прошивка не имеет собственного web-интерфейса. Поскольку web-интерфейс полезен только в локальной сети, то не вижу никакого смысла его программировать и тратить на него ресурсы микроконтроллера.
- Основной протокол управления и контроля – MQTT. Поддерживаются любые типы серверов – с префиксами и без, с TLS и без оного. Имеется поддержка двух MQTT-брокеров – основного и резервного (например локального и облачного).
- Подключение к нескольким WiFi-сетям (до пяти) с автоматическим выбором. Прошивка не имеет web-интерфейса для настройки подключения к wifi, всё необходимое настраивается только в конфигурационном файле. Несколько преднастроенных сетей позволяет переносить устройство из одной локации в другую без необходимости изменения прошивки.
- Автоматическая синхронизация локального времени с серверами SNTP в сети интернет. Это позволяет в большинстве случаев отказаться от использования модуля часов. Но при необходимости можно легко интегрировать модули DS1307 или DS3231.
- Постоянный мониторинг доступа в сеть интернет с помощью пинга с сохранением истории. Это позволяет приостанавливать сетевые процессы в случае проблем с доступом в сеть и предотвращать аварийные ситуации из-за этого (например из-за переполнения памяти).
- Публикация данных с сенсоров вместе с временем измерения и со всеми экстремумами в одном топике в JSON-виде. Впрочем, можно перенастроить устройство на публикацию данных с сенсоров в открытом виде, если очень хочется.
- Мониторинг состояния сервисов и датчиков с уведомлениями. Это позволяет вовремя обнаружить ситуации, когда “что-то пошло не так”.
- Уведомления в Telegram. Можно привязать до 4 отдельных каналов или чатов: обычный, сервисный, охрана и изменение параметров. Уведомления – не обязательная часть, их можно отключить с помощью файла конфигурации проекта. Автоматические уведомления в Telegram об изменениях состояния устройства, в том числе с настраиваемой задержкой (это позволяет пропускать кратковременные сбои и отключения различных сервисов), об сбоях сенсоров и исполнительных устройств. Но полноценного бота (с обратной связью) на данный момент нет.
- Возможность отправки данных на сторонние сервисы ThingSpeak, Народный мониторинг, Open Monitoring – по выбору, можно использовать даже несколько сервисов одновременно.
- OTA (Over The Air) – обновление прошивки без необходимости физического подключения к устройству, через сеть интернет. Но необходим сервер с прямыми ссылками.
- Расширенные возможности для удаленной отладки: отправка backtrace, списка задач с размером стека, фиксация уровня сигнала, пинга, количества свободной памяти.
Но самое главное – это не полностью готовая прошивка, а скорее гибкий шаблон вашей прошивки. То есть вы вольны изменять многое по своему желанию и потребностям. Какие-то компоненты можно просто отключить с помощью “управляющих” макросов препроцессора – например telegram. Что-то вы можете дописать самостоятельно.
Само собой, поддерживаются все протоколы и возможности, которые заложены собственно в ESP-IDF, например одновременно две шины I2C, шина RS485 и протокол Modbus и т.д.
Что понадобится?
Для работы с этой прошивкой вам понадобится Visual Studio Code с установленным плагином PlatformIO. Инструкция по установке и первоначальной настройке. Конечно, можно использовать и оригинальный плагин от espressif, но тогда вам придется немного переделать сам проект. Кроме того, PlatformIO позволяет программировать и модули Arduino в более удобной IDE.
Структура каталогов
Шаблоны всех прошивок, опубликованных на сайте для ESP32, “рассчитаны” на определенную структуру каталогов на диске.
У меня корневой каталог всех проектов – это C:\PlatformIO. Не в профиле пользователя и не в папке “Мои документы”, как предлагается по умолчанию! Не путайте каталог проектов и каталог установки самого platformio – это совершенно разные вещи!
Все общие библиотеки (то есть те, что используются сразу во всех проектах) лежат внутри корневого каталога проектов в подкаталоге libs. То есть полный путь к общим библиотекам будет C:\PlatformIO\libs.
Каталоги (папки) проектов должны быть расположены внутри уже рассмотренного C:\PlatformIO по аналогии с библиотеками. Например: C:\PlatformIO\thermostat или как на картинке ниже:
Это не означает, что “можно так, и только так“! Cовсем нет, вы вполне можете использовать другие каталоги, как будет удобнее вам. Но тогда вам придется изменить настройки каталогов в нескольких файлах проекта самостоятельно. Не готовы этого сделать? – используете структуру как описано выше.
Структура прошивки
Назначение каталогов и файлов проекта:
- Главный исполняемый файл проекта находится в каталоге .\src – как правило это файл main.cpp. Его подробнее я опишу ниже.
- В папке .\include находится файл настроек проекта project_config.h. В нем описаны большая часть параметров, относящихся к проекту: используемые GPIO контроллера, имя и пароль wifi-сетей, параметры mqtt-брокеров, токены и пароли внешних сервисов и прочее, прочее, прочее. В виде макросов препроцессора.
- В папке .\lib расположены прикладные файлы проекта. Именно здесь реализована основная логика, для чего данное конкретное устройство и было собственно создано. Чаще всего здесь только один подкаталог, однако бывает и несколько. В заголовочных файлах этих библиотек вы найдете и большую часть “прикладных” параметров (сенсоры, параметры автоматического регулирования, настройки актуаторов, кранов, реле и т.д.), просто так удобнее.
- В папке .\layouts могут располагаться схемы подключения и чертежи печатных плат устройства.
- В файле partitions.csv находится разметка flash-памяти устройства. По умолчанию настроена схема с двумя OTA-разделами и большим NVS разделом.
- В файле platformio.ini находятся настройки проекта protformio. Про него я рассказывал здесь.
Главный исполняемый файл проекта main.cpp практически не изменяется от проекта к проекту, я изменяю только указания на то, какие прикладные задачи необходимо запустить в конце всех настроек и инициализаций. После этого он завершается и больше не используется. Выглядит он так:
- Вначале инициализируется система отладочных сообщений – логов.
- Затем подключаются обработчики перезапуска
espRegisterSystemShutdownHandler();
– дабы успеть сохранить на flash-памяти все данные перед тем как устройство будет перезагружено. Но это не всегда удается, например в случае паники никакие пользовательские обработчики не работают. - Затем инициализируем саму систему хранения параметров в NVS –
paramsInit()
; - Запускаем задачу системного светодиода –
ledSysInit(...);
При необходимости, сюда же следует добавить и другие светодиоды. - Запускаем главный цикл событий –
eventLoopCreate();
Это прикладной цикл, отличный от системного, хотя можно использовать и один общий. Но возможны “накладки” - Далее запускаем библиотеку, которая будет отслеживать состояние внутренних служб и датчиков –
statesInit(true);
- Запускаем одну или обе шины I2C (по необходимости) –
initI2C()
. При этомscanI2C();
позволяет вывести в лог все устройства на шине, что иногда облегчает диагностику на начальном этапе. - Запускаем “минутный” таймер и службу расписаний –
schedulerEventHandlerRegister();
. В большинстве случаев для суточных и недельных прикладных расписаний секунды не важны, но желательно отмечать начало каждой минуты, чем она и занимается. - Подключаем обработчик PING-ера, который служит для периодической проверки доступа в сеть интернет –
pingerEventHandlerRegister();
На самом деле пигнер в этот момент не стартует, а будет запущен только после того, как в цикле событий будет сигнал об успешном подключении к WiFi. - Запуск и регистрация службы синхронизации времени –
sntpTaskCreate(true);
Здесь же могут быть подключены микросхемы часов реального времени. - Запуск MQTT клиента –
mqttTaskStart(true);
Опять же, собственно запуска не происходит, просто выполняется инициализация библиотеки и клиент переходит в режим ожидания подключения к WiFi сети. - Регистрируем обработчики событий для системы хранения параметров –
paramsEventHandlerRegister();
- Если включены telegram-уведомления – запускаем задачу отправки уведомлений –
tgTaskCreate();
- Запускаем еще одну задачу, которая будет отправлять данные на ThingSpeak, OpenMonitoring или NarodMon одновременно –
dsTaskCreate(false)
; - Наконец, запускаем прикладные задачи, которые лежат в папке lib – например
sensorsTaskStart();
Здесь можно запустить несколько прикладных задач, в зависимости от назначения устройства. - Последним этапом запускаем службу WiFi –
wifiStart()
. С этого момента все приходит в окончательное движение через систему событий и main.cpp завершает свою работу.
Перечень модулей и библиотек
Ну и наконец, перечислю состав модулей в папке и их назначение C:\PlatformIO\libs.
- certs – здесь просто расположены файлы сертификатов ЦС, используемые для TLS-соединений
- consts – в этом каталоге собраны параметры и настройки, по аналогии с project_config.h, но используемые сразу во всех проектах. Как то: форматы дат и времени, форматы чисел, названия общих топиков и т.д.
- clouds – в этом каталоге собраны библиотеки для работы с внешними сервисами:
- reMqtt – клиент MQTT с возможностью переключения между локальным и облачным серверами “на лету”. По сути, это “обертка” вокруг штатного клиента ESP-IDF.
- reDataSend – служба отправки данных на ThingSpeak, OpenMonitoring или NarodMon. Можно отключить с помощью макросов
CONFIG_OPENMON_ENABLE
,CONFIG_THINGSPEAK_ENABLE
иCONFIG_NARODMON_ENABLE
. Можно легко адаптировать для отправки данных на другие cloud-сервисы посредством REST API. - reTgSend – служба отправки уведомлений в Telegram. Можно отключить с помощью макросов
CONFIG_TELEGRAM_ENABLE
. Имеется встроенная очередь отправки, поэтому сообщения не будут потеряны даже в offline (при наличии свободной оперативной памяти, разумеется).
- peripherals – библиотеки для работы с периферийным оборудованием, кроме датчиков и сенсоров:
- reADCIntf – библиотека-обёртка для интерфейса ADC в ESP-IDF версии от 5.0.0 и выше. Просто для удобства использования
- reAlarm – библиотека для создания охранно-пожарной сигнализации. Поддерживаются как проводные, так и беспроводные датчики. Несколько зон и типов реакции, например можно сделать защиту от протечек. Можно использовать совместно с другим функционалом, например датчики движения использовать для управления освещением.
- reBeep – простейшая библиотечка для пассивного зуммера (бипера) для подачи звуковых сигналов
- reBinStat – отслеживание состояния цифрового входа и публикация этого состояния и времени переключения на MQTT в виде JSON
- reDS1307 – драйвер часов реального времени на чипе DS1307
- reDS3231 – драйвер часов реального времени на чипе DS3231
- reElTariffs – контроль тарифов электроэнергии, если у вас установлен многотарифный счетчик. Пока находится в зачаточном состоянии
- reGpio – контроль состояния входов с использованием прерываний и системы событий
- reLCD – драйвер LCD1602 и LCD2004 через шину I2C с русификацией
- reLed – драйвер мигающе-моргающего светодиода
- reLoadCtrl – управление нагрузкой (реле или ключом) со счетчиками и
белкджеком. Умеет сохранять счетчики в NVS и публиковать здоровенный JSON с подробными сведениями. - reMCP23017 – драйвер расширителя входов MCP23017 с прерываниями
- rePCF8574 – драйвер расширителя входов PCF8574
- reRangeMonitor – контроль за диапазонами температуры, влажности, напряжения и иных параметров с поддержкой уведомлений и JSON
- reRTC – обобщающий модуль для часов реального времени
- reRx433 – приемник сигналов по радиоканалу на частоте 433MHz. Для PIR-датчиков и пультов управления
- reShutter – многошаговый драйвер для управления форточками, кранами и подобными устройствами с помощью мостовых схем
- reTriStat – контроль состояния двух входов, и соответственно, трех состояний. В остальном похож на reBinStat.
- sensors – здесь расположены драйверы для популярных датчиков и сенсоров:
- reSensor – базовый класс для всех остальных драйверов сенсоров. Он предоставляет такие “услуги” как: фильтры по среднему и медианный; фиксацию и хранение экстремумов (минимумов и максимумов); генерацию JSON и т.д.
- reADC – драйвер встроенных ADC входов ESP32. Можно использовать, например, для измерения напряжения аккумулятора
- reAHT1x – драйвер для датчиков температуры и влажности ASAIR AHT10/AHT15/AHT20
- reAM232x -драйвер для датчиков температуры и влажности ASAIR AM2320, AM2321
- reBH1750 – драйвер для датчика освещенности BH1750
- reBME280 – драйвер для датчика давления, температуры и влажности BME280
- reBME68x – драйвер для датчика давления, температуры, влажности и качества воздуха BME680 без использования BSEC
- reBMP280 – драйвер для датчика давления и температуры BMP280
- reBSEC68x – драйвер для датчика давления, температуры, влажности и качества воздуха BME680 c использованием библиотеки BSEC
- reCCS811 – драйвер для датчика качества воздуха CCS811
- reCWTSoilS – драйвер для датчиков влажности почвы CWT-Soil-THCPH-S (подключение через RS485 Modbus RTU)
- reDHTxx – драйвер для датчиков температуры и влажности ASAIR DHT11 / DHT12 / DHT21 / DHT22
- reDS18x20 – драйвер для датчиков температуры семейства Dallas DS18x20
- reFXJT – драйвер для флюгера RS-FXJT-N01 на шине RX485
- reHTU2x – драйвер для датчиков температуры и влажности серий HTU2xD / SHT2x / Si7021
- reMD02 -драйвер для датчика XY-MD02 (SHT20 over RS485)
- reMoisture – драйвер для емкостных датчиков влажности Capacitive Soil Moisture Sensor v1.2 или аналогичных
- reQDY30A – драйвер для датчика уровня жидкости QDY30A (подключение через RS485 Modbus RTU)
- reSHT3x -драйвер для датчиков температуры и влажности SHT30D/SHT31D/SHT35D с нагревателем и порогами
- reTH485 – универсальный драйвер для датчиков температуры и влажности и шины RS485 Modbus RTU
- system – набор общих библиотек
- reCerts – поддержка централизованного хранилища TLS-сертификатов
- reEsp32 – здесь собраны все общие системные функции, функции отладки и макросы перехвата ошибок
- reEvents – прикладной цикл событий и объявление типов событий
- reI2C – обертка стандартной библиотеки i2c.h для удобства использования
- reNotifier – класс для генерации уведомлений о сбоях с возможностью “отложить” уведомления на заданное время
- reNvs – обертка стандартной библиотеки NVS для большего удобства.
- reOTA – готовый модуль для OTA обновлений
- reParams – библиотека для управления системными и прикладными параметрами прошивки. Умеет хранить переменные в NVS, подписываться на топики конфигурации на MQTT сервере, отправлять уведомления об изменении и многое другое. Вам нужно только зарегистрировать вашу переменную в списке параметров, остальной библиотека берет на себя
- reScheduler – как следует из названия, это служба расписаний. Контролируется начало каждой новой минуты (00 секунд) и рассылается соответствующее событие через прикладной цикл событий
- reStates – модуль для контроля состояния системы: подключения к wifi и брокеру, состояния датчиков и т.д. Сбои и ошибки индицируются разным режимом вспышек на системном светодиоде, а также отправляются пользователю в виде уведомлений.
- reSysInfo – служит для периодической публикации на MQTT-брокере системной информации. Можно отключить
- rLog – библиотека для вывода отладочных сообщений вроде ESP_LOG.
- rStrings – библиотека для работы с динамическими строками в памяти. Здесь же пока расположены функции генерации топиков по неким “стандартным” правилам, но позже они переедут в другой моудль.
- rTypes – объявления базовых типов данных и некоторые функции для работы с ними
- wifi – всё, что связано с подключением к сети и интернету
- rePing – библиотека для пинга произвольных серверов в сети с ожиданием завершения
- rePinger – тоже пингер, но только для контроля доступа в сети интернет. Пингуется обычно yandex.ru и google.com, но их можно изменить
- reSNTP – обертка вокруг esp_sntp.h для запуска службы синхронизации времени
- reWiFi – модуль для подключения и поддержания соединения к сети wifi с возможностью указания до 5 сетей.
Вот, в общем-то и всё, что имеется на данный момент в моем арсенале. Пока этого было достаточно для всех моих устройств автоматики. Но по мере появления новых идей список может быть расширен. Некоторые из перечисленных библиотек и примеры использования я опишу более подробно в следующих статьях. Почти все из перечисленных библиотек имеются на моем GitHub, при наличии некоего опыта вы можете свободно взять любую из них и переделать под свои нужды.
На этом пока всё, до встречи на сайте и на telegram-канале!
💠 Полный архив статей вы найдете здесь
Пожалуйста, оцените статью:
Здравствуйте! С удовольствием читаю Ваши статьи. Хочу задать немного отвлечённый вопрос. Есть интересный проект, SIP-звонок для домофона, реализованный на ESP-IDF под ESP32. Хочу его повторить, но никак не получается его скомпилировать. Выдаёт ошибку: “undefined reference to `app_main'”. Вы, как человек, разбирающийся в ESP-IDF, могли бы посмотреть, почему проект не компилируется, конечно, если это Вам интересно? Я задал вопрос на ru.stackoverflow.com, но пока глухо как в танке. И все мои попытки разобраться, почему же так происходить пока не дали результатов.
Проект sip-call: https://github.com/sikorapatryk/sip-call
Вопрос на stackoverflow: https://ru.stackoverflow.com/questions/1572478/%d0%9d%d0%b5-%d0%bc%d0%be%d0%b3%d1%83-%d1%81%d0%ba%d0%be%d0%bc%d0%bf%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d1%82%d1%8c-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82-%d0%b4%d0%bb%d1%8f-esp-idf
С уважением, Олег
Здравствуйте. А в чем вы его пытались компилировать? Проект в исходном виде создан для Espressif IDE. Если нужно для PlatformIO к примеру – его нужно чутка переделывать. В Arduino IDE вообще не получится.
Компилировал из под esp-idf командой: idf.py make
Вернее командой idf.py build
Вечером если будет время – попробую
Я вроде бы понял, в чём причина, правда, решения пока не нашёл – папка “main”, как и каждый компонент в папке “components”, должны содержать файл “CMakeList.txt”, в которых описываются зависимости проекта, а этих файлов в проекте нет. Видимо автор проекта забыл их запушить в репозиторий. Осталось теперь понять, какое содержимое должно быть в этих файлах
Смотрели проект?
Пока нет
В reMqtt.h исправьте #include “reWifi.h” на #include “reWiFi.h”
На Linux системах PlatformIO ругается что не может найти файл.
Принято, исправлю.