Работа с клиентом MQTT в ESP32 с использованием ESP-IDF


В этом уроке мы научимся использовать ESP32 в качестве MQTT-клиента, используя библиотеку mqtt_client из ESP-IDF. Мы научимся публиковать и подписываться на MQTT-темы с помощью ESP32. Сначала мы рассмотрим, как установить соединение ESP32 с MQTT-брокером Mosquitto в качестве клиента. Затем мы научимся использовать библиотеку mqtt_client, доступную в ESP-IDF, для подключения ESP32 к MQTT-брокеру, подписки на различные темы, а также для публикации сообщений в различных темах. Для демонстрации мы будем использовать настольное приложение MQTTx client. Мы будем подписываться на MQTT-темы и публиковать сообщения с помощью MQTTx. Мы установим MQTT-брокер Mosquitto на Raspberry Pi, но вы также можете установить его на свой компьютер с Windows и Linux.

Работа с клиентом MQTT в ESP32 с использованием ESP-IDF

Также на нашем сайте вы можете посмотреть и другие статьи, связанные с использованием MQTT:

Публикация и подписка по протоколу MQTT на ESP32 с помощью ESP-IDF

Давайте создадим пример проекта в ESP-IDF и запрограммируем нашу плату ESP32 с помощью скетча MQTT. Мы также обсудим API из файла mqtt_client.h, которые потребуются для этого проекта.

Создание примера проекта

Откройте VS Code и перейдите в меню View > Command Palette («Вид» > «Палитра команд»). Введите   в строке поиска ESP-IDF: New Project и нажмите Enter.

Укажите название проекта и каталог, а также плату и целевое устройство ESP-IDF. Для платы ESP-IDF мы выбрали опцию custom board ("пользовательская плата"). Для целевого устройства ESP-IDF мы выбрали модуль ESP32. Нажмите кнопку ‘Choose Template’ ("Выбрать шаблон"), чтобы продолжить.

В разделе «Расширение» выберите опцию ESP-IDF:

Выбор опции ESP-IDF в разделе Extension («Расширение»)

На вкладке get-started («Начало работы») мы щелкнем по пункту «sample_project». Затем нажмем ‘Create project using template sample_project’) («Создать проект, используя шаблон sample_project»).

Создание проекта с использованием шаблона sample_project

Вы получите уведомление о создании проекта. Чтобы открыть проект в новом окне, нажмите «Да».

Это открывает наш проект, который мы создали во вкладке «Проводник». Внутри папки проекта находится несколько папок. Это справедливо для каждого проекта, который вы будете создавать с помощью ESP-IDF Explorer.

Код ESP32 для работы с MQTT

В папке main  находится исходный код, то есть файл main.c будет расположен именно здесь. Перейдите в папку main > main.c  и откройте его. Скопируйте приведенный ниже код и сохраните его. Следующий код использует обработчики событий для проверки различных событий Wi-Fi и MQTT, подключения ESP32 к локальной сети Wi-Fi и брокеру MQTT, подписки на две темы (/topic/test1, /topic/test2) и публикации в тему (/topic/test3) каждые несколько секунд.

Данный код вы также можете скачать с Github.

Как работает код?

Для начала мы подключим необходимые библиотеки, включая библиотеки FreeRTOS для генерации задержек, esp_wifi.h для включения Wi-Fi-соединения, esp_event.h для мониторинга событий Wi-Fi и MQTT, mqtt_client.h для настройки протокола MQTT для публикации/подписки и esp_log.h в качестве библиотеки для ведения журналов.

Этот код использует информационное логирование. Функция логирования принимает два аргумента. Первый аргумент — это тег, а второй — отформатированная строка. Поэтому эта глобальная переменная будет полезна при вызове функций ESP_LOGI(). Здесь «MQTT_EXAMPLE» — это тег, который будет использоваться при логировании.

Далее мы определили параметры для SSID и пароля Wi-Fi. Укажите свои собственные учетные данные сети, чтобы успешно подключить плату ESP32 к сети Wi-Fi.

Обработка событий Wi-Fi

У нас есть функция event_handler(), которая обрабатывает события Wi-Fi. Она действует как функция обратного вызова при возникновении любого события Wi-Fi. Драйвер Wi-Fi отправляет в задачу обработки событий различные события, в том числе: SYSTEM_EVENT_STA_START, SYSTEM_EVENT_STA_CONNECTED, SYSTEM_EVENT_STA_GOT_IP и SYSTEM_EVENT_STA_DISCONNECTED. Эти события происходят, если Wi-Fi подключен, станция подключается к точке доступа, Wi-Fi получает IP-адрес или станция отключается от точки доступа соответственно.

