Nextion stops communicating

Good day, I am battling with a Nextion screen that is connected to a Aardbox Analog(Leonardo).

My problem is that the Nextion screen will update the variable that is send to the screen for a while and would the stop. I am using software serial on the MISO and CLK pins of the SPI bus. On my serial monitor I can see that the value of the variable is send to the screen, but not updating.I have also noticed that when this happens I can not read the data coming from the Nextion anymore, almost as if mySerial stops working.

My main loop is included as well as the read and write code to the Nextion.

Please assist me.

void loop() {
if(mySerial.available()) {
dfd+=char(mySerial.read());
NexRead();
}
//EmergencyButton();
Jog();
//ButtonCheck();
//LengteCheck();
Update();
//Feed = (SpeedInRPM*Circum)/1000;
//if(RunPhase == 1 && BatchGate == 0){
LengteCheck();
// }
}

The code for Updating to the screen:

void Update(){
static unsigned long SpamTimer;
if((millis() - SpamTimer) >= (250)) {
SpamTimer = millis();
mySerial.print("LUpdate.val="+ String(Length));
mySerial.write(0xff);
mySerial.write(0xff);
mySerial.write(0xff);
Serial.print(" LUpdate-");Serial.println(Length);
//Serial.print``(" Feed-");Serial.println(Feed);
mySerial.print("BUpdate.val="+ String(BUpdate));
mySerial.write(0xff);
mySerial.write(0xff);
mySerial.write(0xff);
//Serial.print``(" BUpdate-");Serial.print(BUpdate);
mySerial.print("SetBatch.val="+ String(SetBatch));
mySerial.write(0xff);
mySerial.write(0xff);
mySerial.write(0xff);
//Serial.print``(" SetBatch-");Serial.print(SetBatch);
mySerial.print("AdjustPer.val="+ String(AdjustPer*100)); //for HMI screen float
mySerial.write(0xff);
mySerial.write(0xff);
mySerial.write(0xff);
//Serial.print``(" AdjustPer-");Serial.println(AdjustPer);
mySerial.flush();
}
}

The code for extracting the data that is send from the screen:

