В этом вводном руководстве по ESP32 с использованием ESP-IDF мы познакомим вас с некоторыми основными понятиями программирования ESP32 с помощью ESP-IDF в VS Code. Будут рассмотрены примеры логирования, генерации задержек, ввода с клавиатуры и мигания встроенного светодиода ESP32.
Прежде чем продолжить, убедитесь, что у вас установлена последняя версия VS Code и настроено расширение ESP-IDF:
- Установка ESP32 ESP-IDF на Windows и его интеграция с Visual Studio Code
- Установка ESP32 ESP-IDF на Linux Ubuntu
В двух предыдущих уроках мы рассмотрели, как установить, скомпилировать, собрать и прошить код в ESP32 с помощью esp-idf. В этом уроке мы рассмотрим несколько примеров для начала работы, таких как логирование, включение отладочной информации и простая программа мигания светодиода.
Также про начало работы с ESP32 с использованием ESP-IDF вы можете прочитать в следующей статье на нашем сайте — эти две статьи как бы дополняют друга, какие то моменты лучше освещены в одной статье, другие моменты — в другой статье.
Вход в систему ESP-IDF
ESP-IDF обладает некоторыми возможностями логирования, которые мы рассмотрим в первую очередь, поскольку они чрезвычайно полезны и используются довольно часто. Сначала мы включим файл «esp_log.h» в наши скрипты.
|
1 |
#include "esp_log.h" |
Вместо простого вывода сообщения с помощью команды printf, мы можем использовать различные типы логов. Библиотека логирования ESP-IDF поддерживает следующие пять уровней логирования:
- ESP_LOGE: Ведение журнала ошибок (самый низкий уровень)
- ESP_LOGW: Ведение журнала предупреждений
- ESP_LOGI: Информационный журнал
- ESP_LOGD: Отладочная инструкция
- ESP_LOGV: Подробный (самый высокий уровень)
Для регистрации ошибки мы будем использовать следующую функцию:
|
1 |
ESP_LOGE(tag, format, __VA_ARGS__) |
Примечание: в функции ESP_LOGE() буква ‘E’ означает ошибку.
Функция логирования принимает два аргумента. Первый аргумент — это тег, а второй — отформатированная строка. Если вы зададите разные теги в разных участках кода, это упростит мониторинг этих частей кода.
В нашем скрипте мы укажем в качестве первого параметра ‘LOG’, который является тегом, а в качестве второго аргумента — отформатированную строку ‘This is an error’. Таким образом, наша функция регистрации ошибок будет выглядеть примерно так:
|
1 |
ESP_LOGE(LOG, "This is an error"); |
Аналогичным образом мы определим разделы журналов для предупреждений, информационных сообщений, отладочной информации и подробного вывода соответственно.
|
1 2 3 4 |
ESP_LOGW(LOG, "This is a warning"); ESP_LOGI(LOG, "This is an info"); ESP_LOGD(LOG, "This is a debug"); ESP_LOGV(LOG, "This is a verbose"); |
Тестирование скрипта для ведения логов.
Вот как выглядит наш скрипт на данный момент:
Теперь давайте скомпилируем этот код. Откройте последовательный терминал, введите следующую команду и нажмите Enter:
|
1 |
idf.py flash monitor |
Вот как выглядит результат после успешной прошивки микросхемы:
Давайте разберемся, что означает этот вывод. Слева направо: E означает ошибку, W — предупреждение, а I — информацию. Числа в скобках указывают время в миллисекундах после запуска приложения и вызова данной функции.
Обратите внимание, что журналы ошибок, предупреждений и информации отображаются, но отладочные сообщения и подробный вывод отсутствуют. По умолчанию они отключены. Нам придется изменить настройки самостоятельно.
Включите режимы отладки и подробного вывода с помощью Menuconfig
Мы будем использовать menuconfig для включения отладочных и подробных настроек. Откройте командную строку ESP-IDF 4.3 и дождитесь загрузки переменных окружения. Теперь укажите путь к текущему корневому каталогу, как показано ниже, а затем откройте menuconfig с помощью команды idf.py menuconfig.
Эта команда открывает конфигурацию среды разработки Espressif IoT. Перейдите в раздел ‘Component config’ («Конфигурация компонентов»).
Далее перейдите в раздел ‘Log output’ («Вывод в журнал»).
Затем перейдите к разделу ‘Default log verbosity (Info)’ («Уровень детализации журнала по умолчанию (Информация)»).
Теперь выберите ‘Verbose’. Здесь мы выбираем минимальный уровень детализации. Это означает, что мы будем получать сообщения в режиме подробного вывода и сообщения более высокого уровня (ошибки, предупреждения, информация, отладка). Однако, если бы мы выбрали ‘debug’ («Отладка»), то вывод отображал бы сообщения до уровня отладки, а подробный вывод отсутствовал бы. По сути, минимальный уровень устанавливается в следующем порядке:
Нажмите ‘Q’ для выхода и сохраните настройки, нажав ‘Y’.
Включите режимы отладки и подробного вывода в коде
Мы также можем включить отладку и подробный вывод в скрипте программы. Добавьте следующую строку кода для установки конфигурации с помощью функции esp_log_level_set(). Она принимает два аргумента. Первый аргумент — это тег, а второй — фактический уровень, который мы хотим установить в качестве минимального уровня.
В нашем скрипте мы укажем в качестве первого параметра ‘LOG’, который является тегом, а в качестве второго аргумента — ‘ESP_LOG_INFO’, уровень логирования. Мы устанавливаем для тега ‘LOG’ уровень info. Таким образом, уровень логирования для тега LOG будет выглядеть примерно так:
|
1 |
esp_log_level_set("LOG", ESP_LOG_INFO); |
Кроме того, мы добавим дополнительный набор уровней логирования с другим тегом. В первом наборе мы использовали тег ‘LOG’. Во втором наборе мы установим тег ‘TAG’.
Вот как сейчас выглядит наш скрипт:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
include <stdio.h> #include "esp_log.h" void app_main(void) { esp_log_level_set("LOG", ESP_LOG_INFO); ESP_LOGE("LOG", "This is an error); ESP_LOGW("LOG", "This is a warning); ESP_LOGI("LOG", "This is an info); ESP_LOGD("LOG", "This is a debug); ESP_LOGV("LOG", "This is a verbose); ESP_LOGE("TAG", "This is an error); ESP_LOGW("TAG", "This is a warning); ESP_LOGI("TAG", "This is an info); ESP_LOGD("TAG", "This is a debug); ESP_LOGV("TAG", "This is a verbose); } |
Теперь запустите программу.
Вот как теперь выглядит вывод. Те сообщения с тегом ‘LOG’ выводились до уровня info. Это потому, что мы установили для тега ‘LOG’ уровень info. Однако сообщения с тегом ‘TAG’ выводились до уровня verbose, потому что именно это мы задали в menuconfig.
Генерация задержек с помощью ESP-IDF на ESP32
Ещё одна важная концепция, которая часто используется, — это включение задержек в наши программные скрипты.
Для генерации задержек мы будем использовать FreeRTOS (на нашем сайте вы также можете более подробно прочитать про использование FreeRTOS в ESP32 с помощью ESP-IDF). Поэтому сначала мы включим необходимые для неё библиотеки в наш программный скетч.
|
1 2 |
#include "freertos/FreeRTOS.h" #include "freertos/task.h" |
Внутри функции цикла мы добавим задержку. Для генерации задержки мы будем использовать функцию «vTaskDelay». Она принимает в качестве первого параметра целое число (uint32), которое является константой TickType, определяющей количество тактов, которые нужно задержать. Это число соответствует такту, то есть частоте микросхемы.
|
1 |
vTaskDelay(1000); |
Чтобы перевести тактовые секунды в миллисекунды, мы разделим их на portTICK_PERIOD_MS. Параметр portTICK_PERIOD_MS является частью директивы #defines. Он настраивается при компиляции скетча и по умолчанию устанавливается равным скорости работы микросхемы. Таким образом, 1000, разделенное на количество тактов, в течение которых работает микросхема, даст нам миллисекунды.
|
1 |
vTaskDelay(1000 /portTICK_PERIOD_MS); |
Пример скетча
Давайте запустим следующий скетч, чтобы увидеть, как генерируется задержка. В этом скетче мы определили TAG как ‘DELAY’. Это будет заменено внутри функции ESP_LOGI() на первый параметр. В качестве второго параметра мы будем увеличивать значение целочисленной переменной ‘i’, которая изначально имеет значение 0. Будет сгенерирована задержка, после которой будет выведена информация в лог.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <stdio.h> #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #define TAG "DELAY" void app_main(void) { int i = 0; while(1) { vTaskDelay(1000 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "in loop %d", i++); } } |
Теперь прошейте микросхему, введя в терминале следующую команду:
Вот как выглядит вывод. Каждую секунду печатается новое число.
Пример мигания светодиода на ESP32 ESP-IDF
Теперь перейдём к одному из самых распространённых первых примеров, который выполняется с использованием ESP32. Мы покажем, как заставить мигать встроенный светодиод ESP32 с помощью ESP-IDF в VS Code.
Для начала создайте новый проект ESP-IDF и перейдите к файлу main.c.
статья в разработке
