Дисплей Nextion с ESP8266 – Сенсорный пользовательский интерфейс для Node-RED

Этот проект показывает, как вы можете создать сенсорный пользовательский интерфейс для Node-RED с дисплеем Nextion и ESP8266 для управления вашими электронными устройствами. Цель этого проекта – иметь возможность управлять вашей системой домашней автоматизации через дисплей Nextion без необходимости обращаться к смартфону или компьютеру для доступа к пользовательскому интерфейсу Node-RED, при этом Node-RED Dashboard всегда остается обновленным.

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

Предварительные требования

Другие полезные ресурсы:

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

Вы создадите физический интерфейс Node-RED с дисплеем Nextion для управления четырьмя различными выходами. Посмотрите на рисунок ниже:

Обзор проекта Nextion с ESP8266
  • Пользовательский интерфейс Nextion управляет четырьмя различными выходами.

  • ESP8266 #1 управляет Розеткой #1 и Розеткой #2 с помощью передатчика 433 МГц. Этот ESP8266 также подключен к дисплею Nextion.

  • ESP8266 #2 управляет двумя светодиодами, называемыми Рабочая лампа (Workbench) и Верхний свет (Top light). Идея состоит в том, что вы замените эти два светодиода полезными выходами, такими как реле или умный выключатель SONOFF, например.

  • Когда вы включаете выход с помощью дисплея Nextion, соответствующее состояние автоматически обновляется в Node-RED Dashboard.

  • Вы также можете управлять всеми этими выходами с помощью Node-RED Dashboard.

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

На рисунке ниже показано, как работает этот проект в 4 этапа.

Обзор работы проекта в 4 этапа

Давайте представим, что вы хотите включить Розетку #1.

1) Когда вы нажимаете кнопку включения Розетки #1, дисплей Nextion отправляет информацию на ESP8266 через последовательное соединение, чтобы он знал, что эта кнопка была нажата.

2) ESP и Raspberry Pi общаются друг с другом, используя протокол связи MQTT.

Raspberry Pi имеет установленный брокер Mosquitto, который принимает все MQTT-сообщения и отправляет их устройствам, подписанным на определенную тему (topic).

Когда вы нажимаете кнопку ON на дисплее Nextion, ESP публикует сообщение «true» в теме office/outlet1/buttonState.

3) Кнопка Розетки #1 в Node-RED подписана на эту тему и получит это сообщение. Когда она получает это сообщение, она изменяет соответствующее состояние кнопки на ON. Когда это происходит, Node-RED публикует сообщение в теме office/outlet1.

4) ESP подписан на эту тему, поэтому он знает, что Node-RED изменил состояние кнопки на ON. Затем ESP8266 отправляет сигнал 433 МГц с помощью передатчика 433 МГц, чтобы включить Розетку #1.

Этот процесс работает аналогично для управления всеми остальными выходами.

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

Для завершения этого проекта вам нужно собрать несколько компонентов:

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

Создание пользовательского интерфейса Nextion

Мы создали пользовательский интерфейс для 3.2» Nextion базовая модель. Если вы используете дисплей Nextion другого размера, вам нужно внести некоторые изменения в пользовательский интерфейс, чтобы он работал для вашей конкретной модели – поэтому вам нужно отредактировать файл .HMI и сгенерировать новый файл .TFT.

Загрузка ресурсов

Вот все ресурсы, которые вам нужны для создания GUI:

  • Файл .HMI (этот файл можно импортировать в Nextion Editor для редактирования GUI);

  • Фоновое изображение, используемое в пользовательском интерфейсе;

  • Файл .TFT (этот файл нужно загрузить на дисплей Nextion, это файл, который запускает дисплей);

Нажмите здесь, чтобы скачать все файлы.

Если вы хотите узнать, как создать или настроить пользовательский интерфейс Nextion, прочитайте: Дисплей Nextion с Arduino – Начало работы, чтобы научиться использовать Nextion Editor.

Компиляция и загрузка кода на дисплей Nextion

Если вы используете 3.2» Nextion базовую модель, вы можете напрямую загрузить файл .TFT на дисплей Nextion.

