Дисплей Nextion с ESP8266 – Сенсорный пользовательский интерфейс для Node-RED
Этот проект показывает, как вы можете создать сенсорный пользовательский интерфейс для Node-RED с дисплеем Nextion и ESP8266 для управления вашими электронными устройствами. Цель этого проекта – иметь возможность управлять вашей системой домашней автоматизации через дисплей Nextion без необходимости обращаться к смартфону или компьютеру для доступа к пользовательскому интерфейсу Node-RED, при этом Node-RED Dashboard всегда остается обновленным.
Сначала посмотрите видео-демонстрацию
Предварительные требования
У вас должна быть установлена операционная система Raspbian на вашем Raspberry Pi – прочитайте Установка Raspbian Lite, включение и подключение через SSH.
Вам нужен Node-RED, установленный на вашем Pi и Node-RED Dashboard.
У вас должен быть установлен брокер Mosquitto на вашем Raspberry Pi – прочитайте Как установить брокер Mosquitto на Raspberry Pi.
У вас должен быть установлен Nextion Editor и библиотека Arduino Nextion установлена в вашей Arduino IDE – прочитайте Дисплей Nextion с Arduino – Начало работы для введения в дисплей Nextion.
Другие полезные ресурсы:
Обзор проекта
Вы создадите физический интерфейс Node-RED с дисплеем Nextion для управления четырьмя различными выходами. Посмотрите на рисунок ниже:
Пользовательский интерфейс Nextion управляет четырьмя различными выходами.
ESP8266 #1 управляет Розеткой #1 и Розеткой #2 с помощью передатчика 433 МГц. Этот ESP8266 также подключен к дисплею Nextion.
ESP8266 #2 управляет двумя светодиодами, называемыми Рабочая лампа (Workbench) и Верхний свет (Top light). Идея состоит в том, что вы замените эти два светодиода полезными выходами, такими как реле или умный выключатель SONOFF, например.
Когда вы включаете выход с помощью дисплея Nextion, соответствующее состояние автоматически обновляется в Node-RED Dashboard.
Вы также можете управлять всеми этими выходами с помощью Node-RED Dashboard.
Как работает проект?
На рисунке ниже показано, как работает этот проект в 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.
Этот процесс работает аналогично для управления всеми остальными выходами.
Необходимые компоненты
Для завершения этого проекта вам нужно собрать несколько компонентов:
Raspberry Pi – прочитайте Лучшие стартовые наборы Raspberry Pi
2x ESP8266 – прочитайте Лучшая плата разработки ESP8266 Wi-Fi
3.2» Nextion дисплей базовая модель – прочитайте Руководство по покупке дисплея Nextion
Вы можете использовать ссылки выше или перейти непосредственно на 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, чтобы предварительно посмотреть, как будет выглядеть интерфейс при отображении.
Для загрузки файла .TFT на дисплей Nextion вам нужна карта microSD, отформатированная как FAT32. Выполните следующие шаги для загрузки кода на дисплей Nextion:
1. Скопируйте файл .TFT, соответствующий финальной версии вашего пользовательского интерфейса.
2. Вставьте этот файл на карту microSD (примечание: карта microSD должна быть предварительно отформатирована как FAT32);
3. Вставьте карту microSD в дисплей Nextion и подключите питание.
4. Вы должны увидеть сообщение на дисплее о том, что код загружается.
5. Когда все будет готово, должно появиться следующее сообщение:
6. Отключите питание от дисплея Nextion и извлеките карту microSD.
7. Снова подайте питание, и вы должны увидеть интерфейс, который вы создали в Nextion Editor, на вашем дисплее Nextion.
ESP8266 #1 – Схема подключения
Подключите ESP8266 к дисплею Nextion и к передатчику 433 МГц, следуя схеме на рисунке ниже.
Вывод TX дисплея Nextion должен быть подключен к выводу RX ESP8266.
Вывод RX дисплея Nextion должен быть подключен к выводу TX ESP8266.
Вывод данных передатчика 433 МГц подключен к GPIO 5 (вывод D1) ESP8266.
Вывод VCC передатчика 433 МГц подключен к выводу 3V3 ESP8266.
ESP8266 #2 – Схема подключения
Подключите два светодиода к другому ESP8266, как показано на схеме ниже.
Красный светодиод подключен к GPIO 5 (вывод D1).
Зеленый светодиод подключен к GPIO 4 (вывод D2).
Декодирование RF сигналов розеток
Для управления розетками через сигналы 433 МГц вам нужно декодировать сигналы, которые включают и выключают розетки. Прочитайте следующую статью, чтобы узнать, как декодировать и отправлять 433 МГц RF сигналы с Arduino.
Код
Для каждого ESP8266 нужно загрузить отдельный скетч. Убедитесь, что вы вносите необходимые изменения в каждый код, чтобы он работал у вас.
Примечание: Перед загрузкой любого кода вам нужно убедиться, что библиотека Nextion для Arduino IDE правильно настроена для работы с ESP8266.
Настройка библиотеки Nextion для ESP8266
Имея библиотеку Nextion, установленную в вашей Arduino IDE, вам нужно внести некоторые изменения, чтобы она работала с вашим ESP8266.
В папке библиотек Arduino откройте папку ITEADLIB_Arduino_Nextion
Там должен быть файл NexConfig.h – откройте этот файл.
Закомментируйте строку 27, чтобы она выглядела следующим образом:
//#define DEBUG_SERIAL_ENABLE
Закомментируйте строку 32:
//#define dbSerial Serial
Измените строку 37, чтобы у вас было следующее:
#define nexSerial Serial
Сохраните файл NexConfig.h.
Вот итоговый результат:
Код ESP8266 #1
Загрузите следующий код на ESP8266 номер #1. Вам нужно внести следующие изменения:
Добавьте ваш SSID, пароль и IP-адрес MQTT-брокера
Добавьте RF коды для включения и выключения ваших розеток. Если вы еще не декодировали RF сигналы для включения и выключения розеток, пожалуйста, следуйте этому руководству: Декодирование RF сигналов.
Вам может потребоваться изменить имя устройства ESP8266
Вы также можете настроить темы 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, в правом верхнем углу, выберите меню и перейдите в Import > Clipboard.
Затем вставьте предоставленный код и нажмите Import.
Вот поток Node-RED, который вы должны получить:
У вас есть четыре различные кнопки для управления четырьмя различными выходами. Каждая кнопка подписана на определенную тему, в которую ESP8266 #1 публикует сообщения для изменения состояния кнопок в Node-RED.
Каждая кнопка Node-RED публикует в теме, на которую подписаны ESP8266 #1 и ESP8266 #2, чтобы они знали, когда менять состояние выходов.
Панель управления Node-RED
Все виджеты сгруппированы внутри группы Outputs на вкладке Office.
Доступ к пользовательскому интерфейсу Node-RED
Перейдите по адресу http://Your_RPi_IP_address:1880/UI, и вы должны увидеть пользовательский интерфейс Node-RED.
3D-печатный корпус
Чтобы придать этому проекту законченный вид, я напечатал на 3D-принтере корпус для дисплея 3.2» Nextion.
Корпус имеет достаточно места для размещения дисплея, ESP8266 и передатчика 433 МГц.
Вы можете скачать файл .STL для корпуса Nextion для 3.5 дюйма. Обратите внимание, что для этого проекта я использовал Nextion 3.2», поэтому вам нужно изменить размер этих файлов, чтобы они подходили для дисплея Nextion 3.2».
Корпус был напечатан с помощью 3D-принтера Creality 3D CR-10 – вы можете прочитать мой полный обзор здесь.
Демонстрация
Когда все готово, вы должны иметь возможность управлять своими выходами, нажимая кнопки на дисплее Nextion.
Когда вы нажимаете кнопку на дисплее Nextion, Node-RED Dashboard обновляется мгновенно.
Посмотрите видео в начале страницы, чтобы увидеть этот проект в действии.
Заключение
Надеемся, вы нашли этот проект полезным. Изучив концепции в этом проекте, вы можете настроить его для управления практически всем, чем хотите, с помощью Node-RED, используя интерфейс дисплея Nextion.
Если вам понравился этот проект, вам наверняка понравятся:
Спасибо за чтение.