void NexRead(){
if((dfd.substring(0,3)=="L&Q") && (dfd.length()==11)){ //Length and Quantity
Serial.println(dfd);
value.charByte[0] = char(dfd[3]);
value.charByte[1] = char(dfd[4]);
value.charByte[2] = char(dfd[5]);
value.charByte[3] = char(dfd[6]);
SetLength = (value.valLong); //Set Length
Serial.print(" SetLength-");Serial.println(SetLength);
value.charByte[0] = char(dfd[7]);
value.charByte[1] = char(dfd[8]);
value.charByte[2] = char(dfd[9]);
value.charByte[3] = char(dfd[10]);
SetBatch = (value.valLong); //Set Batch
Serial.print(" SetBatch-");Serial.println(SetBatch);
Serial.flush();
dfd="";
}
if((dfd.substring(0,3)=="S&D") && (dfd.length()==23)){ //Speeds and distances**
Serial.println(dfd);
value.charByte[0] = char(dfd[3]);
value.charByte[1] = char(dfd[4]);
value.charByte[2] = char(dfd[5]);
value.charByte[3] = char(dfd[6]);
RunPer = value.valLong; //Run percentage
Serial.print(" RunPer-");Serial.println(RunPer);
value.charByte[0] = char(dfd[7]);
value.charByte[1] = char(dfd[8]);
value.charByte[2] = char(dfd[9]);
value.charByte[3] = char(dfd[10]);
CrawlPer = value.valLong; //Crawl percentage
Serial.print(" CrawlPer-");Serial.println(CrawlPer);
value.charByte[0] = char(dfd[11]);
value.charByte[1] = char(dfd[12]);
value.charByte[2] = char(dfd[13]);
value.charByte[3] = char(dfd[14]);
InchPer = value.valLong; //Inch percentage
Serial.print(" InchPer-");Serial.println(InchPer);
value.charByte[0] = char(dfd[15]);
value.charByte[1] = char(dfd[16]);
value.charByte[2] = char(dfd[17]);
value.charByte[3] = char(dfd[18]);
InchDis = value.valLong; //Inch distance
Serial.print(" InchDis-");Serial.println(InchDis);
value.charByte[0] = char(dfd[19]);
value.charByte[1] = char(dfd[20]);
value.charByte[2] = char(dfd[21]);
value.charByte[3] = char(dfd[22]);
CrawlDis = value.valLong; //Crawl distance
Serial.print(" CrawlDis-");Serial.println(CrawlDis);
Serial.flush();
dfd="";
}
if((dfd.substring(0,3)=="CAL") && (dfd.length()==11)){ //Calibration*****
Serial.println(dfd);
value.charByte[0] = char(dfd[3]);
value.charByte[1] = char(dfd[4]);
value.charByte[2] = char(dfd[5]);
value.charByte[3] = char(dfd[6]);
SetLenCal = value.valLong; //Length of test run
Serial.print(" SetLenCal-");Serial.println(SetLenCal);
value.charByte[0] = char(dfd[7]);
value.charByte[1] = char(dfd[8]);
value.charByte[2] = char(dfd[9]);
value.charByte[3] = char(dfd[10]);
ActLenCal = value.valLong; //Actual length of test
Serial.print(" ActLenCal-");Serial.println(ActLenCal);
Serial.flush();
dfd="";
}
if((dfd.substring(0,3)=="P&D") && (dfd.length()==11)){ //******Pulse and distance
Serial.println(dfd);
value.charByte[0] = char(dfd[3]);
value.charByte[1] = char(dfd[4]);
value.charByte[2] = char(dfd[5]);
value.charByte[3] = char(dfd[6]);
PulsePerRev = value.valLong; //PPR of the encoder
Serial.print(" PulsePerRev-");Serial.println(PulsePerRev);
value.charByte[0] = char(dfd[7]);
value.charByte[1] = char(dfd[8]);
value.charByte[2] = char(dfd[9]);
value.charByte[3] = char(dfd[10]);
MMPerPulse = (value.valLong)/100;
Serial.print(" MMPerPulse-");Serial.println(MMPerPulse);
Serial.flush();
dfd="";
}
if((dfd.substring(0,3)=="CPR") && (dfd.length()==3)){
Serial.println(dfd);
Calibration();
Serial.flush();
dfd="";
}
}

Thanks

I know that this is not your fault (but a bug in the forum software) but next time please use edit → copy for forum and paste it here in a reply.

And that next time is now :wink: Please post your complete code.

Why do you use SoftwareSerial on a Leonardo; the Leonardo has a serial port that is independent of the USB interface.

Hi Sterretje, I will repost my code, but I have four tabs. I will paste them after one another. The reason I am using the Software serial is because of the fact that the Leonardo is inside the PLC and I am not too familiar with it. There is a RS-232 port on the PLC but I am not sure what the voltage of the port is as the Nextion is apparently very sensitive to voltages.

Main code:

#include <SoftwareSerial.h>
/*------------------Encoder----------------------*/
//-------------------Pins-------------------------
#define ClockPin I0_0                                          
#define DataPin I0_1                                           
#define Multiplier 60000.0                                     
volatile long EncoderCounter = 0;
long    Counter = 0;
volatile float SpeedInRPM = 0;

/*------------------CONTROLS----------------------*/
//-------------------Feeder------------------------
//-------------------Inputs------------------------
#define InForward     I0_5         //Digital pin for direction forward
#define InReverse     I0_4         //Digital pin for direction reverse
#define InStartStop   I0_6         //Digital pin for direction start/stop
#define Emergency     I0_9         //Digital pin for emergency
//-------------------Output------------------------
#define Run           Q0_0         //Digital output pin for direction forward
#define Dir           Q0_1         //Digital output pin for direction reverse
#define Speed         A0_6         //Analog out for speed
//-------------------Cutter------------------------
#define CutterPin     I0_7         //Input pin to activate cutter
#define CutOut        Q0_3         //Output pin to activate cutter

bool     buttonState;               // the current reading from the input pin
int     lastButtonState = LOW;     // the previous reading from the input pin
unsigned long lastDebounceTime = 0;// the last time the output pin was toggled
unsigned long debounceDelay = 1000;// the debounce time; increase if the output
unsigned long LastCutTime = 0;     // the last time the output pin was toggled
unsigned long CutDelay = 2500;     // the debounce time; increase if the output
bool    RunPhase;
bool    ButtonGate = 0;
bool    CutGate = 0;