Если вы используете дисплей другого размера, вам нужно внести некоторые изменения в внешний вид пользовательского интерфейса. В программе Nextion Editor перейдите в File > Open и выберите предоставленный файл .HMI. Затем внесите необходимые изменения. Вы можете использовать инструмент Debug в Nextion Editor, чтобы предварительно посмотреть, как будет выглядеть интерфейс при отображении.

Окно отладки Nextion Editor

Для загрузки файла .TFT на дисплей Nextion вам нужна карта microSD, отформатированная как FAT32. Выполните следующие шаги для загрузки кода на дисплей Nextion:

1. Скопируйте файл .TFT, соответствующий финальной версии вашего пользовательского интерфейса.

2. Вставьте этот файл на карту microSD (примечание: карта microSD должна быть предварительно отформатирована как FAT32);

3. Вставьте карту microSD в дисплей Nextion и подключите питание.

Вставка microSD карты в дисплей Nextion

4. Вы должны увидеть сообщение на дисплее о том, что код загружается.

Загрузка кода на дисплей Nextion

5. Когда все будет готово, должно появиться следующее сообщение:

Успешная загрузка на дисплей Nextion

6. Отключите питание от дисплея Nextion и извлеките карту microSD.

7. Снова подайте питание, и вы должны увидеть интерфейс, который вы создали в Nextion Editor, на вашем дисплее Nextion.

ESP8266 #1 – Схема подключения

Подключите ESP8266 к дисплею Nextion и к передатчику 433 МГц, следуя схеме на рисунке ниже.

Схема подключения ESP8266 #1 с Nextion и передатчиком 433 МГц
  • Вывод TX дисплея Nextion должен быть подключен к выводу RX ESP8266.

  • Вывод RX дисплея Nextion должен быть подключен к выводу TX ESP8266.

  • Вывод данных передатчика 433 МГц подключен к GPIO 5 (вывод D1) ESP8266.

  • Вывод VCC передатчика 433 МГц подключен к выводу 3V3 ESP8266.

ESP8266 #2 – Схема подключения

Подключите два светодиода к другому ESP8266, как показано на схеме ниже.

Схема подключения ESP8266 #2 с двумя светодиодами
  • Красный светодиод подключен к GPIO 5 (вывод D1).

  • Зеленый светодиод подключен к GPIO 4 (вывод D2).

Декодирование RF сигналов розеток

Для управления розетками через сигналы 433 МГц вам нужно декодировать сигналы, которые включают и выключают розетки. Прочитайте следующую статью, чтобы узнать, как декодировать и отправлять 433 МГц RF сигналы с Arduino.

Код

Для каждого ESP8266 нужно загрузить отдельный скетч. Убедитесь, что вы вносите необходимые изменения в каждый код, чтобы он работал у вас.

Примечание: Перед загрузкой любого кода вам нужно убедиться, что библиотека Nextion для Arduino IDE правильно настроена для работы с ESP8266.

Настройка библиотеки Nextion для ESP8266

Имея библиотеку Nextion, установленную в вашей Arduino IDE, вам нужно внести некоторые изменения, чтобы она работала с вашим ESP8266.

  1. В папке библиотек Arduino откройте папку ITEADLIB_Arduino_Nextion

  2. Там должен быть файл NexConfig.h – откройте этот файл.

  3. Закомментируйте строку 27, чтобы она выглядела следующим образом:

//#define DEBUG_SERIAL_ENABLE
  1. Закомментируйте строку 32:

//#define dbSerial Serial
  1. Измените строку 37, чтобы у вас было следующее:

#define nexSerial Serial
  1. Сохраните файл NexConfig.h.

  2. Вот итоговый результат:

Файл конфигурации Nextion NexConfig.h

Код ESP8266 #1

Загрузите следующий код на ESP8266 номер #1. Вам нужно внести следующие изменения:

  1. Добавьте ваш SSID, пароль и IP-адрес MQTT-брокера

  2. Добавьте RF коды для включения и выключения ваших розеток. Если вы еще не декодировали RF сигналы для включения и выключения розеток, пожалуйста, следуйте этому руководству: Декодирование RF сигналов.

  3. Вам может потребоваться изменить имя устройства ESP8266

  4. Вы также можете настроить темы MQTT, на которые ваш ESP публикует или подписывается

