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

Почему именно ESP32 и ESP-IDF, а не Arduino?

Данная статья – начало цикла статей, посвященных программированию популярного ESP32 на “родном” для этого микроконтроллера фреймворке ESP-IDF. Без использования Arduino. В статье рассмотрен вопрос, зачем же это все-таки нужно и почему в конце-концов я выбрал ESP32 как основу для всех своих последних проектов домашней автоматизации. Ведь существует огромное количество микроконтроллеров других производителей: PIC (Mictochip), AVR (Atmel), ATM (STMicroelectronics), ESP8266??? Некоторые из них обладают гораздо лучшими характеристиками, например по экономичности, да и стоят иногда дешевле…

Как наверное и большинство, я начинал с плат Arduino и Arduino IDE. Однако очень скоро я понял, что мне критически важны удаленный контроль и удаленное управление устройствами. А это означает, что устройство должно иметь возможность подключения к сети, желательно посредством WiFi, чтобы не плодить паутину кабелей и проводов. Встроенный WiFi “на борту” имеют ESP8266 и ESP32 производства Espressif Systems. Да, я знаю, что есть платы сетевых интерфейсов для Arduino, но…

Кроме того, меня сильно смущал тот факт, что сложный и разветвленный функционал в однопоточном приложении Adruino сделать достаточно сложно – чтобы устройство вело себя стабильно, необходимо прилагать особые усилия, чтобы каждая из функций внутри основного цикла loop() выполнялась не дольше нескольких микросекунд. При росте сложности программы и наращивании функционала сделать это становится все сложнее и сложнее. Как правило, хоть иногда “что-то идет не так” и какая-то из функций зависает, что может привести к плачевным последствиям. Однажды “автополив” на esp8266, написанный в ArduinoIDE, “завис” на передаче данных в mqtt, в то время как был включен насос. В итоге насос проработал вместо 15 секунд 2 дня, выкачал 30 литров воды на пол и сгорел. После этого я понял, что дальше так продолжаться не может и нужно что-то менять.

Зачем нужно это удаленное управление?

Во-первых это позволяет минимизировать количество органов управления при создании устройств – в большинстве случаев для автоматизации какого-либо процесса не нужно подключать экран, использовать много кнопок и переключателей для управления. Не нужно создавать встроенные меню для настройки каких-либо параметров. Отображение данных и настройку параметров можно перенести на смартфон или компьютер. Это позволяет использовать в качестве корпуса стандартные различные разветвительные коробки для монтажа электропроводки – это дешево и выглядит достаточно аккуратно. Либо использовать достаточно дешевый стандартные корпуса. Примеры на фотографиях ниже. Конечно, при наличии 3D-принтера можно создать любой корпус, но лично у меня пока такой возможности нет.

Контроллер управления вентиляцией в санузле. Собрано в стандартной коробке для скрытого монтажа

Устройство в стандартной монтажной коробке TDM100x100мм под столешницей стола

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

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

Замена ESP8266 на ESP32

Поначалу я использовал для своих поделок ESP8266, программируя их в уже привычной среде Arduino IDE. Однако достаточно быстро столкнулся с её недостатками. Это небольшое количество выводов для подключения периферии (особенно у платок ESP-01), только один вывод ADC и, увы, нестабильная работа даже на самых простых скетчах (впрочем, возможно, в этом были виноваты достаточно “кривоватые” внешние библиотеки, которые я использовал; либо мои кривые руки).

Потом я увидел и заказал на одной известной китайской торговой площадке отладочные платы с новым (по сравнению с ESP8266, разумеется) контроллером – ESP32 Devkit V4. По стоимости эти платы не намного выше ESP8266, и одно всем известное зеленое земноводное не сильно сопротивлялось при заказе.

Один из вариантов отладочных плат с ESP32. В основном я использую именно эти

Возможности ESP32 по сравнению с ESP8266 гораздо шире:

  • двухядерный процессор и гораздо больше памяти
  • многопоточная операционная система FreeRTOS на борту (даже в Arduino, не удивляйтесь – подробности ниже)
  • достаточно большое количество выводов для подключения датчиков и периферии
  • гораздо большее количество выводов ADC (АЦП – аналого-цифрового-преобразователя). Впрочем, на ESP32 ADC выводы достаточно коряво сделаны и далеко не все их можно использовать, оказывается (этому вопросу я планирую посвятить отдельную статью)
  • две отдельные шины I2C, которые можно использовать одновременно
  • отличная документация на сайте Espressif Systems. Конечно, документация на английском, но Гуголь легко справляется с переводом

В итоге, несколько платок с ESP8266 уже пару лет пылятся в коробочке, а количество заказанных ESP32 и устройств на них исчисляется десятками. В июле было отключено последнее устройство, которое, впрочем более-менее успешно работало несколько лет.

FreeRTOS и нафига она нужна…

Первые опыты с ESP32 я проводил в старой-доброй Arduino IDE. Привычный интерфейс, привычные loop() и setup(). Однако у меня сразу же возник закономерный вопрос – если Arduino это сугубо однопоточная система, а ESP32 имеет сразу два ядра, то как использовать это самое второе ядро?

Изучая примеры для ESP32, легко находится масса примеров программирования ESP32 с использованием операционной системы реального времени FreeRTOS для микроконтроллеров. Хорошо помню, что на тот момент изучать FreeRTOS у меня не было никакого, я сделал очередной проект “по образу и подобию” и закрыл тему.

Но любопытство дало свои результаты. Через какое-то время я обнаружил в файлах платформы Esp32 для Arduino файл-“обертку” для всех скетчей (%profile%\packages\esp32\hardware\esp32\%version%\cores\esp32\main.cpp). Содержимое этого файла таково:

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"