/*----------------Calculations------------------*/
//------------Length to go and speeds--------------
float   Length =      0;
float   Circum =      565.48;
int     RunSpeed =    255;
bool    LengthGate =  0; 
bool    EmGate =      0;
bool    BatchGate =   0;
bool    RunState =    0;
boolean         newButtonState;
static boolean  oldButtonState = false;

//--------------------Data from Nextion------------
float   MMPerPulse;
int     ActLenCal;
int     SetLength;
int     SetBatch;
float   RunPer =      50;
float   InchPer =     10;
float   CrawlPer =    05;
int     InchDis =     1000;
int     CrawlDis =    500;
int     SetLenCal =   1000;
int     PulsePerRev = 1000;

//---------------------Data to Nextion--------------
float   LUpdate =     0;
int     BUpdate =     0;
int     AdjustPer;
int     AdjustMM;
float   StepsPerMM;
float   MMPerRev;
static unsigned long SpamTimer;   

void onPin2CHANGECallBackFunction(uint32_t Time, uint32_t PinsChanged, uint32_t Pins){ 
  static uint32_t lTime;                     // Saved Last Time of Last Pulse
  uint32_t cTime;                            // Current Time
  cTime = micros();                          // Store the time for RPM Calculations
  int32_t dTime;                             // Delta in time
  // Encoder Code
  bool DataPinVal = digitalRead(DataPin);
  EncoderCounter += (DataPinVal) ? 1 : -1;                   
  // calculate the DeltaT between pulses
  dTime = cTime - lTime; 
  lTime = cTime;
  SpeedInRPM = Multiplier / ((DataPinVal) ? dTime: (-1 * dTime)); // Calculate the RPM Switch DeltaT to either positive or negative to represent Forward or reverse RPM
}

SoftwareSerial mySerial(14,15);             // RX, TX pins for 15,14

union{
  char charByte[4];
  long valLong;
}value;

String dfd = "";

void setup() {
  Serial.begin(9600);
  pinMode(ClockPin,     INPUT);  
  pinMode(DataPin,      INPUT);
  pinMode(InForward,    INPUT);
  pinMode(InReverse,    INPUT); 
  pinMode(InStartStop,  INPUT);
  pinMode(CutterPin,    INPUT);
  pinMode(Speed,        INPUT);
  pinMode(Emergency,    INPUT);
  pinMode(CutOut,       OUTPUT);
  pinMode(Run,          OUTPUT);
  pinMode(Dir,          OUTPUT); 
  attachInterrupt(digitalPinToInterrupt(ClockPin),onPin2CHANGECallBackFunction,RISING);
  Serial.println("Welcome to FreeStock Mini Cut-to-length!");
  mySerial.begin(9600);
} 

void loop() {
  if(mySerial.available()) {
    dfd+=char(mySerial.read());
    NexRead();
  }
  //EmergencyButton();
  Jog();
  //ButtonCheck();
  //LengteCheck();
  Update();                                                           
  //Feed = (SpeedInRPM*Circum)/1000;
  //if(RunPhase == 1 && BatchGate == 0){
  LengteCheck();
 // }
}

Functions:

void LengthToGo(){
  long TargetLength = SetLength - Length;
  int FSpeed;
  if((TargetLength - CrawlDis) < Length && LengthGate == 0){
    FSpeed = (RunSpeed*CrawlPer)/100;
    digitalWrite(Dir,HIGH);
    digitalWrite(Run,HIGH);
    analogWrite(Speed,FSpeed);
    Serial.print(" Crawl-");Serial.print(FSpeed);Serial.print(" Length-");Serial.println(Length);
    Update();  
    LengthGate = 1;
  }else if((TargetLength - InchDis) < Length && LengthGate == 1){
    FSpeed = (RunSpeed*InchPer)/100;
    digitalWrite(Dir,HIGH);
    digitalWrite(Run,HIGH);
    analogWrite(Speed,FSpeed);
    Serial.print(" Inch-");Serial.print(FSpeed);Serial.print(" Length-");Serial.println(Length);
    Update();  
  }else if(Length >= SetLength){
    analogWrite(Speed,0);
    digitalWrite(Dir,LOW);
    digitalWrite(Run,LOW);
    Serial.print(" On Length-");Serial.println(Length);
    //CUT();
    //Update();
    delay(1000);
    //BatchCheck();  
  } 
}

