Arduino Forum

Using Arduino => Displays => Topic started by: PerryBebbington on Mar 17, 2019, 05:58 pm

Title: Using Nextion displays with Arduino
Post by: PerryBebbington on Mar 17, 2019, 05:58 pm
Introduction

 Nextion displays include either a resistive touch panel (RTP) or capacitive touch panel (CTP) and provide an easy way to create a touch screen interface, or human machine interface (HMI) for your project. The displays require a spare serial port to communicate with them. To get the best from them requires an understanding of how to drive them, and what works and doesn't work. The advice here is based on my work with 4 projects using Nextion displays with both PIC and Arduino hosts. I don't claim the ideas here are the best way or the only way to control one with an Arduino, just what I have found to work well in my projects. The sample code has been written by me and tested on an Elegoo Mega2560, and you are free to use it, modify or improve as much as you like. My methods and the examples shown here do not use any libraries as I never found them necessary, the displays are easy enough to drive without a library. If you want help with Nextion libraries please see Ray Livingston's improved Nextion libraries (https://forum.arduino.cc/index.php?topic=620821.0). I do not represent Arduino or Nextion.

Nextion support

The displays have their own instruction set which can be found here.  (https://nextion.itead.cc/instruction-set/)The instructions provide the means to control the displays either through messages sent to the serial port or from using the touch screen. This tutorial and sample code uses some of the Nextion instructions and assumes you have made yourself familiar with them from the Nextion web site.

The displays are configured using a WYSIWYG editor, which you can download from here. (https://nextion.itead.cc/nextion-editor-ver-0-58/) The sample configuration attached to this tutorial can be opened with this editor, which you will need to use the example here. (Latest version is V0.58 added 19 July 2019)

Compatibility with Arduino

I have used the basic 4.3" RTP version (NX4827T043) and the enhanced 7" CPT version (NX8048K070) with a WeMos M0, MKR WiFi 1010 and Elegoo Mega2560 without problems. There are problems using one with an ESP8266, see 'using Nextion displays with Arduino part 4' further down this tutorial. I have not tried other versions or other Arduinos. As the only requirement is a spare serial port on the Arduino to connect the display to, I would expect that any Arduino with a spare serial port would work with any Nextion display, but I've not tried combinations other than those mentioned here.

Demonstration
You will need:
 
 • The attached 'Arduino Nextion demo 43V1 HMI', which can be opened with the Nextion editor.
 • The attached 'Nextion_demonstration43.ino', which can be opened with the Arduino IDE.
 • An Arduino with at least 1 spare serial port.
 • A Nextion display.
 • A micro SD card.

Connecting the Nextion display to your Arduino

The displays come with a cable with 4 wires. I have only ever seen them in the following colours but if you get one with different colours please let me know so I can update this part of the tutorial.
 • Red - for connecting to +5V
 • Black - for connecting to 0V
 • Blue - Transmit data from the display to the Arduino, connect to RX on the Arduino
 • Yellow - Receive data from the Arduino to the display. Connect to TX on the Arduino
 
 Note, Arduinios use one serial port for communication with your PC, do not use this serial port for connection to your Nextion display, use a spare one.
 
 The displays run off 5v. All the ones I have output 3.3v on their serial transmit (blue wire). I have not had any problems using them with a WeMos M0 at 3.3v, an Elegoo Mega2560 at 5V or a PIC running on 5v. However, please check the voltage on the display transmit (blue) wire is not higher than maximum voltage your Arduino can tolerate.
 
 To connect a Nextion to an Arduino you need one free serial port on the Arduino. Connect the TX from the Arduino to the yellow wire and the RX to the Arduino to the blue wire. You will also need 0v to the black wire and +5v to the red wire. The current drawn by the display depends on the model and how bright the back light is. The 7" CPT display NX8048K070 requires up to 550mA, the smaller ones less. The 4.3" NX4827T043 used for this tutorial draws 235mA. In my experience they generate quite a bit of noise on the supply and, although not essential, I recommend a 470μF capacitor across the supply soldered to the connector on the back.
 Please see photo

(https://forum.arduino.cc/index.php?action=dlattach;topic=604185.0;attach=299720)

This shows the back of the display with a 470μF capacitor soldered to the outside 2 connections of the connector. Note that it is essential that the negative connection of the capacitor goes to GND and the positive to +5V, otherwise you will fill your room with nasty smelling smoke and scare your cat.

(https://forum.arduino.cc/index.php?action=dlattach;topic=604185.0;attach=299722)

(https://forum.arduino.cc/index.php?action=dlattach;topic=604185.0;attach=299724)

Demonstration software

This demonstration was created for the basic 4.3" RTP version, NX4827T043. You can adapt my configuration for a different display using the Nextion editor.
 
 Open the attached file 'Arduino Nextion demo 43V1.HMI' with the Nextion editor. If you are using a smaller display move the position of any objects that are outside the display area of the smaller display by changing X and Y for each object to a value that puts the object inside the boundaries of your display. Once you have done this select DEVICE ID from the menu and select your display from the list. If you have a bigger display you don't need to move anything around, just select the correct device ID.
 
 Compile the display configuration by clicking 'compile'.
 
 Click on File > Open build folder, this should open a window with a file 'Arduino Nextion demo 43V1.tft'
 
 Copy this file, and only this file, to a micro SD card (There must be nothing else on the SD card)
 
 Put the micro SD card into the card reader slot on the side of the display and connect the black wire to 0V and the red wire to 5V. You should see the display updating, which takes about 5 seconds.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Mar 17, 2019, 06:22 pm
Using Nextion displays with Arduino part 2

Once it has finished disconnect the power and then remove the SD card. Connect the power again and the display should start up and look something like this:

(https://forum.arduino.cc/index.php?action=dlattach;topic=604185.0;attach=299729)

Whatever version of display and Arduino you use make sure you know how to reference the serial port you are using. Because there are many Arduinos and clones, with varying numbers of serial ports, and because the choice of serial port is up to you, I cannot cover all possibilities in this tutorial. To develop this tutorial I used serial port 1 on an Elegoo Mega2560. You will need to edit the code to match the serial port you are using.

By default the Nextion serial port is configured for 9600 Baud and if you are new to Arduino or Nextion or both I recommend you leave it at 9600 Baud so that is one less thing to worry about if something doesn't work.

All you need to set up the Arduino for a Nextion display is:
Code: [Select]
void setup() {
  //This is for the serial monitor. Remove the // if you need to use it.
  //Serial.begin(9600);
  
  //This is for serial port 1, which is the one used for the Nextion in this demonstration.
  //You might need to change this depending on which serial port you are using for your display.
  Serial1.begin(9600);
  
  //For demonstration
  HMI_startup_message();
}
void HMI_startup_message() {
  Serial1.print(F("t0.txt=\""));
  Serial1.print(F("Nextion demonstration by Perry Bebbington. For support go to https://forum.arduino.cc/index.php?board=7.0"));
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}


Demonstration sketch and Nextion configuration.

The demonstration sketch creates a real time clock using millis()as the timing source. If you have read the various Arduino tutorials or are experienced with Arduino you will know that millis() is not accurate enough for an accurate real time clock. The purpose of this tutorial is to demonstrate an Arduino controlling a Nextion, and a clock seemed a simple way to do so. I leave it to you to create a more accurate clock.

Sending data to the display.

Sending to the display requires an understanding of the Nextion instruction set and what the display expects to receive. In the demonstration configuration there is a text box at the bottom with objname t0. To send text to this the display needs to receive.

t0.txt="Your text here"0xff 0xff 0xff

This is typical of any instruction, text or data, sent to the display. The display expects 0xff 0xff 0xff to indicate the end of the instruction.

For example:
Code: [Select]
void HMI_display_page(uint8_t page) {
  Serial.print(F("t0.txt=""));
  Serial.print(F("This is page "));
  Serial.print(page);
  Serial.print(""");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}


Puts the page number on t0.

Sending data from the Nextion display to the Arduino

I developed my own way of sending data from the display to the Arduino, which has proved flexible enough to adapt to all the applications I have so far tried. The basic idea is to identify each object on a page by the page it belongs to, its type and an index of that type.

'Type' is whatever you want it to be. Your project will have any number of buttons, sliders and whatever else on each page, you can group similar ones together and give them the same type, which is a number from 0 to however many you need. I reserve type 0 for the page itself.

'Index of type' is a number from 0 to 1 less than however many instances of the type there are on the page.

Unlike the displays, I chose not to use 0xff 0xff 0xff as a terminator for the data sent to the Arduino. Instead I use 0xa5 0xa5 0xa5 as a start indicator followed by 5 bytes. Sometimes the last byte or 2 is just padding to bring the total to 5. You can modify the code to expect more or fewer bytes, or use a different start sequence. The 5 bytes are the page number, the type, the index of the type and 2 data bytes.

The receive function looks for 0xa5 repeated 3 times, then saves the next 5 bytes in an array, then uses 3 levels of nested switch statements to identify which object on which page sent the data. Each case of the lowest level switch statement represents an individual object on the display and can be used to call whatever code you need for your project. The receive function should be called once each time in the main loop and will empty the receive buffer each time it is called.


Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Mar 17, 2019, 06:33 pm
Using Nextion displays with Arduino part 3

Complete demonstration code

The complete code for the demonstration is here and attached as 'Nextion_demonstration43.ino'

Setup and main loop

Code: [Select]

void setup() {
  //This is for the serial monitor. Remove the // if you need to use it.
  //Serial.begin(9600);
  
  //This is for serial port 1, which is the one used for the Nextion in this demonstration. You might need to change this depending on which serial port you are using for your display.
  Serial1.begin(9600);

  //For  demonstration
  HMI_startup_message();
}

void loop() {
  HMI_read();
  clock_run();
}

struct CLOCK {
  int8_t hour;
  int8_t minute;
  int8_t second;
};
struct CLOCK clock;

//This displays the clock
void HMI_display_clock() {
  char timestring[9];
  sprintf(timestring, "%02d:%02d:%02d ", clock.hour, clock.minute, clock.second);
  Serial.println(timestring);
  Serial1.print(F("t1.txt=\""));
  Serial1.print(timestring);
  Serial1.print("\"");
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

//This displays the page number
void HMI_display_page(uint8_t page) {
  Serial1.print(F("t0.txt=\""));
  Serial1.print(F("This is page "));
  Serial1.print(page);
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

void HMI_P1_display_slider(uint8_t slider_d1, uint8_t slider_d0) {
  uint16_t slider_val = (slider_d1 <<8 | slider_d0);
  
  //This displays byte 1 of the slider value in HEX
  Serial1.print(F("t2.txt=\""));
  Serial1.print(slider_d1, HEX);
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
  
  //This displays byte 0 of the slider value in HEX
  Serial1.print(F("t3.txt=\""));
  Serial1.print(slider_d0, HEX);
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);

  //This displays the complete slider value in decimal
  Serial1.print(F("t4.txt=\""));
  Serial1.print(slider_val);
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

void HMI_startup_message() {
  Serial1.print(F("t0.txt=\""));
  Serial1.print(F("Nextion demonstration by Perry Bebbington. For support go to https://forum.arduino.cc/index.php?board=7.0"));
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

//HMI_read takes the data sent from the Nextion to the serial port and processes it depending on what has been sent
//There are 3 levels of nested switch statements corresponding to the page, the type of object and the index of the object.
void HMI_read() {
  static uint8_t HMI_read_data[10];         //This is a temporary buffer to hold the data from the display. Space for 10 bytes although this demonstration only uses 6 bytes
  static uint8_t HMI_read_data_i;           //This is a count of how many bytes have been received from the display.
  static uint8_t a5count;                   //0xa5 repeated 3 times is used as a start indicator, this is a count of how many times it has been received.
  uint8_t readtemp;                         //This is to hold the last received byte to ensure that it is only read from the receive buffer once.
  
  while (Serial1.available() > 0) {         //Read every byte in the receive buffer
    readtemp = Serial1.read();
    if (readtemp == 0xa5) {                 //Count the number of times 0xa5 has been received
      ++a5count;
      if (a5count > 2) {
        a5count = 0;
        HMI_read_data_i = 0;
      }
    }
    else {
      a5count = 0;
    }
    HMI_read_data[HMI_read_data_i] = readtemp;
    if (HMI_read_data_i == 5) {
      switch (HMI_read_data[1]) {             //HMI_read_data[1] contains the page the data has come from
        case 0:                               //Case 0 means the data has come from page 0
          switch (HMI_read_data[2]) {         //HMI_read_data[2] contains the type of object on the page that the data has come from
            case 0:                           //In this demonstraton case 0 selects a page
              HMI_display_page(HMI_read_data[3]);
              break;
            case 1:                            //In this demonstration case 1 is a button for setting the clock
              switch (HMI_read_data[3]) {      //HMI_read_data[3] is the index of the type of button, so 0 to 5 as there are 6 buttons for setting the clock. Each case is a different button.
                case 0:
                  ++clock.hour;
                  if (clock.hour > 23) {
                    clock.hour = 0;
                  }
                  break;
                case 1:
                  --clock.hour;
                  if (clock.hour < 0) {
                    clock.hour = 23;
                  }
                  break;
                case 2:
                  ++clock.minute;
                  if (clock.minute > 59) {
                    clock.minute = 0;
                  }
                  break;
                case 3:
                  --clock.minute;
                  if (clock.minute < 0) {
                    clock.minute = 59;
                  }
                  break;
                case 4:
                  ++clock.second;
                  if (clock.second > 59) {
                    clock.second = 0;
                  }
                  break;
                case 5:
                  --clock.second;
                  if (clock.second < 0) {
                    clock.second = 59;
                  }
                  break;
              }
              HMI_display_clock();
              break;
          }
          break;
        case 1:                               //Case 1 means the data has come from page 1
          switch (HMI_read_data[2]) {
            case 0:                           //Data from the page itself, this is the post initialisation request to update the page, which displays the page number
              HMI_display_page(HMI_read_data[3]);
              break;
            case 1:                           //Data from the slider on page 1
              HMI_P1_display_slider(HMI_read_data[5], HMI_read_data[4]);      //HMI_read_data[5] is byte 1 of the slider value, HMI_read_data[4] is byte 0 of the slider value
              
              
              
              break;
          }
          break;
      }
    }
    ++HMI_read_data_i;
    if (HMI_read_data_i > 9) {
      HMI_read_data_i = 9;
    }
  }
}

void clock_run() {
  static unsigned long previousMillis;
  unsigned long currentMillis = millis();
  const unsigned long interval = 1000;
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    ++clock.second;
    if (clock.second > 59) {
      clock.second = 0;
      ++clock.minute;
      if (clock.minute > 59) {
        clock.minute = 0;
        ++clock.hour;
        if (clock.hour > 23) {
          clock.hour = 0;
        }
      }
    }
    HMI_display_clock();
  }
}
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Mar 17, 2019, 11:12 pm
Edited 10/8/2019

I have added Nextion additional features, which demonstrates several different thing together

Using Nextion displays with Arduino part 4

Some things that might help you


ESP8266
The ESP8266 has one serial port with both Tx and Rx available, and one with only Tx available. The one with both Tx and Rx is already in use for the serial monitor, making connecting a Nextion a bit of a problem. To get around this first write you code to send information to the Nextion but let it go to the serial monitor. When you are satisfied it is correct then use  Serial.swap(), which will swap the serial port to GPIO15 (Tx yellow) and GPIO13 (Rx blue). Note that GPIO15 (Tx) is also used on boot of the ESP8266 and if high makes it boot from an SD card, which creates a problem if you have a serial device connected and press reset, as the serial device will hold GPIO15 high. To get round this put a 10k (or possibly lower) resistor between GPIO15 and ground, this will hold GPIO15 low during boot.

Numbers
You might have noticed that in this demonstration I have used a single text box, t1, to display the time, I have not used one of the pre-defined number objects available in the Nextion editor. I found the numbers to be pretty useless, they can only be integers and they can't have any symbols attached to them, so you can't easily do £123.65 or 23.85% for example. Using a text box and print is much simpler.

Sliders
Page 1 of the demonstration has a slider with 3 text boxes, the first shows 2 bytes in hex as received from the Nextion, the 3rd shows the decimal value of the slider. I've made the range 0 to 1023, which is 0x00 to 0x3ff.

Baud rate
You can change the baud rate from 9600. In the Nextion editor select page 0 and find post initialisation event under event. Put baud=<required baud rate> as the first entry, for example baud=19200. This will make the display initialise with a baud rate of 19200. In your sketch initialise the serial port with:

Code: [Select]
[/color]
Code: [Select]
void setup() {
   //This is for serial port 1, which is the one used in this demonstration.
   //You might need to change this depending on which serial port you are using for your display.
  Serial1.begin(19200);
}



If you want to change the baud rate during program execution you have to be careful not to end up with the Arduino at one baud rate and the display at another. For this reason you need to send the change of baud rate instruction to the display, wait for the instruction to be sent then change the rate on the Arduino, then send data and instructions at the new rate. This will tell the display to change its baud rate:

Code: [Select]

Code: [Select]
void HMI_baud_change(uint32_t baud) {
  Serial.print(F("baud="));
  Serial.print(baud);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}



However, you have to remember that serial transmission is slow, so after the last Serial.write(0xff); has completed the 'b' of baud will probably not have been sent to the display. Also, once the display has received the complete instruction it takes time to make the change. For this reason you need to wait before changing the Arduino baud rate with:

Code: [Select]

Code: [Select]
Serial.begin(new baud rate);


Changing pages
If you look at my demonstration configuration there are 2 buttons P0 and P1 on each page. P1 on page 0 and P0 on page 1 change the page displayed but don't tell the Arduino that the page has changed. On each page under post initialisation event is the code that tells the Arduino that the page has changed. This is to ensure that the page has properly initialised before the Arduino sends any data to it.

Using background images
The demonstration Nextion configuration I supplied in 'Arduino Nextion demo 43V1 HMI.zip' is about as simple as I could make it. It is possible to use 2 (or more) background images to provide buttons or whatever you like in any design you want. To do this means using the Nextion cropped image feature. Attached to this post is 'Arduino Nextion demo cropped images 43V1.zip', which is exactly the same Nextion configuration file but using cropped images for the buttons to demonstrate how to do this.

Nextion additional features includes:
A scrollable list
Having the Arduino trigger code to run on the Nextion
Using a slider
Displaying numbers without using number boxes
Using flags
A simple state machine

Credits
Thank you Robin 2 (http://"https://forum.arduino.cc/index.php?action=profile;u=174714") and Ballscrewbob (http://"https://forum.arduino.cc/index.php?action=profile;u=261482\""") for your help with this tutorial
Title: Re: Using Nextion displays with Arduino
Post by: Watcher on Apr 01, 2019, 06:37 pm
Excellent Tutorial!

Does anyone know if its possible to create objects with serial commands just like its done via the editor?

I.e Is it possible to create a button from serial and the nhange all its attributes?





Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Apr 01, 2019, 07:38 pm
Excellent Tutorial!

Does anyone know if its possible to create objects with serial commands just like its done via the editor?

I.e Is it possible to create a button from serial and the change all its attributes?
Quote
Excellent Tutorial!
:) THANK YOU!!! :)


Quote
Does anyone know if its possible to create objects with serial commands just like its done via the editor?
I.e Is it possible to create a button from serial and the change all its attributes?
I think probably not. There are attributes that cannot be changed by sending instructions over the serial port. If you look in the Nextion editor at an object some of the attributes are in green text and some in black text. I have not tried every possibility but I was trying to change some of the attributes that are in black text by sending instructions over the serial port and concluded they they cannot be changed this way. I assume from this that if an object has attributes that cannot be changed over the serial port then it must be impossible to create an object over the serial port.

What are you trying to achieve? There might be a way round this restriction.

Title: Re: Using Nextion displays with Arduino
Post by: Watcher on Apr 01, 2019, 08:43 pm
Quote
What are you trying to achieve? There might be a way round this restriction.
I plan to develop a touch screen display for an existing home automation system which is RS485 based.


So basically I need to program a series of soft push button on the display whose description as well as status (on/off) will come from the Arduino.

Pushing the button should send Arduino a unique code which will then execute the associated home automation command.

If it was possible to create buttons with serial commands, then the actual screen layout could be controlled by the arduino.
I did something similar on web based home automation screen using the html dom (https://www.w3schools.com/js/js_htmldom.asp).

The button press return code whoukd also be remotely set (via serial command)  as well.



Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Apr 01, 2019, 09:22 pm

Quote
I need to program a series of soft push button on the display whose description as well as status (on/off) will come from the Arduino.
You can change the text on a button in the same way as you change the text in a text box. You can also change the background colour and the text colour with the appropriate serial commands. For example:


Code: [Select]
void HMI_button_on_message() {
  Serial1.print(F("b0.txt=\""));
  Serial1.print(F("On"));
  Serial1.print(F("\""));
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

Will change the text on button b0 to On.

Play around in the Nextion editor with the debug options and see what you need to send to an object to change particular attributes. For example, in debug, if you type

Code: [Select]
b0.bco=63488<return>

then b0 will become red.


Quote
Pushing the button should send Arduino a unique code which will then execute the associated home automation command.
That's what my method does! Each button in the example sends a unique code that is decoded by the 3 levels of switch() statements to a unique point from which you can call whatever functions you like.


Quote
If it was possible to create buttons with serial commands, then the actual screen layout could be controlled by the arduino.
I don't believe you can change the layout, only the text and colours of the buttons.


Quote
The button press return code should also be remotely set (via serial command)  as well.
You don't need to. You change how your program responds to each unique code sent from the buttons.

What you could do is have multiple pages on the Nextion and have the Arduino send instructions to change the page. Each page would have the different layouts and each button would have a unique identity on the page. If you look at my demonstration I included 2 pages to illustrate how this works.




Title: Re: Using Nextion displays with Arduino
Post by: Watcher on Apr 02, 2019, 09:21 am
Quote
lay around in the Nextion editor with the debug options and see what you need to send to an object to change particular attributes. For example, in debug, if you type

Code: [Select]

b0.bco=63488<return>
Yeap! Already tried all that!

eg  This function changes the text on a textbox:

Code: [Select]
void HMI_displayText(byte boxNo, char* text){
 
  nextion.print(F("t"));
  nextion.print(boxNo);
  nextion.print(F(".txt=\""));
  nextion.print(text);
  nextion.print(F("\""));
 
  HMICommandEnd();
 
}


and this changes the color of a button :

Code: [Select]
void showButtonActivated(byte buttonNo) {

char comd[20];
char temp[20];

strcpy(comd,"b");
sprintf(temp, "%01d.bco=63488", buttonNo);
strcat(comd,temp);
Serial.println (comd);
nextion.print(comd);
 
HMICommandEnd();
 
}


However, I have potentially more than 100 buttons to configure each controlling things from lights, heating, mechanical appliances to  audio, etc . The buttons are grouped together according to their logical operation. For example all bedroom lights are grouped together and should appear on the same page. I am using a 3.5in nextion (for now) which seems like it can accommodate about 8 12 or so buttons per page.

I am trying to figure out some method which will enable me to make changes on the available buttons on the nextion screen as well as their grouping without having to re-program the nextion every time since that would need physical access to the display's usb port which will not be easily accessible once mounted on the wall.

The arduino itself is  being controlled remotely via RS485 link. The same link will curry the command to be executed once a button is pressed.

Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Apr 02, 2019, 06:22 pm
Hello Watcher,

I get the impression you are getting the hang of this and don't need much more from me. My heating controller has 5 pages and buttons in one corner to switch between them. My advice to you is to look how I switch pages in the example in this tutorial; the button on the page switches to the desired page directly, it does not tell the Arduino to change pages. On each page under Postinitializationevent is the code that tells the Arduino that the page has changed. Once the Arduino receives the code that the page has changed it then replies with the data appropriate to the page. The reason for doing it this way is to make sure that the new data needed on the page is not sent until after the page has initialised. I had lots of problems with errors in the data whenever I changed pages until I realised it took ages for a page to initialise and that data sent before that might be lost.
Title: Re: Using Nextion displays with Arduino
Post by: Watcher on Apr 04, 2019, 12:06 pm
I decided to design a single page with 12 buttons the description of each changes as the user changes page.
I other words changing a page it will only change the button's description and the actual code each button sends when pressed.


Anyone knows where to find some nice looking "transparent" images/icons to display on these screens?

Things like arrows left,right, bulbs, thermometers etc ?
Title: Re: Using Nextion displays with Arduino
Post by: valbuz on Apr 04, 2019, 02:29 pm
hi.

my problems are with the fonts.....

some text fields on the page.
there are fields labeled by the editor other are labeled by sending commands from sketch.
but they are different on the page!
the fields by command aren't very good readable. the fields by editor are very well.
it's the same font and size for both.

anybody knows such a problem?

thanks
pat

Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Apr 04, 2019, 06:50 pm
Quote
Anyone knows where to find some nice looking "transparent" images/icons to display on these screens?
Things like arrows left,right, bulbs, thermometers etc ?
When I have needed them I have searched on the internet, there are loads and loads of free downloads if you go looking. Be aware that the Nextion does not support transparent images, although you might need them to construct a background to your needs.
Title: Re: Using Nextion displays with Arduino
Post by: RedyAu on Apr 21, 2019, 06:36 pm
I decided to design a single page with 12 buttons the description of each changes as the user changes page.
I other words changing a page it will only change the button's description and the actual code each button sends when pressed.


Anyone knows where to find some nice looking "transparent" images/icons to display on these screens?

Things like arrows left,right, bulbs, thermometers etc ?
https://www.flaticon.com/ is a good starting place. You should draw everything in another progam (inkscape, photoshop, whatever), and just build the functionality with nextion. That way it'll look very nice.
Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on May 12, 2019, 04:37 am
I'm new to the C language so maybe people have a better way to avoid creating multiple text boxes just to get a line break.

I've been trying to put \n in my t0.txt command, but it just brings up a strange inline character rather than putting a line break...any ideas?
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on May 12, 2019, 09:56 am
I've been trying to put \n in my t0.txt command, but it just brings up a strange inline character rather than putting a line break...any ideas?
If you mean you want to send new line to a Nextion text box then I think you are wasting your time, I don't think they support it. (If I am mistaken and you know for sure that they do support it then I'd like to know). As far as I know the text boxes treat all text as a single line. Where I have needed multiple lines of text I have used multiple text boxes.
Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on May 12, 2019, 06:44 pm
If you mean you want to send new line to a Nextion text box then I think you are wasting your time, I don't think they support it. (If I am mistaken and you know for sure that they do support it then I'd like to know). As far as I know the text boxes treat all text as a single line. Where I have needed multiple lines of text I have used multiple text boxes.
Yeah I wasted some time searching around and trying things, nothing to be done there. But, the good news is that your method is working out great now. Apart from the graphic interface, I have most of my coding and variables on the Arduino now and it receives all the user-entered data through the keyboard in bytes before being appended into a complete string. Anyway - thanks for figuring this thing out, I was going mental.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on May 12, 2019, 10:27 pm
Quote
Yeah I wasted some time searching around and trying things, nothing to be done there.
That's a shame, I was rather hoping you'd discovered something I'd missed!


Quote
Apart from the graphic interface.
What are you trying to do? In my first draft of this tutorial I had graphics in it, but I ditched them because having any graphics would make it much harder for someone to adapt the tutorial to different size displays, so the instructions I gave for using a different display to the one I wrote the tutorial for would have become more complex, and I didn't think that was a good idea for a tutorial aimed at someone new to Nextion displays, so I left it out.


Quote
Thanks for figuring this thing out, I was going mental.
My pleasure :)


Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on May 13, 2019, 02:18 am
What are you trying to do? In my first draft of this tutorial I had graphics in it, but I ditched them because having any graphics would make it much harder for someone to adapt the tutorial to different size displays, so the instructions I gave for using a different display to the one I wrote the tutorial for would have become more complex, and I didn't think that was a good idea for a tutorial aimed at someone new to Nextion displays, so I left it out.
I have to be secretive about the thing I'm building, but I'll make a thread on this forum so I can show off when it's finished. I think if I said it, someone who's much better at programming would make one quicker than me and ruin my chance at being the first :D. It's a machine for manufacturing musical instrument parts.

The graphics I'm using are just bitmap images (actually nextion editor imports PNGs nicely too) to create all the buttons and icons for the UI, but I draw the backgrounds in manually using fill commands. That sort of thing can all be sent over serial from the arduino too using your method (I use it to do vis commands on elements and page changes etc). Theoretically, you could draw all your background UI elements via serial, but I dunno about creating buttons and pages from nothing.

It never occurred to me to control the images from the serial line - the Nextion editor is good enough for creating and navigating through the pages and elements, and you can do a lot of programming on it, but because the serial communication libraries are pretty much useless and there's absolutely no consideration for global variables, complex projects that require a proper MCU board should definitely use your method and store all their code on the board.



I'll post the a QWERTY keyboard code if it'll be useful around here - it's probably not the most attractive looking code, but but you receive all your user-entered data byte by byte and it's assembled into complete variables / strings / integers / floats on the arduino end.


What I'd really like to do with these Nextions though is work out the font issues...they looks so crusty and the sizing/spacing is all over the place, inconsistent, and no antialiasing. The Nextion font generator is absolute garbage, and they charge about $250 USD for a premade font. There's no repository online to download free fonts, and the only project to create proper fonts is still being worked on...who knows how long it'll take.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on May 13, 2019, 09:46 pm

Quote
The Nextion font generator is absolute garbage
Indeed. Search for zi font editor and you should find a tool to edit them to your own liking.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on May 13, 2019, 10:44 pm
Quote
I draw the backgrounds in manually using fill commands.
2 suggestions:

If you want to draw stuff, or do anything that would require a lot of data to be sent over the serial port, create a button and put all the code to do the drawing or whatever under touch release event for the button. Make the button 1 pixel * 1 pixel and give it the same colour as the background, and place it somewhere on the display where it is out of the way. Then you can use something like:


Code: [Select]
void HMI_draw_background() {
  Serial.print("click b0,1");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("click b0,0");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}


To click the button and the Nextion will execute all the code under the button and do the drawing or whatever.

Alternatively, have a look in part 4 of this tutorial at 'using background images', you can create a background with whatever you like on it. Create 2 almost identical backgrounds with one showing, for example, buttons not pressed, the other showing pressed, and use the cropped image feature to select which one shows when you press the button.
Title: Re: Using Nextion displays with Arduino
Post by: rubendargalan on May 14, 2019, 05:51 pm
Hello, thank you very much for this tutorial Perry Bebbington, it is excellent. I see that these screens consume a lot of energy (you said that the NX4827T043 consumes 235mA). Do you have any way to decrease its brightness? Or leave it in sleep mode? To try to reduce your consumption. Thank you very much again. A greeting.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on May 14, 2019, 06:18 pm

Quote
Hello, thank you very much for this tutorial Perry Bebbington, it is excellent.
Thank you :)


Quote
Do you have any way to decrease its brightness?
Look in the Nextion instruction set for 'dim' and 'dims', they control the brightness, and as you expect, lower brightness means lower current consumption. Unfortunately, what does not lower the current consumption is putting dark things on the display, you can make the background black or white and it will consume the same amount of power.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jun 08, 2019, 02:40 pm
I've modified the HMI files to include automatic display dimming, which happens after 10 seconds of no pressing any buttons.
Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on Jun 08, 2019, 06:17 pm
I've modified the HMI files to include automatic display dimming, which happens after 10 seconds of no pressing any buttons.
Nextion needs to put you on the payroll for figuring out how to make their screens useful.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jun 08, 2019, 06:47 pm
Nextion needs to put you on the payroll for figuring out how to make their screens useful.
That would be nice :)
Title: Re: Using Nextion displays with Arduino
Post by: chuckhager on Jun 11, 2019, 06:00 pm
For some reason, I cannot find the HMI file. The zip file only has the TFT file.
 
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jun 12, 2019, 10:07 am
Hello chuckhager,

Apologies, I uploaded the wrong file when I made some changes a few days ago. Hopefully you will get the correct file now if you download again. If not, please let me know.

Thanks,
Perry
Title: Re: Using Nextion displays with Arduino
Post by: Fractoggen on Jun 18, 2019, 08:13 am
it is really good for me. :o
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jun 22, 2019, 10:52 am
In 'Using Nextion displays with Arduino part 4' I have added a demonstration of using a scrollable text list. This includes new HMI and ino files for you to download and try.
Title: Re: Using Nextion displays with Arduino
Post by: kn4ud on Jul 19, 2019, 01:12 pm
Perry, thank you very much for taking your time to share your knowledge and ability of using the Nextion with Arduino. I have a project I have been struggling with and I am finding this a big help.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 19, 2019, 04:19 pm
Perry, thank you very much for taking your time to share your knowledge and ability of using the Nextion with Arduino. I have a project I have been struggling with and I am finding this a big help.
My pleasure! Glad to be of help and I appreciate the feedback :)
Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on Jul 19, 2019, 08:09 pm
Nextion has just released a new update for their editor - I downloaded it and it's actually a decent improvement, not what I expected from them. They've added font anti-aliasing - you have to regenerate your fonts again with their generator tool, but it looks fine so far. Just about to do some testing.

Anyway, thought you'd be interested to know if you hadn't seen it yet - I'm wondering what else they've added...will have to google it now.

e: https://nextion.itead.cc/instruction-set/ has been updated
Title: Re: Using Nextion displays with Arduino
Post by: kn4ud on Jul 19, 2019, 09:54 pm
I updated from 53 yesterday. So far no problems other than the ones I cause for myself. I am glad to know I will need to regenerate my fonts. In my older files they appear as they did. some seem to have irregular spacing as they did. I am going to regenerate them and see if they look better.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 20, 2019, 09:52 am
Thanks for the info JT. I had been concerned that ITEAD were neglecting the Nextion product as there have not been any updates to the IDE for ages. I've updated the link for downloading the editor at the start of this tutorial.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 20, 2019, 10:22 am
Well, it didn't take me long to find a bug in it! When I close it, instead of it closing gracefully I get the Windows warning message 'HMI has stopped working'. Does anyone else get this?
Title: Re: Using Nextion displays with Arduino
Post by: Watcher on Jul 20, 2019, 10:31 am
Well, it didn't take me long to find a bug in it! When I close it, instead of it closing gracefully I get the Windows warning message 'HMI has stopped working'. Does anyone else get this?
No. I have closed the application with no warning message.
Title: Re: Using Nextion displays with Arduino
Post by: kn4ud on Jul 20, 2019, 06:26 pm
Well, it didn't take me long to find a bug in it! When I close it, instead of it closing gracefully I get the Windows warning message 'HMI has stopped working'. Does anyone else get this?
So far I have not had this happen.
Title: Re: Using Nextion displays with Arduino
Post by: orion555 on Jul 22, 2019, 11:22 am
Well, it didn't take me long to find a bug in it! When I close it, instead of it closing gracefully I get the Windows warning message 'HMI has stopped working'. Does anyone else get this?
I have the same problem. Doesn't seem to affect the file, but is a bit annoying. But I'm glade the came along with a reasonable update, since the fonts were, to phrase it polite and politically correct, not quite up to standard...

Since I'm already posting here, I have got a couple of questions as well. To mention it up front, I'm a hobbyist programmer (but an extremely stubborn one though ;-)) and relatively new to Arduino (couple of month) and an absolute beginner with Nextion (two weeks). Was a very stony way so far with partly rather blank nerves but I slowly start getting the desired results...

So here are the questions:

Do you, or anybody else out there, know how to address the new xFloat function (sending a float number to the Display)? Couldn't find anything in their instruction set and NexNumber doesn't seem to work. (solved it for now by converting it to .txt)

Sending data to the  MCU with a button function followed by a page change isn't working. Had to place two buttons, one to send the data and the second one to change the page. Almost drove me nuts before I figured out what the problem was. If I remember it correctly did you have the same or a similar problem. What was your solution. Preinitialize? If so, how does it work?

Regards
Title: Re: Using Nextion displays with Arduino
Post by: orion555 on Jul 22, 2019, 12:22 pm
If you mean you want to send new line to a Nextion text box then I think you are wasting your time, I don't think they support it. (If I am mistaken and you know for sure that they do support it then I'd like to know). As far as I know the text boxes treat all text as a single line. Where I have needed multiple lines of text I have used multiple text boxes.
I'm not sure if this answer is what you are looking for, but there is a function right below txt_maxl called 'isbr'. Set to true, it allows, if you expand the text box down,  at least text wrap. Not sure (haven't tried it myself) if it can be addressed directly from the MCU with a line break. Also not sure on how to address the new 'multiline' function from the outside.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 22, 2019, 10:01 pm

Quote
Do you, or anybody else out there, know how to address the new xFloat function (sending a float number to the Display)? Couldn't find anything in their instruction set and NexNumber doesn't seem to work. (solved it for now by converting it to .txt)
I cannot help with anything related to the Nextion libraries, although there are others on here who might be able to help with them.

I tried:

Code: [Select]
x0.val=4567
Which works.


Quote
Sending data to the  MCU with a button function followed by a page change isn't working. Had to place two buttons, one to send the data and the second one to change the page. Almost drove me nuts before I figured out what the problem was. If I remember it correctly did you have the same or a similar problem. What was your solution. Preinitialize? If so, how does it work?
Assuming you are using my methods look in the sample '2019-06-08 Arduino Nextion demo 43V1.zip' at the start of this tutorial; there are buttons to change the page. The button itself changes the page. On the new page under post initialisation event is the code to tell the Arduino that you have changed pages. The Arduino then responds with whatever data you want on the page. The reason for this is you have to change the page first, then wait for it to initialise then send whatever data you want on it. Putting the request to the Arduino for the data under post initialisation event guarantees that the page will be ready by the time that the data arrives. You can't have a button on page 0 that puts data on page 1 unless the variables on page 1 are global. The variables on page 1 are otherwise out of scope while page 1 is not displayed, so sending anything to page 1 from another page will not work. Sending data to a page before it has had chance to initialise will result in lost or errored data.

Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 22, 2019, 10:10 pm
Quote
I'm not sure if this answer is what you are looking for, but there is a function right below txt_maxl called 'isbr'. Set to true, it allows, if you expand the text box down,  at least text wrap. Not sure (haven't tried it myself) if it can be addressed directly from the MCU with a line break.
Yes, thanks, aware of that. I think what was being asked for was something that did new line within a text box. The old version certainly does not respond to anything with a new line, it just allows one long line of text which can scroll across multiple lines in the text box, but it is only a single line of text.


Quote
Also not sure on how to address the new 'multiline' function from the outside.
Me neither, please report back!

Oh, and ++Karma; for being so helpful and asking intelligent questions on your first visit to the forum.
Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on Jul 25, 2019, 02:38 am
My pleasure! Glad to be of help and I appreciate the feedback :)
I hate to bring back an old issue, but something I've just noticed (maybe the update changed something, or I've just not realized for this whole time):

When I send data in the fourth line of the serial out from the nextion (after index #) using "print t0.txt" or "print h0.val", and then I read it with HMI_read_data[4] and print it back out, I'm getting two digits that appear the same each time.

I have an h0 scrollbar with values from 500 to 5000, yet every time I print the value over the serial on release, I get a number between 41 and 53. Is this part of a hex code I'm not decoding properly? I'd like to convert it to a proper int.
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 25, 2019, 09:21 am
I've read that several times and I am not clear what you are doing. Can you give me both the code on the scroll bar and the corresponding code on the Arduino please?


Code: [Select]
HMI_read_data[4]
Is 1 byte. You need 2 bytes for a range of 500 to 5000.

My heating controller has sliders to control the temperature setting with a range of 0 to 300. That gives me 30 degrees range in steps of 0.1 degree (yes, I know, I probably should be using 0 to 299). That means that the data sent from the sliders takes 2 bytes. The section of code that takes the slider values and updates the set temperature is this:

Code: [Select]
case 1:
       zone[HMI_read_data[3]].settemp = (HMI_read_data[4] | HMI_read_data[5] << 8) * 0.1; //Note 1
       zone[HMI_read_data[3]].flags_HMI |= HMI_text_settemp_update; //Note 2
       break;

Note 1, this is the update for the temperature setting:
Code: [Select]
(HMI_read_data[4] | HMI_read_data[5] << 8)
Combines 2 bytes into one integer, which is the value of the slider setting. I think you need something similar.

Note 2, this is a flag to tell the rest of the program that there has been an update

Although not the cause of your problem, I suggest you don't use that range. I don't know which Nextion you are using, but the highest number of pixels in one direction is 800, so the maximum possible number of unique values from a slider is 800. Any more than that cannot be resolved on the display, so while you might get meaningful values with a slider with a range of 4500, there must, I presume, be gaps in the numbers.

While 500 to 5000 should work from a software point of view, my suggestion would be to use 0 to 4500 and add the 500 in on the Arduino.

In case you are interested, this is another way to combine 2 or more bytes into and integer, or split an integer into bytes, something like:

Code: [Select]
union {
  struct {
     uint8_t data_0;
     uint8_t data_1;
  }
  uint16_t data;
}


If you write to data_0 and data_1 the two bytes will appear in data as a 16 bit int, if you write a 16 bit int to data then you can read the corresponding 2 byes from data_0 and data_1. You can of course expand this for larger ints and for floats.

Title: Re: Using Nextion displays with Arduino
Post by: jtbennett on Jul 25, 2019, 10:42 pm
I used the version in your demonstration file, it worked perfectly - I don't know why I didn't catch that before - I probably got lucky the first time I did it because that slider only goes from 1 to 6.
Title: Re: Using Nextion displays with Arduino
Post by: orion555 on Jul 26, 2019, 12:49 am
Got a bit 'side tracked' in the endless world of coding... especially as a newbie, sometimes it can be quite humbling and overwhelming looking at all those doors opening up in front of one's continuously growing eyes...

In a severe fit of megalomania I tried to write, well, re-write the NexNumber lib to a NexFloat and ended up in a very deep rabbit hole. took me a while to find my way out again, but got it from an endless list of errors down to a couple... and slowly a slightly broader spectrum of to this never ending subject.

But it 's definitely my turn to pass the flowers to you, Perry, for the help you are providing here. Nice little hints you are passing on, especially the last ones I found quite interesting, since it sort of unlocked a whole lot of new possibilities and you deserve every bit of Karma you can get for things like that...

Was using the Nex's own libraries and was a bit too lacy to re-write all the work I finished so fart, with your sample code in your first postings (nicely done, by the way). But I came to the conclusion, well better rephrase that, I was lucky enough to get my fit under control... ;), and now I'm humbly going to use your code and hope I can get back to you, in case I don't get it straight...but all in all work is progressing, even if it isn't 'quite' as fast as I first thought it might happen...but I find if always very satisfying if things slowly start to do the things they should.

Knowing now that I'm at least capable of asking reasonable intelligent questions, I'm glad I found somebody who is helpful  enough to answer them. Thanks a lot for that. Hope I won't have to bother you too much.

I presume that other people on the 'big search' are passing by here as well, so I thought I might pass on a little helper to the Serial.print subject, simple enough that even I could have thought of it... :D, well, I didn't...but going to pass it on anyway, since it safes time and memory...

Code: [Select]


void nexDataSend() {
  Serial2.write(0xff);       // We always have to send this three lines after each command sent to the nextion display.
  Serial2.write(0xff);       //use the Serial(x) you are communicating with your Nex
  Serial2.write(0xff);
}



...and I find it quite handy, maybe it helps someone else as well.

will try my best to surface once in a while and pop by... ;)

kind regards
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Jul 26, 2019, 09:06 am
Thank you Orion, that makes helping you and others worthwhile :)
Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Aug 10, 2019, 11:31 am
I have added to part 4 'Nextion additional features', which brings several different things together in one place. Enjoy!
Title: Re: Using Nextion displays with Arduino
Post by: altitudeap on Sep 11, 2019, 05:01 am
@PerryBebbington et. all.  I posted this in another section but not sure it will get attention there.

I have not yet been successful in understanding the communication from the Nextion.  I have a few pages that are set up and I only need to capture the string that is sent when pages changes.  from this I will create a CASE statement and execute accordingly . 

For instance, when I am viewing the debug, and I am moving from page0 to page1, I get an simulator output (I am assuming I will see this as a serial string?) of  "65 00 02 01 FF FF FF"
So I have recorded all of these strings associated with the page movements and created a table of string, pulse and direction.  This will not be a high frequency event. (it is a shifter for a car)

Can I just use a simple serial program to read the string and then act upon the string in a CASE Statement? 
Thank you for any assistance you may be able to render.  I have some pictures but dont know how to or if I can post them

Title: Re: Using Nextion displays with Arduino
Post by: PerryBebbington on Sep 15, 2019, 12:34 pm
Hello altitudeap,
Sorry for the late reply, I have been on holiday :)


Quote
For instance, when I am viewing the debug, and I am moving from page0 to page1, I get an simulator output (I am assuming I will see this as a serial string?) of  "65 00 02 01 FF FF FF"
Yes, what you see in the simulator window is what is sent to the Nextion serial port. I would hesitate to call it a 'string' as that words has specific meaning in the C and C++ languages, and I don't think this data qualifies. Those bytes, as shown in the simulator window, will be send to the serial port.

It is clear from the rest of your question that you have not tried my examples as set out in this tutorial, the answers are in there. Try the examples, then come back when you need further explanation.