The MQTT Protocol for IoT devices allows you to send and receive data via the MQTT server. But we can also use this Protocol to exchange messages sent by a person from IoT devices, i.e. create a chat for exchanging messages. Only each IoT device needs to be equipped with input and output devices.
Creating an IOT device on ESP32 and Nextion displayCreating An IOT device on the ESP32 microcontroller. To enter data sent to the MQTT server and display data coming from the MQTT server, we will use the Nextion touch screen. The Nextion display is connected to the ESP32 microcontroller via a serial port. We will use the Serial1 port:
• RX1 on GPIO9;
• TX1 on GPIO10.
Connection diagram
The Nextion display is a full-fledged computer with a processor, video card and screen, and it allocates all its computing resources for graphics processing and allows you to write your programs to it. The Nextion display modules have a UART connector and GPIO pins, which makes it possible to use Nextion displays both together with Arduino — connecting the display to the Arduino via the UART bus (exchange using unified commands), and separately — connecting buttons, LEDs, relays, etc.directly to the GPIO pins of the display). Programs can be loaded into the Nextion display via the micro-SD card slot.
To work with Nextion displays, you need to install the Nextion Editor program, which allows you to create a user interface using various library elements: buttons, sliders, images, graphics, text, etc., as well as prescribe display behavior algorithms for various events of elements that form this interface.
In the Nextion program, you need to create several pages : a chat window for displaying recent messages, and several pages for creating a message (keyboard Windows with lowercase alphabet, uppercase letters, and special characters).
All buttons must be enabled to send codes over the serial port at the Touch Presss Event
To flash the display via UART, you will need a USB-Serial adapter. Nextion connection diagram to the USB-Serial adapter.
To download the firmware, select the Upload menu item and click the Go button in the window that opens. The firmware process will be displayed in the program window and on the display module. When the firmware is finished, the downloaded project will be executed and displayed on the display module. It should be noted that the firmware via UART takes a very long time.
When you press the buttons on the display, the ESP32 card receives data via the serial port Serial1. Data received from the firmware loaded into the Nextion display:
Button ID in Nextion Data Note
+ADD t2 65 0 3 0 FF FF FF Create message
< e52 65 1 2C 1 FF FF FF Select message recipient
65 2 2C 1 FF FF FF (previous in the list)
65 3 2C 1 FF FF FF
> e53 65 1 2D 1 FF FF FF Select message recipient
65 2 2D 1 FF FF FF (next in the list)
65 3 2D 1 FF FF FF
send e50 65 1 29 1 FF FF FF Send a message
65 2 29 1 FF FF FF to the MQTT server
65 3 29 1 FF FF FF
back e54 65 1 2E 1 FF FF FF Go back to the chat
65 2 2E 1 FF FF FF window
65 3 2E 1 FF FF FF
<(backspace) b29 65 1 1E 1 FF FF FF Delete the last character
65 2 1E 1 FF FF FF
65 3 1E 1 FF FF FF
<< b39 65 1 28 1 FF FF FF Inserting a new line
65 2 28 1 FF FF FF
65 3 28 1 FF FF FF
z, Z, @ b30 65 1 1F 1 FF FF FF Switch to the next keyboard
65 2 1F 1 FF FF FF
65 3 1F 1 FF FF FF
others sending a character to a
message
Depending on the received data, the sketch performs certain actions specified in the parse_message () procedure. This is either just printing a character and adding it to the message, or switching between pages of characters, or returning, or sending a message to the server, etc.
The contents of the procedure.
void parse_message() {
if(nextionData[0]!=0x65) {
return;
}
if(nextionData[4]!=0xff && nextionData[5]!=0xff &&
nextionData[6]!=0xff) {
return;
}
// *****
// переход на набор сообщения
if(nextionData[1]==0 && nextionData[2]==3 &&
nextionData[3]==0) {
nextionSerial.print("page 1");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
// user
nextionSerial.print("e51.txt=\"");
nextionSerial.print(users[tuser].userName);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
// message
nextionSerial.print("e100.txt=\"");
nextionSerial.print(tekMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
// switching to a different keyboard
else if(nextionData[2]==0x1F) {
nextionSerial.print("page ");
nextionSerial.print(String((nextionData[1]%3+1)));
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
nextionSerial.print("e100.txt=\"\\r");
nextionSerial.print(tekMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
// send
else if(nextionData[2]==0x29) {
Serial.println("send");
publishData();
nextionSerial.print("page 0");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
//chatMessage=chatMessage+"\\r"+"\\t";
chatMessage=chatMessage+"I --> "+users[tuser].userLogin+": ";
chatMessage=chatMessage+tekMessage;
Serial.println(chatMessage);
nextionSerial.print("t0.txt=\"");
nextionSerial.print(chatMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
chatMessage=chatMessage+"\\r";
nextionSerial.print("t0.txt+=\"\\r\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
tekMessage="";
}
// back
else if(nextionData[2]==0x2E) {
Serial.println("back");
nextionSerial.print("page 0");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
Serial.println(chatMessage);
nextionSerial.print("t0.txt=\"");
nextionSerial.print(chatMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
tekMessage="";
}
// previos user
else if(nextionData[2]==0x2C) {
Serial.println("previos user");
tuser=(tuser+nusers-1)%nusers;
nextionSerial.print("e51.txt=\"");
nextionSerial.print(users[tuser].userName);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
// следующий user
else if(nextionData[2]==0x2D) {
Serial.println("next user");
tuser=(tuser+1)%nusers;
nextionSerial.print("e51.txt=\"");
nextionSerial.print(users[tuser].userName);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
// Backspace (deleting a character)
else if(nextionData[2]==0x1E) {
if(tekMessage.length()>0){
int d=1;
Serial.println(tekMessage.length());
if(tekMessage.endsWith("\r")==true)
d=2;
tekMessage=tekMessage.substring(0,tekMessage.length()-d);
Serial.println(tekMessage);
Serial.println(tekMessage.length());
Serial.println("забой");
nextionSerial.print("e100.txt=e100.txt-1");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
}
// \r\n
else if(nextionData[2]==0x28) {
Serial.println("\ n");
tekMessage=tekMessage+"\\r";
nextionSerial.print("e100.txt+=\"\\r\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
// вывод символа
else {
tekMessage=tekMessage+
nextionChars[nextionData[1]-1][nextionData[2]-1];
Serial.println(tekMessage);
Serial.println(tekMessage.length());
nextionSerial.print("e100.txt=\"");
nextionSerial.print(tekMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
}
Sending and receiving data from the MQTT serverWhen the send button is clicked, data is sent (published to topics) to /user1/user2, /user1/user3, or /user1/user4, depending on the selected message recipient. To send data, use the publishData () procedure. Procedure code
// sending data to topics of the broker
void publishData() {
String topic="/"+iam.userLogin+"/"+users[tuser].userLogin;
client.publish(topic.c_str(), tekMessage.c_str(), true);
}
To get data from the server, subscribe to the topics /user2/user1, /user3/user1, /user4/user1:
client.subscribe("/user2/user1");
client.subscribe("/user3/user1");
client.subscribe("/user4/user1");
And declare the callback function callback:
client.setCallback(callback);
The function code
// data acquisition
void callback(char* topic, byte* payload, unsigned int length) {
//Serial.print("from topic - ");
//Serial.print(topic);
//Serial.print(" ");
//Serial.print(length);
//Serial.print("=");
String myString = String((char*)payload);
//Serial.println(myString);
chatMessage=chatMessage+topic+": ";
chatMessage=chatMessage+myString.substring(0,9);
Serial.println(chatMessage);
nextionSerial.print("t0.txt=\"");
nextionSerial.print(chatMessage);
nextionSerial.print("\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
delay(10);
chatMessage=chatMessage+"\\r";
nextionSerial.print("t0.txt+=\"\\r\"");
nextionSerial.write(0xff);
nextionSerial.write(0xff);
nextionSerial.write(0xff);
}
We upload the sketch to the ESP32 Board and type messages on the Nextion display screen and send them to the server. All chat messages can be viewed on the server cloudmqtt.com. At the same time, you can send messages to any topic from the server panel, for example, for our device.
The user's incoming and outgoing messages are displayed on the display screen
Comments
Please log in or sign up to comment.