void LengteCheck(){
  Counter = EncoderCounter;
  Length = (Counter*(Circum/PulsePerRev))+(Counter*((Circum/PulsePerRev)*AdjustPer));
}

void Calibration(){
   float i;
   if(SetLenCal > ActLenCal){
     i =  (((float)SetLenCal-(float)ActLenCal)/SetLenCal);
     AdjustPer = i;   
  }else{
     i = (((float)ActLenCal-(float)SetLenCal)/SetLenCal);
     AdjustPer = i*-1;            //Not tested on screen  
  }
}


void EmergencyButton(){
if(digitalRead(Emergency) == LOW && EmGate == 0){
    mySerial.print("page page5");
    mySerial.write(0xff);
    mySerial.write(0xff);
    mySerial.write(0xff);
    EmGate = 1;
    Counter = 0;
    EncoderCounter = 0;
    digitalWrite(CutOut,LOW);
    digitalWrite(Dir,LOW);
    digitalWrite(Run,LOW);
    analogWrite(Speed,0);
  }else if(digitalRead(Emergency) == HIGH && EmGate == 1){
    mySerial.print("page page1");
    mySerial.write(0xff);
    mySerial.write(0xff);
    mySerial.write(0xff);
    EmGate = 0;
  }
}

void ButtonCheck(){
  //int reading = digitalRead(InStartStop);
  if(digitalRead(InStartStop) == HIGH && ButtonGate == 0){
    ButtonGate = 1;
    lastDebounceTime = millis();
  }
  if((lastDebounceTime + debounceDelay) < millis() && ButtonGate == 1){
    buttonState = !buttonState;
    //lastDebounceTime = millis();
    ButtonGate = 0;
    RunPhase = 1;
    //Serial.print(" BatchGate-");Serial.print(BatchGate);Serial.print(" RunPhase-");Serial.print(RunPhase);Serial.print(" State-");Serial.println(buttonState);
  }
  if(digitalRead(CutterPin) == HIGH && CutGate == 0){
    CutGate = 1;
    LastCutTime = millis();
    digitalWrite(CutOut,HIGH);
  }
  if((LastCutTime + CutDelay) < millis() && CutGate ==1){
    digitalWrite(CutOut,LOW);
    CutGate = 0;
  }
}

Nextion write:

void Update(){
 
  if((millis() - SpamTimer) >= (250)) {
   SpamTimer = millis();
   mySerial.print("LUpdate.val="+ String(Length));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   Serial.print(" LUpdate-");Serial.println(Length);
   //Serial.print(" Feed-");Serial.println(Feed);
   mySerial.print("BUpdate.val="+ String(BUpdate));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   //Serial.print(" BUpdate-");Serial.print(BUpdate);
   mySerial.print("SetBatch.val="+ String(SetBatch));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   //Serial.print(" SetBatch-");Serial.print(SetBatch);
   mySerial.print("AdjustPer.val="+ String(AdjustPer*100));       //for HMI screen float
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   //Serial.print(" AdjustPer-");Serial.println(AdjustPer);
   mySerial.flush();
  }
}

Nextion Read:

