ESP8266 и Node-RED с MQTT (публикация и подписка)

Узнайте, как публиковать и подписываться на MQTT-топики с помощью платы ESP8266 NodeMCU. В этом руководстве мы будем использовать панель Node-RED для управления выходами ESP8266 и отображения данных датчиков ESP8266 на её интерфейсе. Программное обеспечение Node-RED работает на Raspberry Pi, а связь между ESP8266 и Node-RED осуществляется через коммуникационный протокол MQTT. Мы будем программировать ESP8266 с помощью Arduino IDE.

ESP8266 и Node-RED с MQTT (публикация и подписка)

Обзор проекта

На следующем рисунке показан обзор того, что мы будем делать в этом руководстве.

MQTT ESP8266 публикация и подписка Node-RED

Сначала посмотрите видео-демонстрацию ниже

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.

Брокер Mosquitto

Вы можете установить MQTT-брокер Mosquitto локально на Raspberry Pi, на вашем компьютере или в облаке. Следуйте одному из следующих руководств для установки брокера Mosquitto:

Чтобы проверить, был ли брокер Mosquitto успешно установлен, выполните следующую команду:

pi@raspberry:~ $ mosquitto -v

Эта команда возвращает версию Mosquitto, которая в данный момент работает на вашем Raspberry Pi. Она должна быть 2.0.11 или выше.

Проверка версии Mosquitto

Примечание: команда Mosquitto возвращает версию Mosquitto, которая в данный момент установлена, но также пытается инициализировать Mosquitto заново. Поскольку Mosquitto уже запущен, выводится сообщение об ошибке. Не беспокойтесь — Mosquitto правильно установлен и работает, если вы видите подобное сообщение.

Установка MQTT-соединения с Node-RED

В этом разделе мы установим MQTT-соединение с Node-RED с помощью MQTT-узлов.

Макет панели управления

Первым шагом является создание макета панели управления. В этом примере у нас будет кнопка для управления выходом ESP8266, график и индикатор для отображения показаний температуры и влажности с датчика DHT11.

В правом верхнем углу нажмите на маленький значок стрелки и нажмите Dashboard.

Доступ к макету панели Node-RED Dashboard

На вкладке Layout создайте вкладку с названием Room, а внутри вкладки Room создайте две группы: Lamp и Sensor, как показано на рисунке ниже.

Пример макета панели Node-RED Dashboard

Создание потока (Flow)

Из раздела dashboard на левой боковой панели перетащите узлы switch, chart и gauge в поток. Затем перетащите два узла MQTT in и один узел MQTT out в поток (они находятся в разделе network) — см. рисунок ниже.

Поток Node-RED
  • switch — он будет управлять выходом ESP8266

  • mqtt output node — он будет публиковать сообщение для ESP8266 в соответствии с состоянием переключателя

  • 2x mqtt input nodes — эти узлы будут подписаны на топики температуры и влажности для получения данных датчиков от ESP

  • chart — будет отображать показания датчика температуры

  • gauge — будет отображать показания датчика влажности

Node-RED и MQTT-брокер должны быть подключены. Чтобы подключить MQTT-брокер к Node-RED, дважды щёлкните на узле MQTT output. Появится новое окно — как показано на рисунке ниже.

MQTT Output узел

1) Нажмите на опцию Add new mqtt-broker.

Редактирование узла MQTT-брокера в Node-RED

2) Введите localhost в поле Server. Все остальные настройки уже правильно сконфигурированы по умолчанию.

Если вы не запускаете Node-RED на том же компьютере, на котором работает Mosquitto (Raspberry Pi), введите IP-адрес MQTT вместо localhost.

3) Нажмите на вкладку Security и введите имя пользователя и пароль вашего MQTT-брокера, если это необходимо.

Пароль MQTT-брокера в Node-RED

4) Нажмите Update, а затем Add. Узел MQTT output автоматически подключится к вашему брокеру после развёртывания потока Node-RED.

Отредактируйте свойства всех остальных узлов, как показано в следующих инструкциях.

Узел Switch

Переключатель отправляет строковое сообщение on, когда он включён; и отправляет строковое сообщение off, когда он выключен. Этот узел будет публиковать в топике room/lamp. Ваш ESP8266 затем будет подписан на этот топик для получения его сообщений. Отредактируйте свойства узла, как показано на рисунке ниже.

Редактирование узла Switch в Node-RED для MQTT

Узел mqtt output

Этот узел подключён к MQTT-брокеру Mosquitto и будет публиковать в топике room/lamp. Заполните поля, как показано ниже. Введите топик, на который хотите подписаться, установите значение QoS и укажите, хотите ли вы сохранять сообщения или нет.

Узел MQTT Out

Что такое 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 будет публиковать показания температуры в этом топике.

Node-RED подписка на топик температуры

Узел chart

График будет отображать показания, полученные в топике room/temperature.

Узел chart Node-RED

Узел mqtt input

Этот узел подписан на топик room/humidity для получения данных датчика влажности от ESP8266. ESP8266 будет публиковать показания влажности именно в этом топике.

Узел MQTT input для влажности

Узел gauge

Индикатор будет отображать показания, полученные в топике room/humidity. Отредактируйте свойства индикатора, как показано ниже. Вы можете настроить градиент цвета по своему вкусу.

Редактирование узла gauge для влажности в Node-RED

Соедините ваши узлы, как показано на рисунке ниже.

Соединение узлов Node-RED

Ваше приложение Node-RED готово. Нажмите кнопку Deploy в правом верхнем углу.

Развёртывание приложения Node-RED

Приложение Node-RED готово. Чтобы увидеть, как выглядит ваша панель управления, перейдите по адресу http://your-pi-ip-address:1880/ui.

Теперь следуйте следующим разделам для подготовки вашего ESP8266.

Сборка схемы

В следующих разделах показаны необходимые компоненты и схемы для сборки цепи этого проекта.

Необходимые компоненты

Это компоненты, необходимые для сборки схемы (нажмите на ссылки ниже, чтобы найти лучшую цену на Maker Advisor):

Вы можете использовать приведённые выше ссылки или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

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

Вот схемы подключения для цепи этого проекта.

Схема подключения ESP8266 MQTT Node-RED

Подготовка 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.

Установка библиотеки Adafruit DHT

3) После установки библиотеки DHT от Adafruit введите «Adafruit Unified Sensor» в поле поиска. Прокрутите до самого низа, чтобы найти библиотеку, и установите её.

Установка библиотеки драйвера 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 получает и публикует.

Монитор последовательного порта Arduino IDE

Демонстрация

Поздравляем! Ваш проект теперь завершён.

Перейдите по адресу http://your-pi-ip-address/ui, чтобы управлять ESP с помощью приложения Node-RED. Вы можете получить доступ к вашему приложению в любом браузере в той же сети, что и ваш Pi (смотрите видео-демонстрацию ниже).

Приложение должно выглядеть примерно как на рисунке ниже.

Приложение Node-RED Dashboard на смартфоне

Заключение

В этом руководстве мы показали вам основные концепции, которые позволят вам включать свет и контролировать датчики на вашем ESP8266, используя Node-RED и коммуникационный протокол MQTT. Вы можете следовать этим базовым шагам для создания более продвинутых проектов.

У нас есть другие руководства по MQTT с использованием других датчиков, которые могут оказаться полезными:

Надеемся, что это руководство было для вас полезным.

Если вам нравится этот проект и домашняя автоматизация, обязательно ознакомьтесь с нашей электронной книгой: SMART HOME with Raspberry Pi, ESP32, and ESP8266.