Важно: чтобы загрузить код на ваш ESP8266, вы должны отключить кабели TX и RX, подключенные к дисплею Nextion.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

// Loading the required libraries
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "Nextion.h"
#include <RCSwitch.h>

//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX

// 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";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "REPLACE_WITH_YOUR_MQTT_BROKER_IP";
// For example: const char* mqtt_server = "192.168.1.112";

// Initialize the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

// Initialize the RC Switch component
RCSwitch mySwitch = RCSwitch();

// Declare a button object [page id:0,component id:1, component name: "b0"]
NexButton b0on = NexButton(0, 2, "b0on");
NexButton b0off = NexButton(0, 4, "b0off");
NexButton b1on = NexButton(0, 8, "b1on");
NexButton b1off = NexButton(0, 9, "b1off");
NexButton b2on = NexButton(0, 10, "b2on");
NexButton b2off = NexButton(0, 11, "b2off");
NexButton b3on = NexButton(0, 12, "b3on");
NexButton b3off = NexButton(0, 13, "b3off");

//Register a button object to the touch event list
NexTouch *nex_listen_list[] = {
  &b0on,
  &b0off,
  &b1on,
  &b1off,
  &b2on,
  &b2off,
  &b3on,
  &b3off,
  NULL
};

// Button component push callback function
void b0onPushCallback(void *ptr) {
  client.publish("office/workbench/buttonState", "true");
}
void b0offPushCallback(void *ptr) {
  client.publish("office/workbench/buttonState", "false");
}
void b1onPushCallback(void *ptr) {
  client.publish("office/toplight/buttonState", "true");
}
void b1offPushCallback(void *ptr) {
  client.publish("office/toplight/buttonState", "false");
}
void b2onPushCallback(void *ptr) {
  client.publish("office/outlet1/buttonState", "true");
}
void b2offPushCallback(void *ptr) {
  client.publish("office/outlet1/buttonState", "false");
}
void b3onPushCallback(void *ptr) {
  client.publish("office/outlet2/buttonState", "true");
}
void b3offPushCallback(void *ptr) {
  client.publish("office/outlet2/buttonState", "false");
}

// Don't change the function below.
// This function connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  //mySerial.println();
  //mySerial.print("Connecting to ");
  //mySerial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //mySerial.print(".");
  }
  //mySerial.println("");
  //mySerial.print("WiFi connected - ESP IP address: ");
  //mySerial.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) {
  //mySerial.print("Message arrived on topic: ");
  //mySerial.print(topic);
  //mySerial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    //mySerial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  //mySerial.println();

  // Feel free to add more if statements to control more outputs with MQTT
  // If a message is received on the topic office/outlet1, you check if the message is either true or false
  // Turns the outlet1 according to the message
  if(topic=="office/outlet1"){
      //mySerial.print("Changing Outlet 1 to ");
      if(messageTemp == "true"){
        mySwitch.send(4527445, 24);
        //mySerial.print("On");
      }
      else if(messageTemp == "false"){
        mySwitch.send(4527444, 24);
        //mySerial.print("Off");
      }
  }
  // Turns the outlet2 according to the message
  else if(topic=="office/outlet2"){
      //mySerial.print("Changing Outlet 2 to ");
      if(messageTemp == "true"){
        mySwitch.send(4539733, 24);
        //mySerial.print("On");
      }
      else if(messageTemp == "false"){
        mySwitch.send(4539732, 24);
        //mySerial.print("Off");
      }
  }
  //mySerial.println();
}