void NexRead(){
  if((dfd.substring(0,3)=="L&Q") && (dfd.length()==11)){                  //Length and Quantity
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    SetLength = (value.valLong);                                         //Set Length 
    Serial.print(" SetLength-");Serial.println(SetLength);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    SetBatch = (value.valLong);                                         //Set Batch
    Serial.print(" SetBatch-");Serial.println(SetBatch);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="S&D") && (dfd.length()==23)){                //*************Speeds and distances***************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    RunPer = value.valLong;                                             //Run percentage
    Serial.print(" RunPer-");Serial.println(RunPer);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    CrawlPer = value.valLong;                                           //Crawl percentage
    Serial.print(" CrawlPer-");Serial.println(CrawlPer);
    value.charByte[0] = char(dfd[11]);
    value.charByte[1] = char(dfd[12]);
    value.charByte[2] = char(dfd[13]);
    value.charByte[3] = char(dfd[14]);
    InchPer = value.valLong;                                            //Inch percentage
    Serial.print(" InchPer-");Serial.println(InchPer);
    value.charByte[0] = char(dfd[15]);
    value.charByte[1] = char(dfd[16]);
    value.charByte[2] = char(dfd[17]);
    value.charByte[3] = char(dfd[18]);
    InchDis = value.valLong;                                            //Inch distance
    Serial.print(" InchDis-");Serial.println(InchDis);
    value.charByte[0] = char(dfd[19]);
    value.charByte[1] = char(dfd[20]);
    value.charByte[2] = char(dfd[21]);
    value.charByte[3] = char(dfd[22]);
    CrawlDis = value.valLong;                                           //Crawl distance
    Serial.print(" CrawlDis-");Serial.println(CrawlDis);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="CAL") && (dfd.length()==11)){                //***************Calibration********************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    SetLenCal = value.valLong;                                          //Length of test run
    Serial.print(" SetLenCal-");Serial.println(SetLenCal);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    ActLenCal = value.valLong;                                          //Actual length of test
    Serial.print(" ActLenCal-");Serial.println(ActLenCal);
    Serial.flush();
    dfd="";   
  }
  if((dfd.substring(0,3)=="P&D") && (dfd.length()==11)){                //*********************Pulse and distance***************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    PulsePerRev = value.valLong;                                        //PPR of the encoder
    Serial.print(" PulsePerRev-");Serial.println(PulsePerRev);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    MMPerPulse = (value.valLong)/100;
    Serial.print(" MMPerPulse-");Serial.println(MMPerPulse);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="CPR") && (dfd.length()==3)){
    Serial.println(dfd);
    Calibration();
    Serial.flush();
    dfd="";
  }
}

Maths:

void LengthToGo(){
  long TargetLength = SetLength - Length;
  int FSpeed;
  if((TargetLength - CrawlDis) < Length && LengthGate == 0){
    FSpeed = (RunSpeed*CrawlPer)/100;
    digitalWrite(Dir,HIGH);
    digitalWrite(Run,HIGH);
    analogWrite(Speed,FSpeed);
    Serial.print(" Crawl-");Serial.print(FSpeed);Serial.print(" Length-");Serial.println(Length);
    Update();  
    LengthGate = 1;
  }else if((TargetLength - InchDis) < Length && LengthGate == 1){
    FSpeed = (RunSpeed*InchPer)/100;
    digitalWrite(Dir,HIGH);
    digitalWrite(Run,HIGH);
    analogWrite(Speed,FSpeed);
    Serial.print(" Inch-");Serial.print(FSpeed);Serial.print(" Length-");Serial.println(Length);
    Update();  
  }else if(Length >= SetLength){
    analogWrite(Speed,0);
    digitalWrite(Dir,LOW);
    digitalWrite(Run,LOW);
    Serial.print(" On Length-");Serial.println(Length);
    //CUT();
    //Update();
    delay(1000);
    //BatchCheck();  
  } 
}

void LengteCheck(){
  Counter = EncoderCounter;
  Length = (Counter*(Circum/PulsePerRev))+(Counter*((Circum/PulsePerRev)*AdjustPer));
}

void Calibration(){
   float i;
   if(SetLenCal > ActLenCal){
     i =  (((float)SetLenCal-(float)ActLenCal)/SetLenCal);
     AdjustPer = i;   
  }else{
     i = (((float)ActLenCal-(float)SetLenCal)/SetLenCal);
     AdjustPer = i*-1;            //Not tested on screen  
  }
}

I will look into the Leonardo and see if I can figure out what other serial I can use.

A few of those and your precious 2.5k or RAM on your Leonardo will soon get used up! On a bvoard like the Leonardo, please do use the F macro to store character array constants in program memory:

`Serial.println(F("Welcome to FreeStock Mini Cut-to-length!"));`

As a matter or curiousity, how much dynamic memory do you have left after compiling?

Since dfd is defined as type String, then this:

could just be:

SetLength = dfd.substring(3,7).toLong():

and the second block:

SetBatch = dfd.substring(7).toLong();

