Debugging help - dust collection system with Nextion

This is my first post to the forum so apologies in advance if the formatting isn’t correct or this isn’t the correct category for the post.

I’m trying to automate my wood shop dust collection system. Ultimately, the system will use a Mega 2560 with inputs from current sensors on each of 12 tools. When a tool is turned on or off, servos will open or close the appropriate blast gates from the total of 15 gates and turn the dust collection cyclone on or off as required. A Nextion (NX3224K028) will be used to display system status and to allow testing individual blast gate operation, cyclone operation and overall program logic.

This will be my first Arduino project and I have no prior C or CPlus programming experience. I do have 30+ years experience using SAS and limited javascript experience but have found neither of these to be much help. I guess you could categorize me as just starting to appreciate what I have yet to learn.

As far as this project, I’ve downloaded and worked with Perry’s Nextion tutorial and looked at Seithan’s tutorial on using Nextion with Arduino. Apparently, I’ve missed something fundamental in trying to adapt these methods to my project so I’m asking for help.

I’ve created a slimmed down version of the project to illustrate the issues I’m having. The Nextion display is loaded with 3 pages:
ErrorPage SystemPage ToolsPage
Here’s the code:


#define NEXTION Serial1
#define NUMTOOLS 3
uint8_t toolsOnCount = 0;
const char toolNames[3] [15] = {"Table Saw",
                                "Drill Press",
                                "Supermax Sander"
                               };
uint8_t curToolStates [NUMTOOLS] =  {LOW, LOW, LOW};
uint8_t prevToolStates [NUMTOOLS] =  {LOW, LOW, LOW};
uint8_t curHMIPage;
uint8_t prevHMIPage;
char hmiEventType;
uint8_t hmiButton;
uint8_t i;
uint8_t j;

void setup() {
  Serial.begin(9600);
  NEXTION.begin(9600);
  delay(500);
  updateSystemPage();
}

void loop() {
  readHMI();
  setPrevious();
}

void updateSystemPage() {
  Serial.print(F("Starting "));
  Serial.println(__func__);
  NEXTION.print(F("page System"));
  NEXTION.println(F("\xFF\xFF\xFF"));
  NEXTION.print(F("toolsOn.txt=\""));  // if these lines are commented, the
  NEXTION.print(F(" "));               // System page is displayed when the
  NEXTION.print(F("\""));              // sketch is uploaded or Arduino is reset
  NEXTION.print(F("\xFF\xFF\xFF"));    // but the toolsOn text is not updated
  if (toolsOnCount == 0) {
    Serial.println(F("toolsOnCount=0"));
    NEXTION.print(F("toolsOn.txt=\""));
    NEXTION.print(F("All tools are off"));
    NEXTION.print(F("\r\n"));
    NEXTION.print(F(" "));
    NEXTION.print(F("\""));
    NEXTION.print(F("\xFF\xFF\xFF"));
  }
  else {
    Serial.print(F("Update System Page Number of tools on: "));
    Serial.println(toolsOnCount);
    NEXTION.print(F("toolsOn.txt=\""));
    for (i = 0; i < NUMTOOLS; i++) {
      j = 0;
      if (curToolStates[i] == HIGH) {
        NEXTION.print(toolNames[i]);
        j++;
        if (j > 0) {
          NEXTION.print(F("\r\n"));
        }
      }
    }
    NEXTION.print(F("\""));
    NEXTION.print(F("\xFF\xFF\xFF"));
  }
  Serial.print(F("Ending "));
  Serial.println(__func__);
}