// This function 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()) {
    //mySerial.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:
       client.connect("ESP1_Office");
     Then, for the other ESP:
       client.connect("ESP1_Kitchen");
      That should solve your MQTT multiple connections problem
    */
    if(client.connect("ESP1_Office")) {
      //mySerial.println("connected");
      client.subscribe("office/outlet1");
      client.subscribe("office/outlet2");
    }
    else {
      //mySerial.print("failed, rc=");
      //mySerial.print(client.state());
      //mySerial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup(void) {
  //Set the baudrate which is for debug and communicate with Nextion screen
  nexInit();

  //Register the pop event callback function of the current button component
  b0on.attachPush(b0onPushCallback, &b0on);
  b0off.attachPush(b0offPushCallback, &b0off);
  b1on.attachPush(b1onPushCallback, &b1on);
  b1off.attachPush(b1offPushCallback, &b1off);
  b2on.attachPush(b2onPushCallback, &b2on);
  b2off.attachPush(b2offPushCallback, &b2off);
  b3on.attachPush(b3onPushCallback, &b3on);
  b3off.attachPush(b3offPushCallback, &b3off);

  // mySerial.begin(115200);

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  // Connect RF 433MHz Transmitter to GPIO 5
  mySwitch.enableTransmit(5);

  // SET YOUR PULSE LENGTH
   mySwitch.setPulseLength(REPLACE_WITH_YOUR_PULSE_LENGTH);

  // SET YOUR PROTOCOL (default is 1, will work for most outlets)
  mySwitch.setProtocol(REPLACE_WITH_YOUR_PROTOCOL);

  // Set number of transmission repetitions
  mySwitch.setRepeatTransmit(20);
}

void loop(void){
  // When a push event occured every time,
  // the corresponding component[right page id and component id] in touch event list will be asked
  nexLoop(nex_listen_list);

  if (!client.connected()) {
    reconnect();
  }
  /*
    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:
      client.connect("ESP1_Office");
    Then, for the other ESP:
      client.connect("ESP1_Kitchen");
    That should solve your MQTT multiple connections problem
    */
  if(!client.loop())
    client.connect("ESP1_Office");
}

Посмотреть исходный код

Код ESP8266 #2

Загрузите следующий код на ESP8266 номер #2. Не забудьте отредактировать код, чтобы добавить ваш SSID, пароль и IP-адрес MQTT-брокера:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

// Loading the required libraries
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX

// 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";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "REPLACE_WITH_YOUR_MQTT_BROKER_IP";
// For example: const char* mqtt_server = "192.168.1.112";

// 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);

// LED pins
const int ledPin5 = 5;
const int ledPin4 = 4;

// Don't change the function below. This function connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  //mySerial.println();
  //mySerial.print("Connecting to ");
  //mySerial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //mySerial.print(".");
  }
  //mySerial.println("");
  //mySerial.print("WiFi connected - ESP IP address: ");
  //mySerial.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) {
  //mySerial.print("Message arrived on topic: ");
  //mySerial.print(topic);
  //mySerial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    //mySerial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  //mySerial.println();

  // Feel free to add more if statements to control more outputs with MQTT
  // If a message is received on the topic office/workbench, you check if the message is either true or false
  // Turns the workbench according to the message
  if(topic=="office/workbench"){
      //mySerial.print("Changing Workbench to ");
      if(messageTemp == "true"){
        digitalWrite(ledPin5, HIGH);
        //mySerial.print("On");
      }
      else if(messageTemp == "false"){
        digitalWrite(ledPin5, LOW);
        //mySerial.print("Off");
      }
  }
  else if(topic=="office/toplight"){
      //mySerial.print("Changing Top Light to ");
      if(messageTemp == "true"){
        digitalWrite(ledPin4, HIGH);
        //mySerial.print("On");
      }
      else if(messageTemp == "false"){
        digitalWrite(ledPin4, LOW);
        //mySerial.print("Off");
      }
  }
  //mySerial.println();
}