The conversion to a long value by using a union to map numeric characters to a variable of type long does not appear to be valid unless the characters are bytes representing a 32-bit value and the Endianness matches. However, since dfd is being printed "as is" to be viewed, one concludes that its just a character string, in which case the extracted characters would need to be stored as a null terminated character array and then converted to a numeric value by being passed to atol() or strtol(). But since dfd is a String type there is no need to go to such lengths.

Should be 250UL just to make it clear to the compiler.

My problem is that the Nextion screen will update the variable that is send to the screen for a while and would the stop. I am using software serial on the MISO and CLK pins of the SPI bus. On my serial monitor I can see that the value of the variable is send to the screen, but not updating.I have also noticed that when this happens I can not read the data coming from the Nextion anymore, almost as if mySerial stops working.

You are clearly having issues with the reliability of software serial and switching to hardware serial on Serial1 (pins 0,1) on the Leonardo should be beneficial.

Using the Aardbox puts you in a difficult situation.

https://docs.rs-online.com/6303/0900766b81690c05.pdf

However, check out the section on Page 10 relating to Left Side configuration switches would indicate that you can get direct i/o connection to the Serial1 pins 0 and 1.

If you can work with technical support from the Industrial Shields manufacturer of the Ardbox it would be helpful.

Hi BitSeeker, thanks for the reply. This code is from a tutorial on the Nextion screen I copied and modified to suit my needs, not sure how it works. The screen sends data as ASCII codes.

My knowledge on these screens is zero.

But the problem is not on the recieving side, this part of the code works.

Hi Cattledog, thanks. The one I am using is a bit different,

https://www.mouser.lt/pdfDocs/ArdboxAnalogHFUserGuide.pdf?srsltid=AfmBOop1wUHtkdnXBcsUzQVP3vrmCiiXtMVR-fmBrvgb-QLaCgeZNWU_

I will try to setup Gpio0/1 as hardware serial and see if that improves.

I found this on the Industrial screen website.

https://www.industrialshields.com/forum/help-1/serial-ttl-on-ardbox-relay-100

I am almost confident that the plc is sending the data to the screen, so it might be a Nextion issue?

In my experience, with Nextions, I have never had one become unresponsive like you are describing. That is, the Nextion works perfectly for a while and then takes a nap.

is send to the screen for a while and would the stop.

I am almost confident that the plc is sending the data to the screen

How do you know this? Do you have a scope on the Tx line?

Is there possibly a page issue where your code is not setting the Nextion to the page where you are trying to write/read values?

Given that the Leonardo keeps functioning with Serial output, it is not the use of Strings which is causing failure through a loss of memory.

If Industrial Shields says that you can not configure the inputs to get direct access to Serial1, perhaps you can try the RS - 232 to Serial TTL convertor route. Is your project using the RS232 for something else?

One other thing to try would be to use AltSoftSerial instead of the standard Software Serial.

It is available through the Library Manager. For the Leonardo, it uses pin5 as the Tx and 13 as the Rx.

Good day,

I am having issues with a Nextion screen hooked up to a ESP32 Wroom. I’ve got the screen connected to hardware serial 2. I can recieve data from the screen and am able to use the data in my coding. I can also print/write to the screen and update display values.

I am busy with the software of a cut to length machine. This machine de-coils thin steel plate coils and measures the distance de-coiled by means of an encoder. The user enters a distance on the screen which is send to the ESP for processing. There are other user define input on the screen as well that are updated, either by pressing a button or upon exiting the page, like feed rate etc, and the distance uncoiled is updated back to the Nextion display.

The problem I am stuck with is, if I use these functions simultaneously, the data from the screen to the ESP stops flowing if you flip through the pages. If I comment out the Update function, the data flows.

I checked it with my scope, if the update command is active, the screen sends out data without any intervention from the user at random intervals.

Below is the data bit that comes through, I can not read it, maybe you might find a clue in it.

WhatsApp Image 2026-01-04 at 11.25.20 (1)

WhatsApp Image 2026-01-04 at 11.25.20 (1)960×1280 127 KB

This is one of the intervals at which it happens, but as stated, they are random.

WhatsApp Image 2026-01-04 at 11.29.46

WhatsApp Image 2026-01-04 at 11.29.46720×1280 135 KB