TaskHandle_t loopTaskHandle = NULL;

#if CONFIG_AUTOSTART_ARDUINO

bool loopTaskWDTEnabled;

void loopTask(void *pvParameters)
{
setup();
    for(;;) {
        if(loopTaskWDTEnabled){
            esp_task_wdt_reset();
        }
        loop();
    }
}

extern "C" void app_main()
{
    loopTaskWDTEnabled = false;
    initArduino();
    xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}

#endif

Эта “обертка” используется для всех скетчей, которые Вы создаете в классической Arduino IDE.

Какую информацию отсюда можно почерпнуть? Из содержимого этого файла видно, что FreeRTOS всегда по умолчанию подключается к Вашему скетчу (через #include “freertos/FreeRTOS.h”), а любой классический скетч Arduino IDE (то есть написанный без использования задач) – это всего лишь задача FreeRTOS, которая выполняется на втором ядре процессора #1, и которой выделено всего 8192 байт стека! Сама FreeRTOS при этом выполняется на ядре процессора #0.

Таким образом, получается, что “служебные надобности” ESP32 теперь выполняются на отдельном ядре процессора, не затрагивая вашу программу. Теперь даже если скетч зависнет или уйдет в Sleep на столетие, то это никак не повлияет на работу служебных подпрограмм (но это никак не спасет прикладные задачи).
Но при этом ваш скетч получит только доступ только к ограниченному объему стека, остальная доступная память просто не будет использоваться. 8192 – это далеко не весь стек, что доступен задачам FreeRTOS.

Отсюда вывод: если Вы хотите использовать ESP32 “на всю катушку” придется осваивать FreeRTOS (как основу ESP-IDF). Хотите этого Вы или нет. Иначе это выглядит как “микроскопом гвозди забивать”.

Дальнейшее исследование данного вопроса привело на ресурсы, посвященные ESP-IDF. Оказалось, что ESP-IDF – это основной фреймворк для программирования микроконтроллеров на базе ESP32, разработанный тем же Espressif Systems. Более того, фреймворк Arduino Esp32 использует большинство функций из ESP-IDF и представляет собой попытку “втиснуть” возможности ESP32 в рамки Arduino IDE.

ESP-IDF – основной framework для ESP32

ESP-IDF представляет собой основную среду разработки программного обеспечения для оборудования на основе чипа ESP32 от Espressif. ESP-IDF по сути это портированная на ESP32 версия FreeRTOS.

Возможности многозадачной операционной системы лично меня просто восхищают. Создав несколько задач для разных функций прошивки, можно больше не опасаться, что пауза в одной из задач вызовет завивание всего контроллера. Например отключение WiFi роутера не вызывает катастрофы в сервисах измерения данных с сенсоров и обработки результатов. ESP-IDF уже включает в себя встроенные драйверы, библиотеки и модули почти “на все случаи жизни”: GPIO, UART, Modbus, SPI, SDIO, I2C, I2S, PWM, WIFI, PING, клиент MQTT, HTTP(S) и многое, многое другое. Для основных больше не нужны библиотеки сторонних разработчиков – почти все необходимое уже включено в состав платформы. Всё это достаточно хорошо документировано и описано, есть много примеров.

Но, как всегда, есть “подводные камешки”.

Во-первых, придется отказаться от привычной Arduino IDE, так как возможности установить “чистый” ESP-IDF в Arduino IDE нет. А использовать “урезанный” вариант мне не хотелось. Впрочем, нет худа без добра – я перешел на гораздо более удобную и бесплатную IDE – VS Code (хотя и без недостатков).

Во-вторых: в ESP-IDF отсутствуют как класс драйвера для всевозможных датчиков и экранов (например DHT22, LCD1602 и т.д.). Производители плат создают драйвера для ArduinoIDE, так как она очень популярна; а вот для ESP-IDF драйвер придется написать самому, копаясь в даташитах. Впрочем, сейчас довольно много готовых драйверов можно найти на GitHub. В частности, вы можете бесплатно использовать и мои драйвера.

Visual Studio Code + PlatformIO

Как я уже писал выше, чтобы начать “кодить” с использованием ESP-IDF, необходимо использовать другую IDE. Существует несколько вариантов, но самыми популярными вариантом является бесплатный Visual Studio Code. Но собственно VSCode это просто универсальный редактор для любых языков программирования, чтобы иметь возможность писать программы для ESP32, ESP8266 и других микроконтроллеров, необходимо установить специальное расширение – plugin. Существует как минимум два plugin-а, позволяющих работать с ESP-IDF – “родной” plugin от Espressif (который позволяет работать только с ESP-IDF, собственно) и популярный проект PlatfotmIO (который позволит вам работать с множеством самых разных микроконтроллеров). На PlatformIO, собственно, я и остановился. Более подробно процесс установки VSCode и PlatformIO в другой статье.

Вместо заключения

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

PS: Я не профессиональный программист встраиваемых систем (хотя профессиональный программист учетных программ и баз данных), и я не освоил и четверти всех возможностей, которые предоставляет ESP32 и ESP-IDF. Просто потому, что мне пока не нужно было использовать некоторые возможности. Предлагаю вам осваивать этот микроконтроллер и его среду программирования вместе.

Подписывайтесь, будет интересно… 👍

Полезные ссылки:

  1. Официальная документация по ESP-IDF (на английском)
  2. Андрей Курниц “FreeRTOS — операционная система для микроконтроллеров”
  3. FreeRTOS — практическое применение
  4. Справочник по Free RTOS API
  5. Канал на Дзене
  6. Мои репозитории

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

Ваш адрес email не будет опубликован.