// This function 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()) {
    //mySerial.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:
       client.connect("ESP2_Office");
     Then, for the other ESP:
       client.connect("ESP1_Kitchen");
      That should solve your MQTT multiple connections problem
    */
    if (client.connect("ESP2_Office")) {
      //mySerial.println("connected");
      client.subscribe("office/workbench");
      client.subscribe("office/toplight");
    } else {
      //mySerial.print("failed, rc=");
      //mySerial.print(client.state());
      //mySerial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup(void) {
  // Set GPIOs as Outputs
  pinMode(ledPin5, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  // mySerial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop(void){
  if (!client.connected()) {
    reconnect();
  }
  /*
   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:
     client.connect("ESP2_Office");
   Then, for the other ESP:
     client.connect("ESP1_Kitchen");
    That should solve your MQTT multiple connections problem
  */
  if(!client.loop())
    client.connect("ESP2_Office");
}

Посмотреть исходный код

Создание приложения Node-RED

Когда на обе платы ESP загружен код, пришло время создать ваш поток Node-RED. У вас должен быть установлен Node-RED и Node-RED Dashboard на вашем Raspberry Pi. Если нет, пожалуйста, прочитайте: Начало работы с Node-RED Dashboard, чтобы следовать инструкциям по установке Node-RED Dashboard.

Запуск Node-RED

Для запуска Node-RED введите следующее в окне терминала:

pi@raspberry:~ $ node-red-start

Для доступа к Node-RED откройте вкладку в любом браузере в локальной сети и введите следующее:

http://Your_RPi_IP_address:1880

Вы должны заменить Your_RPi_IP_address на IP-адрес вашего Raspberry Pi. Если вы не знаете IP-адрес вашего Raspberry Pi, в терминале введите:

pi@raspberry:~ $ hostname -I

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

Вы можете импортировать предоставленный поток Node-RED, а затем внести изменения, если это необходимо.

Чтобы импортировать поток Node-RED, перейдите в репозиторий Github или нажмите на рисунок ниже, чтобы увидеть исходный файл, и скопируйте предоставленный код.

Исходный код потока Node-RED на GitHub

Далее, в окне Node-RED, в правом верхнем углу, выберите меню и перейдите в Import > Clipboard.

Импорт узлов в Node-RED

Затем вставьте предоставленный код и нажмите Import.

Импорт потока Node-RED

Вот поток Node-RED, который вы должны получить:

Поток Node-RED

У вас есть четыре различные кнопки для управления четырьмя различными выходами. Каждая кнопка подписана на определенную тему, в которую ESP8266 #1 публикует сообщения для изменения состояния кнопок в Node-RED.

Каждая кнопка Node-RED публикует в теме, на которую подписаны ESP8266 #1 и ESP8266 #2, чтобы они знали, когда менять состояние выходов.

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

Все виджеты сгруппированы внутри группы Outputs на вкладке Office.

Вкладки панели управления Node-RED

Доступ к пользовательскому интерфейсу Node-RED

Перейдите по адресу http://Your_RPi_IP_address:1880/UI, и вы должны увидеть пользовательский интерфейс Node-RED.

Панель управления Node-RED с Nextion ESP8266

3D-печатный корпус

Чтобы придать этому проекту законченный вид, я напечатал на 3D-принтере корпус для дисплея 3.2» Nextion.

3D-печатный корпус для дисплея Nextion

Корпус имеет достаточно места для размещения дисплея, ESP8266 и передатчика 433 МГц.

3D-модель корпуса Nextion 3.2

Вы можете скачать файл .STL для корпуса Nextion для 3.5 дюйма. Обратите внимание, что для этого проекта я использовал Nextion 3.2», поэтому вам нужно изменить размер этих файлов, чтобы они подходили для дисплея Nextion 3.2».

Корпус был напечатан с помощью 3D-принтера Creality 3D CR-10 – вы можете прочитать мой полный обзор здесь.

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

Когда все готово, вы должны иметь возможность управлять своими выходами, нажимая кнопки на дисплее Nextion.

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

Когда вы нажимаете кнопку на дисплее Nextion, Node-RED Dashboard обновляется мгновенно.

Демонстрация Nextion ESP8266 с обновлением Node-RED

Посмотрите видео в начале страницы, чтобы увидеть этот проект в действии.

Заключение

Надеемся, вы нашли этот проект полезным. Изучив концепции в этом проекте, вы можете настроить его для управления практически всем, чем хотите, с помощью Node-RED, используя интерфейс дисплея Nextion.

Если вам понравился этот проект, вам наверняка понравятся:

Спасибо за чтение.