I am adding my Main code:

#include "Adafruit_SHT31.h" 
#include <Wire.h>

#define ClockPin 14                                          
#define DataPin 12                                           

volatile long EncoderCounter = 0;
volatile float SpeedInRPM = 0;

/*-----------------CONTROLS----------------------*/
//-----------------Feeder------------------------
//#define Speed                 //Analog out for speed
#define OutForward 26           //Digital pin for direction forward
#define OutReverse 27           //Digital pin for direction reverse
#define InForward 35            //Digital pin for direction forward
#define InReverse 32            //Digital pin for direction reverse
#define InStartStop 34          //Digital pin for direction start/stop
//------------------Cutter-----------------------
# define CutterPin 2            //Pin to activate cutter
# define BladeHome 33           //Home sensor of the blade pin
//------------------Recoiler---------------------
# define Actuate 4              //Decoiler open and close pin

/*-----------------Calculations------------------*/
//-----------------Length to go and speeds-------------------
int Length = 0;
float Feed;
float Circum = 556.48;
long Counter;
int RunSpeed = 255; 

/*------------------Nextion--------------------------------*/
HardwareSerial mySerial(2);
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;              // interval at which to blink (milliseconds)
//Data from Nextion
int SetLength;
int SetBatch;
float RunPer = 0.50;
float InchPer = 0.10;
float CrawlPer = 0.05;
int InchDis = 500;
int CrawlDis = 100;
int SetLenCal = 1000;
int ActLenCal;
int PulsePerRev = 1000;
float MMPerPulse;

//Data to Nextion
float LUpdate = 0;
int BUpdate = 0;
int AdjustPer;
int AdjustMM;
float StepsPerMM;
float MMPerRev;

union{
  char charByte[4];long valLong;
  }value;

String dfd = "";

void ARDUINO_ISR_ATTR onPin2CHANGECallBackFunction(){ 
    bool DataPinVal = digitalRead(DataPin);
    EncoderCounter += (DataPinVal) ? 1 : -1;                    // Should we step up or down?
    Counter = EncoderCounter;
}

Adafruit_SHT31 sht31 = Adafruit_SHT31();


void setup() {
  Serial.begin(9600);
  Wire.begin(21,19);
  pinMode(ClockPin, INPUT);  
  pinMode(DataPin, INPUT);
  attachInterrupt(ClockPin, onPin2CHANGECallBackFunction, RISING);
  while(!Serial){
    ; 
  }
  Serial.println("Goodnight moon!");
  mySerial.begin(9600, SERIAL_8N1, 17, 16);
  if (! sht31.begin(0x44)) {   // Set to 0x45 for alternate i2c addr
      Serial.println("Couldn't find SHT31");
  }
} 

void loop() { // run over and over
  if (mySerial.available()) {
    dfd+=char(mySerial.read());
    NexRead();
  }
  if (millis() - previousMillis >= interval) {
    previousMillis = millis();
    I2CRead();
    ScreenUpdate();
    //noInterrupts ();                                                            
    //Counter = EncoderCounter;
    //interrupts ();
  }
}

void SerialUpdate(){
 static unsigned long SpamTimer;
  if ( (unsigned long)(millis() - SpamTimer) >= interval) {
    SpamTimer = millis();
    Serial.print(Length ,2);
    Serial.print(" mm ");
    Serial.print(Feed , 1);
    Serial.print(" m/Min ");
    Serial.print(Counter);
    //Serial.print(" m/Min");
    SpeedInRPM = 0; // if no pulses occure in the next 100 miliseconds then we must assume that the motor has stopped
  } 
}

void I2CRead(){
  float t = sht31.readTemperature();
  float h = sht31.readHumidity();
  if (! isnan(t)) {  // check if 'is not a number'
    //Serial.print("Temp *C = "); Serial.println(t);
  }
  else {    
    t=0.0;
    Serial.println("Failed to read temperature");
  }
  if (! isnan(h)) {  // check if 'is not a number'
    //Serial.print("Hum. % = "); Serial.println(h);
  }
  else { 
    h=0.0;
    Serial.println("Failed to read humidity");    
  }
  Length = t*100;
  BUpdate = h*100;
}


Here is the update function:

