Публикация показаний DS18B20 в Node-Red с помощью ESP32, MQTT и ESP-IDF


В этом проекте мы научимся публиковать показания датчика DS18B20 в Node-Red с помощью ESP32 и MQTT, используя ESP-IDF. Мы будем осуществлять MQTT-связь между ESP32 и Node-Red, а также публиковать и подписываться на темы MQTT. Плата разработки ESP32 будет выступать в роли издателя MQTT, а Node-Red — в роли подписчика. Используя протокол MQTT, ESP32 будет публиковать показания датчика DS18B20 на панели управления Node-Red, которая будет подписываться на соответствующие темы MQTT. Данные датчика, включающие показания температуры в градусах Цельсия и Фаренгейта, будут интерактивно отображаться на панели управления Node-Red.

Мы будем использовать MQTT-брокер Mosquitto на Raspberry Pi, но вы также можете установить его на свои компьютеры с Windows и Linux, если вы их используете. Издатель и подписчик установят соединения с MQTT-брокером, установленным на Raspberry Pi. После этого ESP32 будет публиковать данные с датчиков на панель управления Node-Red по указанным темам.

Чтобы лучше понять материал данной статьи рекомендуем прочитать предыдущие статьи по этой тематике:

MQTT-клиент в ESP32 с помощью ESP-IDF: публикация показаний датчика DS18B20 в Node-Red

Наша цель — создать проект, использующий протокол MQTT на ESP32 с помощью ESP-IDF для публикации показаний датчика DS18B20 в Node-Red. Рассмотрим этапы, необходимые для реализации этого проекта.

  1. Плата ESP32 подключена к датчику DS18B20, используемому для измерения температуры окружающей среды. Эта плата ESP32 будет подключаться к MQTT-брокеру. В нашем случае мы будем использовать брокер Mosquitto на Raspberry Pi. Если вы хотите узнать, как успешно установить брокер на ваш Raspberry Pi, вы можете обратиться к следующему руководству: установка Mosquitto MQTT брокера на Raspberry Pi.
  2. После получения данных с датчика DS18B20 плата ESP32 публикует эти показания в отдельных темах MQTT: esp32/ds18b20/temperatureC предназначена для публикации показаний температуры DS18B20 в градусах Цельсия, а esp32/ds18b20/temperatureF — для публикации показаний температуры DS18B20 в градусах Фаренгейта.
  3. Node-Red будет подписан на эти две темы. Таким образом, он сможет получать показания датчиков и интерактивно отображать их на своей панели управления с помощью индикаторов.

Публикация показаний DS18B20 в Node-Red с помощью ESP32, MQTT и ESP-IDF

Подключение DS18B20 к ESP32

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

Для подключения платы ESP32 к датчику DS18B20 нам понадобятся следующие компоненты:

  1. Плата ESP32.
  2. Датчик DS18B20.
  3. Подтягивающий резистор 4,7 кОм.
  4. Соединительные провода.
  5. Макетная плата.

Датчик DS18B20 может включаться в двух режимах: обычном и паразитном. В обычном режиме датчик питается от внешнего источника через вывод VCC и резистор 4,7 кОм. Однако в паразитном режиме датчик питается от линии данных, поэтому внешний источник питания не требуется. Мы будем питать наш датчик DS18B20 в обычном режиме.

В таблице ниже показано подключение трех контактов датчика DS18B20 к плате ESP32.

DS18B20 ESP32
VCC 3.3V / Vin
Data GPIO4
GND GND

Подключите вывод VCC датчика к выводу 3,3 В или Vin платы ESP32 и соедините заземление обоих устройств. Кроме того, подключите вывод данных датчика к соответствующему выводу GPIO платы ESP32, который можно настроить как выходной вывод. Обратите внимание, что выводы GPIO34-39 являются только входными и не могут использоваться для управления однопроводной шиной. Мы используем GPIO4 для подключения к выводу данных через подтягивающий резистор 4,7 кОм. Один конец резистора будет подключен к выходу данных, а другой — к источнику питания.

Обратите внимание, что если вы используете модуль DS18B20, то вам не нужно добавлять внешний подтягивающий резистор. Это связано с тем, что модуль уже оснащен датчиком и встроенным подтягивающим резистором.