В нашей функции event_handler() мы проверим, соответствует ли идентификатор события Wi-Fi одному из этих четырех событий. Если да, то на ESP-IDF будет выведено соответствующее сообщение в соответствии с типом события, и будет вызвана соответствующая функция. Если произойдет событие SYSTEM_EVENT_STA_START или SYSTEM_EVENT_STA_DISCONNECTED, будет вызвана функция esp_wifi_connect(). Она будет отвечать за подключение станции Wi-Fi ESP32 к точке доступа. Если произойдет событие SYSTEM_EVENT_STA_GOT_IP, то будет вызвана функция mqtt_app_start() для инициирования подключения MQTT-клиента.

Инициализация Wi-Fi

Функция wifi_init() будет вызываться внутри функции app_main() для инициализации Wi-Fi в режиме станции для ESP32.

ESP-IDF предоставляет полезный макрос ESP_ERROR_CHECK(), который используется для проверки наличия или отсутствия ошибки. Если функция, переданная в него, не возвращает ESP_OK, то мы проверяем наличие ошибки и записываем её в лог.

Здесь мы инициализируем lwIP с помощью функции esp_netif_init() и создаём задачу IwIP, также известную как задача TCP/IP. lwIP — это стек библиотек TCP/IP, предоставляемый ESP-IDF, который используется для выполнения различных протоколов, таких как TCP, UDP, DHCP и т. д.

Далее мы создаём цикл обработки событий по умолчанию, который позволяет отправлять системные события в задачу обработки событий.

Кроме того, следующая строка используется для инициализации Wi-Fi по умолчанию в режиме станции. Этот API используется для инициализации, а также регистрации обработчиков событий для интерфейса по умолчанию, которым в нашем случае является станция. Он создает экземпляр сетевого интерфейса, связывающий драйвер Wi-Fi и стек TCP/IP. Когда станция находится в процессе подключения к точке доступа, различные процессы автоматически обрабатываются с помощью этой функции.

Затем мы инициализируем ресурс выделения Wi-Fi для драйвера Wi-Fi. Он отвечает за запуск задачи Wi-Fi. Он принимает единственный параметр cfg, который является указателем на уже инициализированную структуру конфигурации Wi-Fi, установленную в значение WIFI_INIT_CONFIG_DEFAULT(), так что инициализация конфигурации происходит со значениями по умолчанию. Здесь wifi_init_config_t — это структура, обозначающая параметры конфигурации стека Wi-Fi, которые передаются в функцию esp_wifi_init().

Затем вызывается функция esp_event_loop_init(), которая инициализирует цикл событий, используемый для отправки обратных вызовов событий, связанных с Wi-Fi, IP и Ethernet.

В этой части мы задаём SSID и пароль сети, к которой хотим подключить наш ESP32, а также назначаем параметры безопасности.

Кроме того, мы устанавливаем режим Wi-Fi как «станция». Для этого мы используем функцию esp_wifi_set_mode() и передаем в качестве параметра параметр WiFI_MODE_STA.

Затем мы назначаем SSID и пароль нашей сети. Таким образом, драйвер Wi-Fi настраивается с использованием учетных данных сети точки доступа и режима Wi-Fi. После этого мы запускаем Wi-Fi-соединение с заданными параметрами.

Обработка событий MQTT

Далее у нас есть функция mqtt_event_handler(), которая обрабатывает события MQTT. Эта функция вызывается циклом обработки событий MQTT-клиента. Мы проверим, соответствует ли идентификатор события одному из семи возможных событий: MQTT_EVENT_CONNECTED, MQTT_EVENT_DISCONNECTED, MQTT_EVENT_SUBSCRIBED, MQTT_EVENT_UNSUBSCRIBED, MQTT_EVENT_PUBLISHED, MQTT_EVENT_DATA или MQTT_EVENT_ERROR. Если да, то на ESP-IDF будет выведено соответствующее сообщение в зависимости от типа события, и будет вызвана соответствующая функция.

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