/**************************************************************************************/
/**  Data is sent from NEXTION when a page is landed on (from postinitialize event)  **/
/**  or a button is pressed (touchpress event). Data sent is 3 bytes of the form #en **/
/**      where:    # (hex 23) signals the start of the sent data                     **/
/**                e is an alpha character:  P (hex 50) for a page landed on         **/
/**                                          T (hex 54) for a tool button click      **/
/**                                          R (hex 52) for reset button click       **/
/**                n is the button index                                             **/
/**************************************************************************************/
void readHMI() {
  uint8_t i;
  static uint8_t hmiReadBuffer[3];
  static uint8_t bufIndex = 0;
  uint8_t readTemp;
  while (NEXTION.available() > 0) {
    readTemp = NEXTION.read();
    if (readTemp == 0x23) {
      hmiReadBuffer[0] = readTemp;
      readTemp = 0xff;
      bufIndex++;
    }
    if (bufIndex > 0 && readTemp != 0xff) {
      hmiReadBuffer[bufIndex] = readTemp;
      bufIndex++;
    }
    if (bufIndex > 2) {          // we have the 3 byte sequence from Nextion
      Serial.println(F("Data from Nextion"));
      Serial.println(F("hmiReadBuffer"));
      for (i = 0; i < 3; i++) {
        Serial.println(hmiReadBuffer[i], HEX);
      }
      hmiEventType = hmiReadBuffer[1];
      switch (hmiEventType) {
        case 'P':   // page change
          curHMIPage = hmiReadBuffer[2];
          hmiButton = 0;
          Serial.println(F("case P"));
          break;
        case 'T':   // tool button
          curHMIPage = 1;
          hmiButton = hmiReadBuffer[2];
          toggleTool();
          Serial.println(F("case T"));
          break;
        case 'R':   // reset button
          Serial.println(F("case R"));
          curHMIPage = prevHMIPage;
          hmiButton = hmiReadBuffer[2];
          clearAll();
          break;
      }
      bufIndex = 0;
    }
  }
}

void clearAll() {
  Serial.print(F("Starting "));
  Serial.println(__func__);
  for (i = 0; i < NUMTOOLS; i++) {
    curToolStates[i] = LOW;
    toolsOnCount = 0;
  }
  Serial.print(F("Ending "));
  Serial.println(__func__);
}

void setPrevious() {
  for (i = 0; i < NUMTOOLS; i++) {
    prevToolStates[i] = curToolStates[i];
  }
  curHMIPage = prevHMIPage;
}

void toggleTool() {
  Serial.print(F("Starting "));
  Serial.println(__func__);
  Serial.print(F("toolsOnCount = "));
  Serial.println(toolsOnCount);
  Serial.print(F("hmiButton ="));
  Serial.println(hmiButton);
  if (curToolStates[hmiButton] == HIGH) {
    curToolStates[hmiButton] = LOW;
    toolsOnCount--;
  }
  else {
    curToolStates[hmiButton] = HIGH;
    toolsOnCount++;
    if (toolsOnCount > 2 ) {
      Serial.println(__func__);
      Serial.print(F("toolsOnCount = "));
      Serial.println(toolsOnCount);
      hmiShowError();
    }
  }
  updateToolsPage();
  Serial.print(F("Ending "));
  Serial.println(__func__);
  Serial.print(F("toolsOnCount = "));
  Serial.println(toolsOnCount);
}

void updateToolsPage() {
  Serial.print(F("Starting "));
  Serial.println(__func__);
  for (i = 0; i < NUMTOOLS; i++) {
    NEXTION.print(F("t"));
    NEXTION.print(i);
    NEXTION.print(F(".bco="));
    Serial.print(F("t"));
    Serial.print(i);
    Serial.print(F(".bco="));
    if (curToolStates[i] == HIGH) {
      NEXTION.print(F("GREEN"));
      Serial.print(F("GREEN"));
    }
    else {
      NEXTION.print(F("RED"));
      Serial.print(F("RED"));
    }
    NEXTION.println(F("\xFF\xFF\xFF"));
    Serial.println(F("\xFF\xFF\xFF"));
  }
  Serial.print(F("Ending "));
  Serial.println(__func__);
}

void hmiShowError() {
  Serial.print(F("Starting "));
  Serial.println(__func__);
  NEXTION.print(F("page Error"));
  NEXTION.println(F("\xFF\xFF\xFF"));
  Serial.print(F("hmiEventType ="));
  Serial.println(hmiEventType);
  while (hmiEventType != 'R') {  // wait until reset button is pressed
    readHMI();
  }
  Serial.print(F("Ending "));
  Serial.println(__func__);
}

The serial monitor seems to indicate that the program is functioning as expected:

Starting updateSystemPage
toolsOnCount=0
Ending updateSystemPage
Data from Nextion
hmiReadBuffer
23
50
0
case P
Data from Nextion
hmiReadBuffer
23
50
1
case P
Data from Nextion
hmiReadBuffer
23
54
2
Starting toggleTool
toolsOnCount = 0
hmiButton =2
Starting updateToolsPage
t0.bco=RED���
t1.bco=RED���
t2.bco=GREEN���
Ending updateToolsPage
Ending toggleTool
toolsOnCount = 1
case T
Data from Nextion
hmiReadBuffer
23
54
1
Starting toggleTool
toolsOnCount = 1
hmiButton =1
Starting updateToolsPage
t0.bco=RED���
t1.bco=GREEN���
t2.bco=GREEN���
Ending updateToolsPage
Ending toggleTool
toolsOnCount = 2
case T
Data from Nextion
hmiReadBuffer
23
54
0
Starting toggleTool
toolsOnCount = 2
hmiButton =0
toggleTool
toolsOnCount = 3
Starting hmiShowError
hmiEventType =T

