Go Down

Topic: Using Nextion displays with Arduino (Read 47147 times) previous topic - next topic

PerryBebbington

#75
Jan 18, 2020, 07:39 pm Last Edit: Jan 18, 2020, 08:42 pm by PerryBebbington
Quote
I don't know why, but the display is not actually showing the clock value, however I am able to see the functionality of all the buttons, the slider, and the page concepts. I am guessing it has something to do with the fact I have an Arduino Uno, and am using one of the Basic displays, but I am not positive.
I would not expect that using a basic display would cause a problem, I was careful to design the code to use the minimum of the resources available on a Nextion and everything in this tutorial has been tested on a NX4827T043, which is one of the basic Nextion displays.

A Uno might be a problem as the only serial port is the one used for the USB connection to your PC, so using it for connection to a Nextion (or anything else) means you have 2 different serial connections fighting each other. I did originally test everything using a Uno and I didn't find any problems, however, given that, theoretically at least, there might be problems I have not stated in the introduction that any of this works with a Uno. For changes to this tutorial I mostly test on a Mega, and sometimes on an MKR1010.

Quote
One side note: The Nextion website lists print to be depreciated and it looks like it will add a length attribute, but it seems you can limit the number of bytes sent as well.
Thanks, I didn't notice that, I appreciate you pointing it out. I have updated the demonstration files to use prints, which I see replaces print. If you find I've missed any please tell me (I think I only used print for the scroll bar, but there's always the possibility I used it elsewhere and forgot!)
++Karma;

DRE50

I have a question? where do i set what RX TX port im using with my mega2560? i cant seem to find the info.

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

If im using serial port 2 then do i put Serial2.begin(9600) in my code? or am i missing something?
thanks

PerryBebbington

If im using serial port 2 then do i put Serial2.begin(9600) in my code? or am i missing something?
thanks
Yes, correct. You also need to go through the code and change every instance of Serial1 to Serial2.

Squid171

Hello Perry,

I recently tried contacting you about an issue with this project that I am experiencing and you told me to post it on the forum. I have tried that 3 separate times and even after following the the forum guidelines it keeps having errors and not posting so I am just going to post it here.

I am fairly new at using both Arduino and Nextion displays so I tried looking online for tutorials about how other people have made them work together. Most of these tutorials have use of the Nextion library so I have tried multiple uses of that but none of them worked quite right. The board and display would not communicate. So I finally found your demonstration about how to do this without the library and it seemed much more simple and made more sense to me. But since I was frustrated with not getting these devices to communicate together I just used your code (Nextion_demonstration43) and displays for starters so that I could change things around once I everything communicating.

The only difference between your display and mine is that mine is the 10.1" so when I loaded your screens onto it they stayed in the upper left corner. Not an issue when you're just trying t make something work. The code however was slightly changed but only by changing the serial port used like you had said to do. Since my board is an Arduino Uno I do not have any extra ports so I have to use pins 0 and 1. I had seen on other tutorials that people have made this work by loading the sketch to the board with the RX and TX of the HMI disconnected and then unplugging the board from the computer and powering it with an external power supply and reconnecting the RX and TX  to the TX and RX of the board. I did this and most of the program seemed to work like the messages "This is page 0" and "Please do not press this button again", the hex and decimal values for the slider on page 1 even read. But the clock on page 0 remains at "hh: mm: ss" with not number values there.

I guess my question is if there is a different way of using serial communication with my Uno or if I need an Arduino Mega? And are there any errors in my code that I missed? Like I said all I changed were the comm. ports but then it should have worked. Any help would be greatly appreciated.

Squid171

Sorry this would not send as one piece...

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.
  Serial.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);
  Serial.print(F("t1.txt=\""));
  Serial.print(timestring);
  Serial.print("\"");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

//This displays the page number
void HMI_display_page(uint8_t page) {
  Serial.print(F("t0.txt=\""));
  Serial.print(F("This is page "));
  Serial.print(page);
  Serial.print(F("\""));
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.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
  Serial.print(F("t2.txt=\""));
  Serial.print(slider_d1, HEX);
  Serial.print(F("\""));
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
 
  //This displays byte 0 of the slider value in HEX
  Serial.print(F("t3.txt=\""));
  Serial.print(slider_d0, HEX);
  Serial.print(F("\""));
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

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

void HMI_startup_message() {
  Serial.print(F("t0.txt=\""));
  Serial.print(F("Nextion demonstration by Perry Bebbington. For support go to https://forum.arduino.cc/index.php?board=7.0"));
  Serial.print(F("\""));
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.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 (Serial.available() > 0) {         //Read every byte in the receive buffer
    readtemp = Serial.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();
  }
}

PerryBebbington

#80
Mar 28, 2020, 07:15 pm Last Edit: Mar 28, 2020, 07:17 pm by PerryBebbington
Hello,

I would expect you to have problems using a Uno to communicate with a Nextion because the serial port is already in use communicating with the USB connection. The Uno schematic shows 1k Ohm resistors in series with the connection between the ATmega328 and then CH340 that controls the USB connection, so you might be able to get it working on the serial port, but this seems like a bit of a bodge to me. If it works then fine, it works. If not then yes, I suggest buying an Arduino with a spare serial port, such as a Mega. However, if you have some features of my code working that suggests the problem is not the serial port.

Quote
And are there any errors in my code that I missed?
I'm not sure how you expect me to answer that with code I cannot see....!  :smiley-confuse:

You need to find every single instance of Serial1.something and change it to Serial.something. Miss one and it won't work. If you are not seeing the clock then I guess you missed one in the function void HMI_display_clock();


[EDIT] You had not posted your code when I typed the above....
Also, my dinner is ready, back later :)

PerryBebbington

In the function:
Code: [Select]
//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);
  Serial.print(F("t1.txt=\""));
  Serial.print(timestring);
  Serial.print("\"");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}


Is the line
Code: [Select]
  Serial.println(timestring);
Which sends the time to the serial monitor. When HMI_display_clock is used as intended, with the Nextion on serial port 1, this line doesn't matter. When you connect the Nextion to the serial port monitor then this line makes a mess of the data sent to the Nextion. You need to comment out that line then it will work, like this:

Code: [Select]
//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);
  Serial.print(F("t1.txt=\""));
  Serial.print(timestring);
  Serial.print("\"");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

Squid171

Thank you that worked! The clock is now counting and everything appears to be communicating properly. And it appears that the dimming of the screen is 100% controlled by the program in the HMI and has nothing to do with the arduino code... Is that correct?

Thank you again.

PerryBebbington

It appears that the dimming of the screen is 100% controlled by the program in the HMI and has nothing to do with the Arduino code... Is that correct?
Yes, the screen dimming is on the Nextion, I leave you to discover how it works.

PerryBebbington

#84
Mar 29, 2020, 12:04 am Last Edit: Apr 15, 2020, 12:28 pm by PerryBebbington
I have now asked the moderators to lock this topic as there are enough questions and answers to cover most things.

Please do not send me a PM with questions about this tutorial or Nextion displays in general, I will just reply telling you to use the forum.

If you have a question about either this tutorial or about your project that includes a Nextion display then read General guidance and
How to use this forum
And start a new question in the appropriate forum.


Go Up