ESP32 MQTT — Публикация показаний датчика BME280 (Arduino IDE)
Узнайте, как публиковать показания датчика BME280 (температура, влажность и давление) через MQTT с ESP32 на любую платформу, поддерживающую MQTT, или в любой MQTT-клиент. В качестве примера мы будем публиковать показания датчика в Node-RED Dashboard, а ESP32 будет запрограммирован с использованием Arduino IDE.
Рекомендуемое чтение: Что такое MQTT и как он работает
Обзор проекта
На следующей диаграмме показан общий обзор проекта, который мы создадим.
ESP32 запрашивает показания температуры у датчика BME280.
Показания температуры публикуются в топике esp32/bme280/temperature;
Показания влажности публикуются в топике esp32/bme280/humidity;
Показания давления публикуются в топике esp32/bme280/pressure;
Node-RED подписан на эти топики;
Node-RED получает показания датчика и отображает их на приборных панелях (gauges);
Вы можете получать показания на любой другой платформе, поддерживающей MQTT, и обрабатывать их как угодно.
Предварительные требования
Перед тем как приступить к этому руководству, убедитесь, что выполнены следующие предварительные требования.
Arduino IDE
Мы будем программировать ESP32 с использованием Arduino IDE, поэтому убедитесь, что у вас установлено дополнение ESP32.
MQTT Брокер
Для использования MQTT вам нужен брокер. Мы будем использовать брокер Mosquitto, установленный на Raspberry Pi. Прочитайте Как установить Mosquitto Broker на Raspberry Pi.
Вы можете использовать любой другой MQTT-брокер, включая облачный MQTT-брокер. Мы покажем, как это сделать в коде далее.
Если вы не знакомы с MQTT, обязательно прочитайте наше вводное руководство: Что такое MQTT и как он работает.
Библиотеки MQTT
Для использования MQTT с ESP32 мы будем использовать библиотеку Async MQTT Client.
Установка библиотеки Async MQTT Client
Нажмите здесь, чтобы скачать библиотеку Async MQTT client. У вас должен появиться .zip файл в папке загрузок
Распакуйте .zip файл, и вы получите папку async-mqtt-client-master
Переименуйте папку из async-mqtt-client-master в async_mqtt_client
Переместите папку async_mqtt_client в папку библиотек вашей Arduino IDE
Наконец, перезапустите Arduino IDE
В качестве альтернативы вы можете перейти в Sketch > Include Library > Add .ZIP library и выбрать только что скачанную библиотеку.
Установка библиотеки Async TCP
Для использования MQTT с ESP вам также нужна библиотека Async TCP.
Нажмите здесь, чтобы скачать библиотеку Async TCP client. У вас должен появиться .zip файл в папке загрузок
Распакуйте .zip файл, и вы получите папку AsyncTCP-master
Переименуйте папку из AsyncTCP-master в AsyncTCP
Переместите папку AsyncTCP в папку библиотек вашей Arduino IDE
Наконец, перезапустите Arduino IDE
В качестве альтернативы вы можете перейти в Sketch > Include Library > Add .ZIP library и выбрать только что скачанную библиотеку.
Библиотеки датчика BME280
Для получения показаний с модуля датчика BME280 мы будем использовать библиотеку Adafruit_BME280. Вам также нужно установить библиотеку Adafruit_Sensor. Выполните следующие шаги для установки библиотек в Arduino IDE:
Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.
Введите «adafruit bme280» в поле поиска и установите библиотеку.
Для использования библиотеки BME280 вам также нужно установить Adafruit Unified Sensor. Выполните следующие шаги для установки библиотеки в Arduino IDE:
Введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз, чтобы найти библиотеку, и установите её.
После установки библиотек перезапустите Arduino IDE.
Чтобы узнать больше о датчике BME280, прочитайте наше руководство: ESP32 с датчиком BME280 в Arduino IDE (давление, температура, влажность).
Необходимые компоненты
Для этого руководства вам понадобятся следующие компоненты:
ESP32 (читайте Лучшие платы разработки ESP32)
Плата Raspberry Pi (читайте Лучшие стартовые наборы Raspberry Pi)
Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Схема подключения
Подключите BME280 к ESP32, как показано на следующей схеме: вывод SDA подключён к GPIO 21, а вывод SCL — к GPIO 22.
Код
Скопируйте следующий код в вашу Arduino IDE. Чтобы он заработал, вам нужно вставить свои сетевые учётные данные, а также данные MQTT-брокера.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-mqtt-publish-bme280-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
// Raspberry Pi Mosquitto MQTT Broker
#define MQTT_HOST IPAddress(192, 168, 1, XXX)
// For a cloud MQTT broker, type the domain name
//#define MQTT_HOST "example.com"
#define MQTT_PORT 1883
// Temperature MQTT Topics
#define MQTT_PUB_TEMP "esp32/bme280/temperature"
#define MQTT_PUB_HUM "esp32/bme280/humidity"
#define MQTT_PUB_PRES "esp32/bme280/pressure"
// BME280 I2C
Adafruit_BME280 bme;
// Variables to hold sensor readings
float temp;
float hum;
float pres;
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
/*void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
Serial.println("Subscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
Serial.print(" qos: ");
Serial.println(qos);
}
void onMqttUnsubscribe(uint16_t packetId) {
Serial.println("Unsubscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}*/
void onMqttPublish(uint16_t packetId) {
Serial.print("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
void setup() {
Serial.begin(115200);
Serial.println();
// Initialize BME280 sensor
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
// If your broker requires authentication (username and password), set them below
//mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
connectToWifi();
}
void loop() {
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
// New BME280 sensor readings
temp = bme.readTemperature();
//temp = 1.8*bme.readTemperature() + 32;
hum = bme.readHumidity();
pres = bme.readPressure()/100.0F;
// Publish an MQTT message on topic esp32/BME2800/temperature
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_PUB_TEMP, packetIdPub1);
Serial.printf("Message: %.2f \n", temp);
// Publish an MQTT message on topic esp32/BME2800/humidity
uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(hum).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_PUB_HUM, packetIdPub2);
Serial.printf("Message: %.2f \n", hum);
// Publish an MQTT message on topic esp32/BME2800/pressure
uint16_t packetIdPub3 = mqttClient.publish(MQTT_PUB_PRES, 1, true, String(pres).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_PUB_PRES, packetIdPub3);
Serial.printf("Message: %.3f \n", pres);
}
}
Как работает код
Следующая секция импортирует все необходимые библиотеки.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
Укажите свои сетевые учётные данные в следующих строках.
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
Вставьте IP-адрес Raspberry Pi, чтобы ESP32 подключился к вашему брокеру.
#define MQTT_HOST IPAddress(192, 168, 1, 106)
Если вы используете облачный MQTT-брокер, вставьте доменное имя брокера, например:
#define MQTT_HOST "example.com"
Определите порт MQTT.
#define MQTT_PORT 1883
Температура, влажность и давление будут публиковаться в следующих топиках:
#define MQTT_PUB_TEMP "esp32/bme280/temperature"
#define MQTT_PUB_HUM "esp32/bme280/humidity"
#define MQTT_PUB_PRES "esp32/bme280/pressure"
Инициализация объекта Adafruit_BME280 с именем bme.
Adafruit_BME280 bme;
Переменные temp, hum и pres будут хранить значения температуры, влажности и давления от датчика BME280.
float temp;
float hum;
float pres;
Создайте объект AsyncMqttClient с именем mqttClient для управления MQTT-клиентом и таймеры для переподключения к MQTT-брокеру и маршрутизатору при потере соединения.
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
Затем создайте вспомогательные переменные таймера для публикации показаний каждые 10 секунд. Вы можете изменить время задержки в переменной interval.
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
Функции MQTT: подключение к Wi-Fi, подключение к MQTT и события Wi-Fi
Мы не добавляли комментарии к функциям, определённым в следующем разделе кода. Эти функции поставляются с библиотекой Async Mqtt Client. Названия функций достаточно говорят сами за себя.
Например, функция connectToWifi() подключает ESP32 к вашему маршрутизатору:
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
Функция connectToMqtt() подключает ESP32 к вашему MQTT-брокеру:
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
Функция WiFiEvent() отвечает за обработку событий Wi-Fi. Например, после успешного подключения к маршрутизатору и MQTT-брокеру она выводит IP-адрес ESP32. С другой стороны, если соединение потеряно, запускается таймер и выполняется попытка переподключения.
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0);
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
Функция onMqttConnect() выполняется после начала сессии с брокером.
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
Функции MQTT: отключение и публикация
Если ESP32 теряет соединение с MQTT-брокером, вызывается функция onMqttDisconnect, которая выводит сообщение в монитор порта.
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
Когда вы публикуете сообщение в MQTT-топик, вызывается функция onMqttPublish(). Она выводит идентификатор пакета в монитор порта.
void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
По сути, все эти функции, которые мы только что упомянули, являются callback-функциями. Они выполняются асинхронно.
setup()
Теперь перейдём к setup(). Инициализация датчика BME280.
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Следующие две строки создают таймеры, которые позволят переподключиться как к MQTT-брокеру, так и к Wi-Fi в случае потери соединения.
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
Следующая строка назначает callback-функцию, так что при подключении ESP32 к Wi-Fi будет выполнена функция WiFiEvent() для вывода описанных ранее данных.
WiFi.onEvent(WiFiEvent);
Наконец, назначьте все callback-функции. Это означает, что эти функции будут выполняться автоматически при необходимости. Например, когда ESP32 подключается к брокеру, автоматически вызывается функция onMqttConnect() и так далее.
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
Аутентификация брокера
Если ваш брокер требует аутентификации, раскомментируйте следующую строку и вставьте свои учётные данные (имя пользователя и пароль).
mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
Наконец, подключитесь к Wi-Fi.
connectToWifi();
loop()
В loop() вы создаёте таймер, который позволяет получать новые показания от датчика BME280 и публиковать их в соответствующий топик каждые 10 секунд.
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
// New BME280 sensor readings
temp = bme.readTemperature();
//temp = 1.8*bme.readTemperature() + 32;
hum = bme.readHumidity();
pres = bme.readPressure()/100.0F;
Узнайте больше о получении показаний с датчика BME280: ESP32 с датчиком BME280: руководство по температуре, влажности и давлению.
Публикация в топики
Для публикации показаний в соответствующие MQTT-топики используйте следующие строки:
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(hum).c_str());
uint16_t packetIdPub3 = mqttClient.publish(MQTT_PUB_PRES, 1, true, String(pres).c_str());
По сути, используйте метод publish() объекта mqttClient для публикации данных в топик. Метод publish() принимает следующие аргументы по порядку:
MQTT топик (const char*)
QoS (uint8_t): качество обслуживания — может быть 0, 1 или 2
Флаг retain (bool): флаг сохранения
Полезная нагрузка (const char*) — в данном случае полезная нагрузка соответствует показанию датчика
QoS (качество обслуживания) — это способ гарантировать доставку сообщения. Может быть одного из следующих уровней:
0: сообщение будет доставлено один раз или не доставлено вообще. Сообщение не подтверждается. Нет возможности дублирования сообщений;
1: сообщение будет доставлено как минимум один раз, но может быть доставлено более одного раза;
2: сообщение всегда доставляется ровно один раз;
Загрузка кода
При включённом Raspberry Pi с запущенным MQTT-брокером Mosquitto загрузите код в ESP32.
Откройте монитор порта на скорости 115200 бод, и вы увидите, что ESP32 начинает публиковать сообщения в определённые ранее топики.
Настройка панели Node-RED Dashboard
ESP32 публикует показания температуры каждые 10 секунд в топики esp32/bme280/temperature, esp32/bme280/humidity и esp32/bme280/pressure. Теперь вы можете использовать любую панель управления, поддерживающую MQTT, или любое другое устройство, поддерживающее MQTT, для подписки на эти топики и получения показаний.
В качестве примера мы создадим простой flow в Node-RED для подписки на эти топики и отображения показаний на приборных панелях.
Если у вас не установлен Node-RED, следуйте этим руководствам:
Когда Node-RED запущен на вашем Raspberry Pi, перейдите по IP-адресу Raspberry Pi с портом :1880.
http://raspberry-pi-ip-address:1880
Должен открыться интерфейс Node-RED. Перетащите три узла MQTT in и три узла gauge в flow.
Нажмите на узел MQTT и отредактируйте его свойства.
Поле Server указывает на MQTT-брокер. В нашем случае MQTT-брокер — это Raspberry Pi, поэтому установлено значение localhost:1883. Если вы используете облачный MQTT-брокер, измените это поле.
Укажите топик, на который хотите подписаться, и QoS. Предыдущий узел MQTT подписан на топик esp32/bme280/temperature.
Нажмите на другие узлы MQTT in и отредактируйте их свойства с тем же сервером, но для других топиков: esp32/bme280/humidity и esp32/bme280/pressure.
Нажмите на узлы gauge и отредактируйте их свойства для каждого показания. Следующий узел настроен для показаний температуры. Отредактируйте остальные узлы для других показаний.
Соедините узлы, как показано ниже:
Наконец, разверните ваш flow (нажмите кнопку в правом верхнем углу).
В качестве альтернативы вы можете перейти в Menu > Import и скопировать следующий код в Clipboard для создания вашего Node-RED flow.
[{"id":"5a45b8da.52b0d8","type":"mqtt in","z":"b01416d3.f69f38","name":"","topic":"esp32/bme280/temperature","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":340,"y":120,"wires":[["3042e15e.80a4ee"]]},{"id":"3042e15e.80a4ee","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"37de8fe8.46846","order":2,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"ºC","format":"{{value}}","min":0,"max":"40","colors":["#00b500","#f7df09","#ca3838"],"seg1":"","seg2":"","x":610,"y":120,"wires":[]},{"id":"8ff168f0.0c74a8","type":"mqtt in","z":"b01416d3.f69f38","name":"","topic":"esp32/bme280/humidity","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":320,"y":200,"wires":[["29251f29.6687c"]]},{"id":"29251f29.6687c","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"37de8fe8.46846","order":2,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"%","format":"{{value}}","min":"30","max":"100","colors":["#53a4e6","#1d78a9","#4e38c9"],"seg1":"","seg2":"","x":600,"y":200,"wires":[]},{"id":"681a1588.8506fc","type":"mqtt in","z":"b01416d3.f69f38","name":"","topic":"esp32/bme280/pressure","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":330,"y":280,"wires":[["41164c6.e7b3cb4"]]},{"id":"41164c6.e7b3cb4","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"37de8fe8.46846","order":2,"width":0,"height":0,"gtype":"gage","title":"Pressure","label":"hPa","format":"{{value}}","min":"900","max":"1100","colors":["#a346ff","#bd45cb","#7d007d"],"seg1":"","seg2":"","x":600,"y":280,"wires":[]},{"id":"8db3fac0.99dd48","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"37de8fe8.46846","type":"ui_group","z":"","name":"BME280","tab":"53b8c8f9.cfbe48","order":1,"disp":true,"width":"6","collapse":false},{"id":"53b8c8f9.cfbe48","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":2,"disabled":false,"hidden":false}]
Демонстрация
Перейдите по IP-адресу вашего Raspberry Pi с добавлением :1880/ui.
http://raspberry-pi-ip-address:1880/ui
Вы должны получить доступ к текущим показаниям датчика BME280 на Dashboard. Вы можете использовать другие типы узлов dashboard для отображения показаний различными способами.
Вот и всё! Ваша плата ESP32 публикует показания температуры, влажности и давления BME280 в Node-RED через MQTT.
Заключение
MQTT — отличный протокол связи для обмена небольшими объёмами данных между устройствами. В этом руководстве вы узнали, как публиковать показания температуры, влажности и давления с датчика BME280 с ESP32 в различные MQTT-топики. Затем вы можете использовать любое устройство или платформу домашней автоматизации для подписки на эти топики и получения показаний.
Вместо датчика BME280 вы можете использовать любой другой датчик, например, температурный датчик DS18B20 (ESP32 MQTT — Публикация показаний температуры DS18B20).
Если вы хотите узнать больше об ESP32, ознакомьтесь с нашими ресурсами:
Спасибо за чтение.
Источник: Rui Santos & Sara Santos — Random Nerd Tutorials