The Nextion display isn’t showing what I expect to see:
When the serial monitor shows that the toggleTool function is run for the first time, on the Nextion I should see t0 and t1 with red backgrounds but only t0 is red.
When toggleTool function is run for the 3rd time, as expected, the hmiShowError function begins but the Nextion doesn’t display the Error page. I’m sure that the coding for displaying the Error page is correct as if I copy the Nextion.print statements for displaying it into the setup function the page displays. Finally (for now) I have to reset the Arduino twice to get the Nextion to reshow the System page.

Appreciate any suggestions as to what’s going on or how to revise the code to work. Also welcome any information on an alturnative to using all the Serial.print statements for debugging. I know that there are some hardware debugging options but I’d like to avoid starting a second learning curve that they seem to require.

1 Like

An interesting and serious project.
Serial.print is an excellent debugging tool to make the code work. Then the Serial.prints ought to be commented out.
You can also use Serial in order to send commands from the computer and the IDE, just in order to make the hardware verification proceed.
I don’t know Nexion at all.
What is the status regarding the hardware?

Hello rbreed,

Much of what you posted doesn’t look like my code so I take it you are using @Seithan’s methods, which I can’t help with, I’m also using a mobile phone, which is awkward.

Your code is very long, I suggest you start with a short sketch that just does one of the things you want then build on that a step at a time.

I’d also avoid the for loops with conditions to print this or that to the Nextion, building up a complete message in steps because doing it like that is also building up problems in steps at the same time. Get it working with simple, unconditional prints first then add the clever stuff afterwards. I think you are trying to be too clever and write code that is too complex before you have established that the basics work.

This won’t work:

NEXTION.println(F("\xFF\xFF\xFF"))

(Ditch the ln)

Interesting project through!

Oh, and well done for using functions!

Still working on the hardware. I have a friend who’s working on the tool sensors for me. As of now it looks like I’ll be using a donut CT at the tool feeding a two stage op amp comparator to convert the signal to a high/low digital input. I’ve built 6" blast gates that operate on a high torque hobby servo. The existing remote control switch for my cyclone has room to insert a miniature DPDT relay controlled by the Arduino while still maintaining the switch’s original functionality. Bottleneck right now is getting the code to function. I have it written to include the sensors, servos and cyclone but it’s to big for my to debug successfully using Serial.print.

Perry,
Thanks for the suggestions. Changing NEXTION.println(F("\xFF\xFF\xFF")) to NEXTIO.print(F("\xFF\xFF\xFF")) solved 99% of the problems! I’d have never found it no matter how simple I made the sketch.

It appears that NEXTION.read() returns one char at a time, which you place into hmiReadBuffer[].
I don’t know anything about the display, but does the second char always hold ‘P’, ‘T’, or ‘R’? Can it every return a lowercase letter? It seems that the 3rd char holds the current HMI page, when the second char is a ‘P’, but holds the hmiButton on ‘T’ or ‘R’, right? If lowercase is allowed, it might be safer to use:

 hmiEventType = toupper(hmiReadBuffer[1]);

When you get more problems, you might consider building the command into a C string so that you can be certain that what you show on the serial monitor is the exact same thing you sent to the Nextion. Note C string, not String object.

econjack,
You’re correct that the second character returned from the display can only be a ‘P’, ‘T’, or ‘R’ (unless I’ve made a mistake in creating the event on the Nextion. You’re also correct that the 3rd character represents the page number for a ‘P’ event and the hmiButton number for a ‘T’ or ‘R’. I’ll be adding a
‘G’ event for the blast gates and a ‘D’ event for the cyclone state in the final version of the code. Again, these will always be uppercase.

wildbill,

Thanks for the suggestion. I’ll look into it. Sure would be nice, though, to have access to a debugger. I would not have made the mistake of using NEXTION.println had I not copied the Serial.println function and changed Serial to NEXTION.

Don’t beat yourself up over it, I have made the same mistake and spent ages staring at my code until my eyes were red! Took me ages to see it. That’s why I spotted it so quickly in your code.

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