Следуйте приведенной ниже принципиальной схеме, чтобы соединить два устройства.

Схема подключения датчика DS18B20 к плате ESP32

Публикация показаний DS18B20 в Node-Red по MQTT с использованием ESP32 и ESP-IDF

Мы создадим проект в VS Code с расширением ESP-IDF. Код будет считывать показания температуры с помощью библиотеки DS18B20, а затем использовать библиотеку mqtt_client для подключения ESP32 к MQTT-брокеру и публикации показаний в различных темах. Мы будем использовать простую библиотеку DS18B20 для одного датчика DS18B20 с ESP32. Она предоставлена ​​feelfreelinux  на GitHub.

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

Откройте 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.

  • Для начала добавим необходимые заголовочные файлы для библиотек, требуемых для этого проекта. Создайте новую папку с названием «components» и добавьте в неё следующие файлы:

Необходимые для нашего проекта заголовочные файлы для библиотек

CMakeLists.txt

ds18b20.h

ds18b20.c

  • Теперь перейдите к файлу main.c. В папке main находится исходный код, то есть файл main.c будет находиться здесь. Перейдите в папку main > main.c и откройте его. Скопируйте приведенный ниже код из этого файла и сохраните его.

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

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

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

Переменная 'DS_PIN' содержит номер однопроводного GPIO, который будет использоваться для подключения к выводу данных датчика. Мы используем GPIO4.

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

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

Мы определим несколько переменных для мониторинга Wi-Fi-соединения, включая максимальное значение количества повторных попыток, установленное на 10, и количество повторных попыток, которое изначально имеет значение 0.

После этого мы определяем темы, в которые будет публиковать данные плата ESP32. К ним относятся: esp32/ds18b20/temperatureC для показаний температуры в градусах Цельсия и esp32/ds18b20/temperatureF для показаний температуры в градусах Фаренгейта.

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

У нас есть функция wifi_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-адрес или станция отключается от точки доступа соответственно.

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

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

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

Для начала мы создаём цикл событий по умолчанию, вызвав функцию esp_event_loop_create_default(). Затем мы используем функцию esp_event_handler_register() для регистрации обработчиков событий в системном цикле событий для событий WIFI_EVENT и IP_EVENT.

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

Здесь мы инициализируем 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().

Кроме того, мы устанавливаем режим 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_ERROR. Если да, то на ESP-IDF будет выведено соответствующее сообщение в зависимости от типа события, и будет вызвана соответствующая функция.

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

MQTT_EVENT_CONNECTED Это событие отправляется, когда клиент успешно подключается к брокеру и готов отправлять/получать данные.
MQTT_EVENT_DISCONNECTED Это событие регистрируется, когда клиент разрывает соединение с брокером из-за недоступности сервера. В этом случае клиент не может отправлять/получать данные.
MQTT_EVENT_ERROR Это событие отправляется клиентом при возникновении ошибки.

Если клиент отправляет событие MQTT_EVENT_CONNECTED, переменная «MQTT_CONNECTED» устанавливается в значение 1, тогда как изначально она имела значение 0.

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

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()

Внутри функции Publisher_Task() инициализируется датчик DS18B20 и происходит сбор данных с него. Затем эти данные публикуются в соответствующие темы каждую секунду с использованием протокола MQTT.

Сначала мы инициализируем датчик DS18B20 с помощью функции ds18b20_init() и передаем в качестве параметра контакт GPIO с одним проводом.

Внутри бесконечного цикла while мы начнем получать показания датчика DS18B20, сначала запросив температуру с помощью функции ds18b20_requestTemperatures(). Затем мы получим показания температуры в градусах Цельсия с помощью функции ds18b20_get_temp(). Эта функция возвращает показания температуры в виде числа с плавающей запятой. Сначала мы преобразуем число с плавающей запятой в массив символов и округлим до двух десятичных знаков. Аналогично, мы преобразуем показания температуры в градусах Цельсия в градусы Фаренгейта, умножив их на 9/5 и прибавив 32. Оба показания считываются непрерывно с задержкой в ​​одну секунду и выводятся на терминал ESP-IDF.

