ESP8266 и Node-RED с MQTT (публикация и подписка)
Узнайте, как публиковать и подписываться на MQTT-топики с помощью платы ESP8266 NodeMCU. В этом руководстве мы будем использовать панель Node-RED для управления выходами ESP8266 и отображения данных датчиков ESP8266 на её интерфейсе. Программное обеспечение Node-RED работает на Raspberry Pi, а связь между ESP8266 и Node-RED осуществляется через коммуникационный протокол MQTT. Мы будем программировать ESP8266 с помощью Arduino IDE.
Обзор проекта
На следующем рисунке показан обзор того, что мы будем делать в этом руководстве.
Сначала посмотрите видео-демонстрацию ниже
Node-RED и панель Node-RED Dashboard
Для прохождения этого руководства вам необходимо иметь Node-RED и Node-RED Dashboard, установленные на вашем Raspberry Pi. Следуйте следующим руководствам для установки и начала работы с Node-RED и панелью Node-RED Dashboard:
Протокол MQTT
В этом руководстве мы установим связь между Raspberry Pi, на котором работает программное обеспечение Node-RED, и ESP8266 с помощью MQTT.
MQTT расшифровывается как MQ Telemetry Transport — это удобная лёгкая система публикации и подписки, в которой вы можете публиковать и получать сообщения как клиент. Это простой протокол обмена сообщениями, разработанный для ограниченных устройств с низкой пропускной способностью. Поэтому это идеальное решение для приложений Интернета вещей.
Если вы хотите узнать больше о MQTT, посмотрите видео ниже.
Для текстовой версии этого видео и дополнительных ресурсов прочитайте этот пост Что такое MQTT и как он работает.
Установка брокера Mosquitto
MQTT-брокер отвечает за получение всех сообщений, фильтрацию сообщений, определение того, кто в них заинтересован, а затем публикацию сообщений всем подписанным клиентам.
Существует несколько брокеров, которые вы можете использовать. В этом руководстве мы будем использовать брокер Mosquitto.
Вы можете установить MQTT-брокер Mosquitto локально на Raspberry Pi, на вашем компьютере или в облаке. Следуйте одному из следующих руководств для установки брокера Mosquitto:
Чтобы проверить, был ли брокер Mosquitto успешно установлен, выполните следующую команду:
pi@raspberry:~ $ mosquitto -v
Эта команда возвращает версию Mosquitto, которая в данный момент работает на вашем Raspberry Pi. Она должна быть 2.0.11 или выше.
Примечание: команда Mosquitto возвращает версию Mosquitto, которая в данный момент установлена, но также пытается инициализировать Mosquitto заново. Поскольку Mosquitto уже запущен, выводится сообщение об ошибке. Не беспокойтесь — Mosquitto правильно установлен и работает, если вы видите подобное сообщение.
Установка MQTT-соединения с Node-RED
В этом разделе мы установим MQTT-соединение с Node-RED с помощью MQTT-узлов.
Макет панели управления
Первым шагом является создание макета панели управления. В этом примере у нас будет кнопка для управления выходом ESP8266, график и индикатор для отображения показаний температуры и влажности с датчика DHT11.
В правом верхнем углу нажмите на маленький значок стрелки и нажмите Dashboard.
На вкладке Layout создайте вкладку с названием Room, а внутри вкладки Room создайте две группы: Lamp и Sensor, как показано на рисунке ниже.
Создание потока (Flow)
Из раздела dashboard на левой боковой панели перетащите узлы switch, chart и gauge в поток. Затем перетащите два узла MQTT in и один узел MQTT out в поток (они находятся в разделе network) — см. рисунок ниже.
switch — он будет управлять выходом ESP8266
mqtt output node — он будет публиковать сообщение для ESP8266 в соответствии с состоянием переключателя
2x mqtt input nodes — эти узлы будут подписаны на топики температуры и влажности для получения данных датчиков от ESP
chart — будет отображать показания датчика температуры
gauge — будет отображать показания датчика влажности
Node-RED и MQTT-брокер должны быть подключены. Чтобы подключить MQTT-брокер к Node-RED, дважды щёлкните на узле MQTT output. Появится новое окно — как показано на рисунке ниже.
1) Нажмите на опцию Add new mqtt-broker.
2) Введите localhost в поле Server. Все остальные настройки уже правильно сконфигурированы по умолчанию.
Если вы не запускаете Node-RED на том же компьютере, на котором работает Mosquitto (Raspberry Pi), введите IP-адрес MQTT вместо localhost.
3) Нажмите на вкладку Security и введите имя пользователя и пароль вашего MQTT-брокера, если это необходимо.
4) Нажмите Update, а затем Add. Узел MQTT output автоматически подключится к вашему брокеру после развёртывания потока Node-RED.
Отредактируйте свойства всех остальных узлов, как показано в следующих инструкциях.
Узел Switch
Переключатель отправляет строковое сообщение on, когда он включён; и отправляет строковое сообщение off, когда он выключен. Этот узел будет публиковать в топике room/lamp. Ваш ESP8266 затем будет подписан на этот топик для получения его сообщений. Отредактируйте свойства узла, как показано на рисунке ниже.
Узел mqtt output
Этот узел подключён к MQTT-брокеру Mosquitto и будет публиковать в топике room/lamp. Заполните поля, как показано ниже. Введите топик, на который хотите подписаться, установите значение QoS и укажите, хотите ли вы сохранять сообщения или нет.
Что такое retained (сохранённые) сообщения в MQTT? retain (true или false) — что это значит?
Retained-сообщение — это обычное MQTT-сообщение с флагом retained, установленным в true. Брокер сохраняет последнее retained-сообщение и соответствующий QoS для этого топика. Каждый клиент, который подписывается на шаблон топика, совпадающий с топиком retained-сообщения, получает retained-сообщение сразу после подписки. Брокер хранит только одно retained-сообщение на топик.
Почему это полезно? Retained-сообщения помогают вновь подписавшимся клиентам получить обновление статуса сразу после подписки на топик. Это особенно полезно для получения статуса устройства. Например, GPIO 2 в данный момент находится в состоянии HIGH, и ESP32 внезапно перезагружается. Он не знает, каким было последнее состояние GPIO 2. Однако, если состояние является retained-сообщением, оно будет получено сразу после подписки на топик, и состояние GPIO 2 можно обновить немедленно.
Узел mqtt input
Этот узел подписан на топик room/temperature для получения данных датчика температуры от ESP8266. ESP8266 будет публиковать показания температуры в этом топике.
Узел chart
График будет отображать показания, полученные в топике room/temperature.
Узел mqtt input
Этот узел подписан на топик room/humidity для получения данных датчика влажности от ESP8266. ESP8266 будет публиковать показания влажности именно в этом топике.
Узел gauge
Индикатор будет отображать показания, полученные в топике room/humidity. Отредактируйте свойства индикатора, как показано ниже. Вы можете настроить градиент цвета по своему вкусу.
Соедините ваши узлы, как показано на рисунке ниже.
Ваше приложение Node-RED готово. Нажмите кнопку Deploy в правом верхнем углу.
Приложение Node-RED готово. Чтобы увидеть, как выглядит ваша панель управления, перейдите по адресу http://your-pi-ip-address:1880/ui.
Теперь следуйте следующим разделам для подготовки вашего ESP8266.
Сборка схемы
В следующих разделах показаны необходимые компоненты и схемы для сборки цепи этого проекта.
Необходимые компоненты
Это компоненты, необходимые для сборки схемы (нажмите на ссылки ниже, чтобы найти лучшую цену на Maker Advisor):
Вы можете использовать приведённые выше ссылки или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Схема подключения
Вот схемы подключения для цепи этого проекта.
Подготовка Arduino IDE
Мы будем программировать ESP8266 с помощью Arduino IDE. Для загрузки кода на ESP8266 через Arduino IDE вам необходимо установить дополнение ESP8266 (Как установить плату ESP8266 в Arduino IDE). Вам также потребуется установить две дополнительные библиотеки, чтобы всё было готово для вашего ESP8266.
Установка библиотеки PubSubClient
Библиотека PubSubClient предоставляет клиент для простого обмена сообщениями по модели публикация/подписка с сервером, который поддерживает MQTT (по сути, позволяет вашему ESP8266 общаться с Node-RED).
1) Нажмите здесь, чтобы скачать библиотеку PubSubClient. В папке Downloads у вас должен появиться файл .zip.
2) В Arduino IDE перейдите в Sketch > Include Library > Add .ZIP library и выберите файл библиотеки .zip, который вы только что скачали.
3) Перезапустите вашу Arduino IDE.
Библиотека поставляется с рядом примеров. Смотрите File > Examples > PubSubClient в программе Arduino IDE.
Установка библиотеки датчика DHT
Для чтения данных с датчика DHT мы будем использовать библиотеку DHT от Adafruit. Для использования этой библиотеки вам также необходимо установить библиотеку Adafruit Unified Sensor. Выполните следующие шаги для установки этих библиотек.
1) Откройте вашу Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться Library Manager.
2) Найдите «DHT» в поле поиска и установите библиотеку DHT от Adafruit.
3) После установки библиотеки DHT от Adafruit введите «Adafruit Unified Sensor» в поле поиска. Прокрутите до самого низа, чтобы найти библиотеку, и установите её.
4) После установки библиотек перезапустите вашу Arduino IDE.
Для получения дополнительной информации о датчике DHT11 и ESP8266 прочитайте ESP8266 DHT11/DHT22 Temperature and Humidity Web Server with Arduino IDE.
Выбор правильной платы в Arduino IDE
Вам также необходимо выбрать правильную плату в Arduino IDE:
1) Перейдите в Tools > Board и выберите плату ESP8266, которую вы используете.
2) Выберите правильный COM-порт в Tools > Port.
Загрузка кода
Теперь вы можете загрузить следующий код на ваш ESP8266. Этот код публикует сообщения с температурой и влажностью от датчика DHT11 в топиках room/temperature и room/humidity через протокол MQTT.
ESP8266 подписан на топик room/lamp для получения сообщений, опубликованных в этом топике приложением Node-RED, для включения или выключения лампы.
Код хорошо прокомментирован в тех местах, где вам нужно внести изменения. Вам необходимо отредактировать код, указав ваши сетевые учётные данные (SSID и пароль), а также данные брокера (IP-адрес Raspberry Pi, имя пользователя и пароль mqtt-брокера).
Этот код также совместим с другими датчиками DHT — вам просто нужно раскомментировать и закомментировать нужные строки кода для выбора вашего датчика.
/*****
All the resources for this project:
https://randomnerdtutorials.com/
*****/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
// Uncomment one of the lines bellow for whatever DHT sensor type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// MQTT broker credentials (set to NULL if not required)
const char* MQTT_username = "REPLACE_WITH_MQTT_USERNAME";
const char* MQTT_password = "REPLACE_WITH_MQTT_PASSWORD";
// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "YOUR_BROKER_IP_ADDRESS";
//For example
//const char* mqtt_server = "192.168.1.106";
// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);
// DHT Sensor - GPIO 5 = D1 on ESP-12E NodeMCU board
const int DHTPin = 5;
// Lamp - LED - GPIO 4 = D2 on ESP-12E NodeMCU board
const int lamp = 4;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;
// This functions connects your ESP8266 to your router
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}
// This function is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic room/lamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
if(topic=="room/lamp"){
Serial.print("Changing Room lamp to ");
if(messageTemp == "on"){
digitalWrite(lamp, HIGH);
Serial.print("On");
}
else if(messageTemp == "off"){
digitalWrite(lamp, LOW);
Serial.print("Off");
}
}
Serial.println();
}
// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
/*
YOU MIGHT NEED TO CHANGE THIS LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a new name to the ESP8266.
Here's how it looks:
if (client.connect("ESP8266Client")) {
You can do it like this:
if (client.connect("ESP1_Office")) {
Then, for the other ESP:
if (client.connect("ESP2_Garage")) {
That should solve your MQTT multiple connections problem
*/
if (client.connect("ESP8266Client", MQTT_username, MQTT_password)) {
Serial.println("connected");
// Subscribe or resubscribe to a topic
// You can subscribe to more topics (to control more LEDs in this example)
client.subscribe("room/lamp");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
pinMode(lamp, OUTPUT);
dht.begin();
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {
if (!client.connected()) {
reconnect();
}
if(!client.loop())
client.connect("ESP8266Client", MQTT_username, MQTT_password);
now = millis();
// Publishes new temperature and humidity every 30 seconds
if (now - lastMeasure > 30000) {
lastMeasure = now;
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float humidity = dht.readHumidity();
// Read temperature as Celsius (the default)
float temperatureC = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float temperatureF = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temperatureC) || isnan(temperatureF)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Publishes Temperature and Humidity values
client.publish("room/temperature", String(temperatureC).c_str());
client.publish("room/humidity", String(humidity).c_str());
//Uncomment to publish temperature in F degrees
//client.publish("room/temperature", String(temperatureF).c_str());
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println(" %");
Serial.print("Temperature: ");
Serial.print(temperatureC);
Serial.println(" C");
Serial.print(temperatureF);
Serial.println(" F");
}
}
После загрузки кода, при работающем Raspberry Pi с приложением Node-RED и брокером Mosquitto, вы можете открыть монитор последовательного порта Arduino IDE на скорости 115200 бод и увидеть, что происходит в реальном времени.
Это полезно для проверки того, установил ли ESP8266 успешное соединение с вашим маршрутизатором и брокером Mosquitto. Вы также можете видеть сообщения, которые ESP8266 получает и публикует.
Демонстрация
Поздравляем! Ваш проект теперь завершён.
Перейдите по адресу http://your-pi-ip-address/ui, чтобы управлять ESP с помощью приложения Node-RED. Вы можете получить доступ к вашему приложению в любом браузере в той же сети, что и ваш Pi (смотрите видео-демонстрацию ниже).
Приложение должно выглядеть примерно как на рисунке ниже.
Заключение
В этом руководстве мы показали вам основные концепции, которые позволят вам включать свет и контролировать датчики на вашем ESP8266, используя Node-RED и коммуникационный протокол MQTT. Вы можете следовать этим базовым шагам для создания более продвинутых проектов.
У нас есть другие руководства по MQTT с использованием других датчиков, которые могут оказаться полезными:
ESP8266 NodeMCU MQTT — публикация показаний датчика BME280 (Arduino IDE)
ESP8266 NodeMCU MQTT — публикация показаний температуры DS18B20 (Arduino IDE)
Надеемся, что это руководство было для вас полезным.
Если вам нравится этот проект и домашняя автоматизация, обязательно ознакомьтесь с нашей электронной книгой: SMART HOME with Raspberry Pi, ESP32, and ESP8266.