Nextion keyboard and button spam causes arduino to freeze

Greetings

I struggle with a project and so far, this forum could help me indirectly in many ways. For this particular problem, i sadly have not found a solution yet, that's why I'm asking for your help directly.

I use a Nextion Enhanced together with an Arduino Uno. The goal is to send all second some sensor values to the Nextion, as well as using the Nextion to give some thresholds and to define a name for the logfile. More has to follow, but is not relevant for this problem.
The thresholds can be changed with the qwerty keyboard on the Nextion. When i'm done, i can send the data to the Arduino with an update button that prints the values.
One button sets the new thresholds, one sets the new logfile name, and one let me toggle the onboard led.

My problem is that as soon as i open the Nextion keyboard, or when i press a button repeatedly , the arduino freezes. While the Nextion still works, the arduino does nothing. The led wont toggle, the data which is sent all second will not be send, and the textfields for those datapoints will show "newtxt".
If i look at the message received at those moments, it just shows some rectangles in the serial monitor. I wasn't able to find the problem with the nextion editor debug as well, but i use this software only since 4 days and i'm still unfamiliar with it.
I guess it is a problem with the serial communication, but i'm not sure...

I truly hope you are able to help me, and thank you kindly for your support.
Best regards
Just some random mad scientist

Here is my code so far:

/* 
Arduino to Nextion Display Boring Holiday Project
July / August 2024

Hardware: 
Arduino Uno Rev.3
Nextion Display NX4832K035-010
Enhanced Series, 3.5”,	480*320 pixels
*/

#include <SoftwareSerial.h> //Include the library
SoftwareSerial Serial2(10, 11); // RX, TX

byte            f_goal = 0; // 0-255, force goal
float           f_LC = 0.0; // force load cell
float           displ = 0.0; // displacement
word            rt_goal = 0; // 0-65535, runtime goal  
bool            run = false;
const word      rate = 1000; // in ms
unsigned long   rt_last = 0; // 0-4'294'967'295 -> ca. 49 days, last runtime 

// Nextion Stuff
String          endChar = String(char(0xff)) + String(char(0xff)) + String(char(0xff)); // end-character when sending a message from nextion to arduino.
String          dfd = ""; // dfd = data from display
union {
  char charByte[4];
  long valLong;
} value;

// lofgile stuff
String myLogfile = "";
// --------- TBD --------

// Sensor stuff
// --------- TBD --------

// RTC Stuff
// --------- TBD --------

// stepper motor stuff
// --------- TBD --------

// send text to nextion
void sendValue(const char* adr, const char* msg) {
  delay(30);
  // construct a command string: "<objectname>.txt="<"message">0xff0xff0xff
  String command = String(adr) + ".txt=\"" + String(msg) + "\"";
  Serial2.print(command);
  Serial2.write(0xff); // write the 3 ending bits to the Nextion
  Serial2.write(0xff);
  Serial2.write(0xff);
  //Serial.println("Command send: " + command);
  delay(30);
}
// Overload function with more parameters for float number
void sendValue(const char* adr, float value, int decimalPlaces) {
  delay(30);
  // Buffer to hold the formatted float value as a string
  char buffer[10];
  // Format the float value with the specified number of decimal places
  dtostrf(value, 0, decimalPlaces, buffer);
  // construct a command string: "<objectname>.txt="<"message">0xff0xff0xff
  String command = String(adr) + ".txt=\"" + String(buffer) + "\"";
  Serial2.print(command);
  Serial2.write(0xff); // write the 3 ending bits to the Nextion
  Serial2.write(0xff);
  Serial2.write(0xff);
  //Serial.println("Command send: " + command);
  delay(30);
}


void getNextionData() {
  delay(30);
  while(Serial2.available()){
    dfd += char(Serial2.read()); // adda data do character
  }
  // debug print
  // Serial.print(dfd);
  checkNextionData();
}

// check the data that was received from Nextion
void checkNextionData(){
  // check first characters if they are "val", and check if message length is 11:  3 bytes from text ("val") and 4 bytes per value (f_goal, t_goal)
  // Message will be send in format: valxxxxyyyyzzzz
  if((dfd.substring(0,3)=="val") & dfd.length()==11) {
    getNextionNewValues();
  }
  
  // Start / Stop button
  if(dfd =="StartStop") {
    getNextionStartStop();
  }

  // Get logfile name
  if(dfd.startsWith("log") && dfd.endsWith("logEnd")) {
    getNextionLogName();
  }
}

void getNextionNewValues(){
  // get force goal value
  value.charByte[0] = char(dfd[3]);
  value.charByte[1] = char(dfd[4]);
  value.charByte[2] = char(dfd[5]);
  value.charByte[3] = char(dfd[6]);
  f_goal = value.valLong;
  // Serial.println("New force goal = " + String(value.valLong));
  // debug print
  Serial.print(F("New force goal = "));
  Serial.println(f_goal);
  // get time goal value
  value.charByte[0] = char(dfd[7]);
  value.charByte[1] = char(dfd[8]);
  value.charByte[2] = char(dfd[9]);
  value.charByte[3] = char(dfd[10]);
  rt_goal = value.valLong;
  // Serial.println("New force goal = " + String(value.valLong));
  // debug print
  Serial.print(F("New time goal = "));
  Serial.println(rt_goal);
  Serial.println();

  dfd = ""; // reset the message string
}

void getNextionStartStop() {
  run = !run; // toggle run flag
  digitalWrite(LED_BUILTIN, run ? HIGH : LOW);  // toggle the LED
  dfd = ""; // reset the message string
}

void getNextionLogName() {
  myLogfile = dfd.substring(3, dfd.length() - 6); // Position after "log" until position before "logEnd"
  // debug print
  //Serial.print("Logfile name: ");
  //Serial.println(myLogfile);
  dfd = ""; // reset the message string
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200); //open the serial port
  Serial2.begin(115200); // open the serial port for Nextion display
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  while (!Serial2) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println();
  Serial.println("==============");
  Serial.println("Setup finished");
  Serial.println("==============");
  Serial.println();

  // debug start parameters
  f_LC = 30.0; // debug start value
  displ = 5.0; // debug start value
}

void loop() {
  // Collect data from display
  if(Serial2.available()) {
    getNextionData();
  }

  unsigned long rt = millis(); // 0-4'294'967'295 -> ca. 49 days,
  if(((rt - rt_last) > rate) && (dfd == "")) {
    // read force
    // DEBUG ACTIVE ===============
    float rand = float(random(-1, 2));
    rand = rand / 100.0;
    f_LC = f_LC + rand;
    // DEBUG FINISHED ===============

    // update current force on display
    sendValue("f_current", f_LC, 2);

    // update current time on display
    sendValue("t_current", rt/1000, 1);

    // read displ
    // DEBUG ACTIVE ===============
    rand = float(random(-1, 2));
    rand = rand / 100.0;
    displ = displ + rand;
    // DEBUG FINISHED ===============

    // Update plot with displ
    // --------- TBD --------

    // Read RTC
    // --------- TBD --------

    // update current time on display
    // --------- TBD --------

    // log data
    // --------- TBD --------
    
    // if  force > or < setpoint, move motor
    // --------- TBD --------

    // Update the lastTime_main to the current time
    rt_last = rt;
    
    // debug
    //Serial.println("send");
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.