MQTT_EVENT_CONNECTED Это событие отправляется, когда клиент успешно подключается к брокеру и готов отправлять/получать данные.
MQTT_EVENT_DISCONNECTED Это событие регистрируется, когда клиент разрывает соединение с брокером из-за недоступности сервера. В этом случае клиент не может отправлять/получать данные.
MQTT_EVENT_SUBSCRIBED Это событие регистрируется, когда брокер принимает запрос на подписку от клиента. Данные события также содержат идентификатор сообщения подписки.
MQTT_EVENT_UNSUBSCRIBED В этом случае брокер принимает запрос клиента на отписку. Данные события содержат идентификатор сообщения об отписке.
MQTT_EVENT_PUBLISHED Это событие отправляется, когда брокер подтверждает получение клиентом опубликованного сообщения. Данные события содержат идентификатор опубликованного сообщения.
Обратите внимание, что если уровень QoS установлен на 0, то это событие не будет отправлено, поскольку подтверждения не используются. Оно будет отправлено только для уровней QoS 1 или 2.
MQTT_EVENT_DATA Это событие отправляется, когда клиент получает сообщение о публикации. В этом случае данные события содержат идентификатор сообщения, имя темы, в которую оно было опубликовано, полученные данные и длину данных.
MQTT_EVENT_ERROR Это событие отправляется клиентом при возникновении ошибки.

Если клиент отправляет событие MQTT_EVENT_CONNECTED, переменная «MQTT_CONNECTED» устанавливается в значение 1, тогда как изначально она имела значение 0. После этого вызывается функция esp_mqtt_client_subscribe() для подписки клиента на заданную тему с заданным QoS. Эта функция принимает три параметра: дескриптор MQTT-клиента, тему и значение QoS. В случае успеха она возвращает message_id, который сохраняется в переменной 'msg_id'.

В нашем случае мы придерживаемся двух тем:

  • /topic/topic1 с qos 0
  • /topic/topic2 с QoS 1

Терминал ESP-IDF выводит идентификатор сообщения вместе с сообщением об успешной отправке подписки.

Если клиент отправляет событие MQTT_EVENT_DISCONNECTED, переменная MQTT_CONNECTED устанавливается в значение 0, и терминал выводит сообщение о том, что это событие произошло. Аналогично, для остальных событий на терминал выводится соответствующее сообщение вместе с message_id. Для события MQTT_EVENT_DATA также выводится имя темы вместе с данными.

mqtt_app_start()

Внутри функции mqtt_app_start() создается дескриптор MQTT-клиента в соответствии с параметрами конфигурации, заданными с помощью функции esp_mqtt_client_init(). Эта функция принимает один параметр — указатель на структуру конфигурации MQTT. Структура конфигурации MQTT содержит IP-адрес MQTT-брокера, который выступает в качестве MQTT-сервера. Убедитесь, что вы указали IP-адрес вашего Raspberry Pi, на котором запущен брокер Mosquitto, в структуре конфигурации MQTT.

После этого мы вызовем функцию esp_mqtt_client_register_event(), которая используется для регистрации события MQTT. Она принимает четыре параметра. Первый параметр — это дескриптор MQTT-клиента. Второй параметр — это тип события. Третий параметр — это функция обратного вызова обработчика, а последний параметр — это контекст дескриптора, который в нашем случае равен mqtt_client_handle, 'client'. Наконец, мы запустим MQTT-клиент с помощью функции esp_mqtt_client_start() и укажем уже созданный дескриптор клиента в качестве параметра внутри неё.

Внутри функции Publisher_Task(), если отправляется событие MQTT_CONNECTED, клиент публикует сообщение «Hello World» брокеру каждые 15 секунд. Функция esp_mqtt_client_publish() отвечает за публикацию сообщения. Она принимает шесть параметров, включая дескриптор MQTT-клиента, строку темы, данные для публикации, длину данных, QoS и флаг сохранения.

app_main()

Внутри функции app_main() сначала инициализируется NVS путем вызова функции nvs_flash_init(). Затем проверяется, не содержит ли раздел NVS пустых страниц или содержит ли он данные в формате, отличном от текущей версии кода. Если выполняется хотя бы одно из этих условий, то стирается флэш-память NVS с помощью nvs_flash_erase() и инициализируется заново. Затем вызывается функция wifi_init(), которая инициализирует Wi-Fi в режиме станции для ESP32. После этого используется xTaskCreate() для создания задачи Publisher_Task, которая будет публиковать сообщение Hello World брокеру каждые 15 секунд.

Компиляция скетча

Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.

После успешной прошивки кода на терминале ESP-IDF можно будет увидеть различные сообщения. Сначала успешно установится соединение с Wi-Fi.

Публикация и подписка с использованием MQTT X Client

Для тестирования мы будем использовать клиентский инструмент MQTT 5.0 – MQTT X. Чтобы скачать это приложение, перейдите по ссылке:  https://mqttx.app/

После завершения установки откройте приложение MQTT X. Нажмите кнопку ‘+ New Connection’ («+ Новое соединение»).

Создание нового соединения в приложении MQTT X

 

 

 

 

статья в разработке

(Проголосуй первым!)
Загрузка...
1 просмотров

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

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