void ScreenUpdate(){
  //if((millis() - SpamTimer) >= (250)) {
  //SpamTimer = millis();
   mySerial.print("LUpdate.val="+ String(Length));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   //Serial.print(" LUpdate-");Serial.print(Length);
   mySerial.print("BUpdate.val="+ String(BUpdate));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   //Serial.print(" BUpdate-");Serial.print(BUpdate);
   /*mySerial.print("SetBatch.val="+ String(SetBatch));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   Serial.print(" SetBatch-");Serial.print(SetBatch);
   mySerial.print("AdjustPer.val="+ String(AdjustPer*100));       //for HMI screen float
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   Serial.print(" AdjustPer-");Serial.println(AdjustPer);
   mySerial.print("n0.val="+ String(Length));
   mySerial.write(0xff);
   mySerial.write(0xff);
   mySerial.write(0xff);
   Serial.print(" n0-");Serial.print(Length);*/
}


Here is the reading function:

void NexRead(){
  if((dfd.substring(0,3)=="L&Q") && (dfd.length()==11)){                  //Length and Quantity
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    SetLength = (value.valLong);                                         //Set Length 
    Serial.print(" SetLength-");Serial.println(SetLength);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    SetBatch = (value.valLong);                                         //Set Batch
    Serial.print(" SetBatch-");Serial.println(SetBatch);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="S&D") && (dfd.length()==23)){                //*************Speeds and distances***************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    RunPer = value.valLong;                                             //Run percentage
    Serial.print(" RunPer-");Serial.println(RunPer);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    CrawlPer = value.valLong;                                           //Crawl percentage
    Serial.print(" CrawlPer-");Serial.println(CrawlPer);
    value.charByte[0] = char(dfd[11]);
    value.charByte[1] = char(dfd[12]);
    value.charByte[2] = char(dfd[13]);
    value.charByte[3] = char(dfd[14]);
    InchPer = value.valLong;                                            //Inch percentage
    Serial.print(" InchPer-");Serial.println(InchPer);
    value.charByte[0] = char(dfd[15]);
    value.charByte[1] = char(dfd[16]);
    value.charByte[2] = char(dfd[17]);
    value.charByte[3] = char(dfd[18]);
    InchDis = value.valLong;                                            //Inch distance
    Serial.print(" InchDis-");Serial.println(InchDis);
    value.charByte[0] = char(dfd[19]);
    value.charByte[1] = char(dfd[20]);
    value.charByte[2] = char(dfd[21]);
    value.charByte[3] = char(dfd[22]);
    CrawlDis = value.valLong;                                           //Crawl distance
    Serial.print(" CrawlDis-");Serial.println(CrawlDis);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="CAL") && (dfd.length()==11)){                //***************Calibration********************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    SetLenCal = value.valLong;                                          //Length of test run
    Serial.print(" SetLenCal-");Serial.println(SetLenCal);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    ActLenCal = value.valLong;                                          //Actual length of test
    Serial.print(" ActLenCal-");Serial.println(ActLenCal);
    Serial.flush();
    dfd="";   
  }
  if((dfd.substring(0,3)=="P&D") && (dfd.length()==11)){                //*********************Pulse and distance***************
    Serial.println(dfd);
    value.charByte[0] = char(dfd[3]);
    value.charByte[1] = char(dfd[4]);
    value.charByte[2] = char(dfd[5]);
    value.charByte[3] = char(dfd[6]);
    PulsePerRev = value.valLong;                                        //PPR of the encoder
    Serial.print(" PulsePerRev-");Serial.println(PulsePerRev);
    value.charByte[0] = char(dfd[7]);
    value.charByte[1] = char(dfd[8]);
    value.charByte[2] = char(dfd[9]);
    value.charByte[3] = char(dfd[10]);
    MMPerPulse = (value.valLong)/100;
    Serial.print(" MMPerPulse-");Serial.println(MMPerPulse);
    Serial.flush();
    dfd="";
  }
  if((dfd.substring(0,3)=="CPR") && (dfd.length()==3)){
    Serial.println(dfd);
    //Calibration();
    Serial.flush();
    dfd="";
  }
}

If would really appreciate your help as I am not sure where to post on the forum and where to look for other help.

Kindest regards

Charles de Bruin