Если MQTT_CONNECTED имеет значение true, то показания датчиков будут публиковаться в соответствующие темы каждую секунду.

app_main()

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

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

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

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

Тестирование работы проекта в окне терминала

Теперь давайте настроим панель мониторинга Node-Red для просмотра данных с датчиков.

Панель мониторинга Node-Red в качестве подписчика показаний MQTT DS18B20

Наш ESP32 Publisher отправляет показания отдельных датчиков DS18B20 в определенные темы каждую секунду. В этом разделе мы покажем, как настроить Node-Red в качестве MQTT-подписчика для тем, связанных с датчиком DS18B20 на нашем ESP32. Используя панель управления Node-Red, мы сможем просматривать показания датчиков на нашем смартфоне/ноутбуке/компьютере. Давайте сначала разберемся, как создать панель управления.

Для подписки на темы MQTT можно использовать любой другой сервис подписки MQTT, например, MQTTx Desktop Client, который мы использовали ранее.

Для доступа к Node-RED нам потребуется IP-адрес вашего Raspberry Pi и номер порта, на котором доступен Node-RED. По умолчанию он запускается на порту 1880. Откройте любой веб-браузер и введите IP-адрес вашего Raspberry Pi, а затем номер порта.

Например:

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

Это откроет интерфейс Node-RED. Теперь начнём создавать поток.

Создание потока в Node-RED

Перейдите в правую часть экрана и найдите раздел dashboard («Панель управления»). Установите панель управления, если она еще не установлена.

Переход на панель управления в Node-RED

Нажмите ‘Dashboard’ («Панель управления»), чтобы открыть вкладку. Теперь создадим узел вкладки панели управления. Чтобы создать новую вкладку, перейдите на вкладку «Панель управления» и нажмите кнопку «+вкладка». Присвойте ей имя по своему усмотрению и выберите значок из списка ссылок ниже:

После этого нажмите Update («Обновить»), чтобы сохранить изменения.

Мы создали вкладку под названием Home («Главная») и используем иконки из Angular Material Icons.

Создание вкладки под названием Home

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

Мы назвали эту группу «DS18B20 Readings».

Создание группы «DS18B20 Readings»

Теперь добавим виджеты в нашу группу. Для отображения показаний температуры выберем датчики. Перейдите в раздел Nodes («Узлы»), расположенный в левом углу, и прокрутите вниз, чтобы найти необходимые узлы в разделе Dashboard («Панель управления»).

Перетащите два индикатора и два узла MQTT в поток, как показано ниже:

Перетаскивание двух индикаторов и двух узлов MQTT в поток

Теперь давайте отредактируем свойства узлов. Щёлкните по первому узлу mqtt. Откроются его свойства. Для сервера (брокера MQTT), которым является Mosquitto Broker на Raspberry Pi, установите значение localhost:1883. Добавьте имя темы, на которую нужно подписаться, укажите QoS и затем нажмите кнопку Done («Готово»).

Данный узел подписан на тему 'esp32/ds18b20/temperatureC'.

Настройки узла подписанного на тему 'esp32/ds18b20/temperatureC'

Аналогичным образом отредактируйте свойства второго MQTT-соединения в узле. Этот конкретный узел подписан на тему 'esp32/ds18b20/temperatureF'.

Настройки узла подписанного на тему 'esp32/ds18b20/temperatureF'

Отредактируйте свойства первого и второго индикаторов, как показано ниже:

Редактирование свойств первого и второго индикаторов

Редактирование свойств второго индикатора

Соедините узлы, как показано ниже. Затем нажмите кнопку Deploy («Развернуть») вверху.

Развертывание проекта

Статус MQTT-соединения в узлах меняется на ‘connected’ («подключено»).

Изменение статуса MQTT-соединений в узлах на ‘connected’

Чтобы открыть панель управления, введите в новом окне веб-браузера: http://Your_RPI_IP_address:1880/ui и нажмите Enter. Откроется пользовательский интерфейс, отображающий два индикатора с показаниями датчика DS18B20.

Пользовательский интерфейс нашего проекта

Так выглядит панель управления Node-Red при просмотре на смартфоне.

Панель управления Node-Red нашего проекта при просмотре на смартфоне

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

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

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