ITEADLIB_NEXTION Library Device Return Data Question

Hi @ScruffR and all,

I am using the Iteadlib_nextion library for my new project, but I ran into a problem trying to capture the autosleep event (0x86) and Touch event in sleep mode (0x68) on the P1 side. Is there a built in command in the Iteadlib_nextion library for such thing or other ways? Any help will be great. Thank You.

While the P1 is asleep the only thing you could catch then would be an edge on the RX pin as interrupt but the rest of the RX communication till your code is up and fully running would be lost.

@ScruffR, sorry for the confusion. I am trying to capture the Nextion display autosleep event and touch event return code while P1 is not asleep. I want P1 to know when the Nextion display autosleep or been touch during sleep. According to Nextion instruction set, Nextion display will return 0x86 for autosleep event and 0x68 for touch event during sleep mode. I am trying to find a way to capture 0x86 or 0x86 form the Nextion display when it happen at the P1 module end. From googling, it seem like I might have to add the functionality in the NexLoop procedure of the NexHardware.cpp. Unless the Iteadlib_nextion library have the functionality already.

Hello @sheng, I have been thinking about implementing this in my code and you got me motivated… just a bit. I am not an expert, but I have had to dig into this library to work around some differences for the BluzDK. I have not tested my suggestion, so I hope it works.
I can think of three options: modify the library to handle the events; adapt the library by creating a fake button press; or handle them in your loop() function. The last one is the easiest, but it corrupts the structure of the library by moving code into your main loop.

Modifying the library is beyond my present skills. Too many pointers to follow without a debugger, so I am going to punt this one… perhaps @ScruffR is interested.

Adapting the library would make it intercept the 68 and 86 events in the nexLoop function in the file NexHardware.cpp. You would add an else if statement that changes the buffer to the cid and pid of the hidden buttons and pretend they actually occurred.
These events would execute the callback functions in your main code. The hidden buttons should not generate any data, but first check what codes they would send for a button press.
This is more work, but I feel it is worth a shot because it enhances the library as opposed to having lose code in your main file. Note that you have to add #define for the 86 opcode… or just type it in.
For example, the sleep event would look like this:

void nexLoop(NexTouch *nex_listen_list[])
{
  static uint8_t __buffer[20];

  uint16_t i;
  uint8_t c;

  delay(100);  //need delay or it will not see data on serial port
  while (nexSerial.available())
  {
    c = nexSerial.read();
   .
   .
   .

   //new else if statement to be added after the last else if
    else if (NEX_RET_EVENT_SLEEP_POSITION_HEAD == c)
    {
    if (nexSerial.available() >= 6)
      {
        __buffer[0] = NEX_RET_EVENT_TOUCH_HEAD ;
        for (i = 1; i < 7; i++)
        {
          __buffer[i] = nexSerial.read();
        }
        __buffer[i] = 0x00;
 
          //change values based on hidden button
          __buffer[1] = 0x00;  //insert code of hidden button
          __buffer[2] = 0x01;  //insert code of hidden button
          __buffer[3] = 0x02;  //insert code of hidden button

        if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6])
        {
          NexTouch::iterate(nex_listen_list, __buffer[1], __buffer[2], (int32_t)__buffer[3], NULL);
        }
      }
    }

Then at the top of your .ino file you declare two button objects, you add them to the *nex_listen_list[] and you create the callback functions.
Finally, you “attach” the buttons to the callback functions in the setup() function of your code.
This is no different than adding a new button press even to your code.

The less intense method would be to use Serial.peek();
In your loop() function you check what’s in the serial port buffer. If the header code is 68 or 86, you first flush the serial buffer and then call a function in your .ino file. Otherwise, you let the Nextion library handle it.
You also have to remove the while (nexSerial.available()) line from the nexLoop function and add it to your loop() function, otherwise the event might happen right after “peeking” and the Nextion code will throw it away. This is the part I don’t like.

I am curious how you will use the sleep/wakeup events. Let me know.

EDIT: Forgot some curly brackets.

1 Like

I’ll have a look whether and how to create a dedicated soft “nexSleepClass”

@Pescatore, Thank you for the reply, I will have to do something similar to catch the nextion display going to sleep automatic and touch during sleep event. I will post what I figure out once I got something working. @ScruffR, were you able to get around to create the nexSleepClass?

Not yet, but I’ll do it some time - unless someone beats me to it and files a PR on the GitHub repo - pull requests are always welcome :wink:

@ScruffR, here is my attempted solution, it’s a work around for my purpose but not perfect:

NexHardware.cpp

//wakeup
#define NEX_RET_EVENT_AUTOSLEEP             (0x86)
#define NEX_RET_EVENT_AUTOWAKE              (0x87)

NexSleepClass nexSlpCl;
...

void nexLoop(NexTouch *nex_listen_list[])
{
...

  //screen wakeup routine
  else if (NEX_RET_EVENT_AUTOSLEEP  == c)
      {
        dbSerialPrint("autoSleep:");

          if (nexSerial.available() >= 3)
          {
              __buffer[0] = c;
              for (i = 1; i < 4; i++)
              {
                  __buffer[i] = nexSerial.read();
              }
              __buffer[i] = 0x00;
              if (0xFF == __buffer[1] && 0xFF == __buffer[2] && 0xFF == __buffer[3])
              {
                  // Need to create a new function to call when falls asleep
                  // call this new onsleep function
                  dbSerialPrint(" Inside AutoSleep ");
                  dbSerialPrintln(__buffer[1]);
                  nexSlpCl.isMicroSensorEn(true);
              }
          }
      }

      else if (NEX_RET_EVENT_AUTOWAKE  == c)
      {
        dbSerialPrint("AUTOWAKE:");

          if (nexSerial.available() >= 3)
          {
              __buffer[0] = c;
              for (i = 1; i < 4; i++)
              {
                  __buffer[i] = nexSerial.read();
              }
              __buffer[i] = 0x00;
              if (0xFF == __buffer[1] && 0xFF == __buffer[2] && 0xFF == __buffer[3])
              {
                  // Need to create a new function to call when now wakes up
                  // call this new onwake function
                  dbSerialPrint(" Inside AUTOWAKE ");
                  dbSerialPrintln(__buffer[1]);
                  nexSlpCl.isMicroSensorEn(false);

              }
          }
      }
      // end wakeup routine

NexSleepClass.h

#ifndef __NEXSLEEPCLASS_H__
#define __NEXSLEEPCLASS_H__

#include "application.h"

/**
 * NexSleepClass component.
 */
class NexSleepClass
{
public: /* methods */

  bool isMicroSensorEn (bool slpFlag);

};

#endif /* #ifndef __NEXSLEEPCLASS_H__ */

NexSleepClass.cpp

#include "NexSleepClass.h"
#define MOTEN A3

bool NexSleepClass::isMicroSensorEn(bool slpFlag)
{
  bool flg = slpFlag;
  pinMode(MOTEN, OUTPUT);

  if (flg)
  {
    digitalWrite(MOTEN,HIGH);
  }else {
    digitalWrite(MOTEN,LOW);
  }

  return flg;
}

The above code was able to capture AUTOSLEEP and AUTOWAKE and was able to turn on or off a motion sensor. But the draw back is not in the scope of P1 MCU. Is there any way to attach an attachPush or attachPop callback when AUTOSLEEP and AUTOWAKE is capture or similar method? Any advice will be great? Thanks

1 Like

My work around fail when I change value over the cloud since Nextion display is asleep, it would not be able to update the values. So the only way to get the update values is to have P1 keep track of the autosleep event and wakeup event. @Pescatore, which method did you end up using with success? I am still trying to figure out the library since my project is on a time limit, I will take any work around. Maybe @ScruffR can give us some suggestion. :slight_smile:

Is there any way to query the Nextion “sleep” value from P1? If I can get the current “sleep” value, I would know the state of the Nextion display.

I found another way to check the event return data. You can use “void seialEvent1()” and do a “nexSerial.peek()” BUT sometime it will miss the event return data. If I can get the current “sleep” value, it will compensate the miss. Any idea will be grateful.

@sheng, I stopped trying to debug the Nextion display library and I am in the process of integrating the ePaper displays from waveshare. I realized that even in sleep mode, the Nextion uses too much energy for my application.

I don’t know of a way to query the Nextion for the sleep state. I would think it can’t respond when in deep sleep.
I always imagined that the Photon would need to keep track of the display state. Otherwise, why bother looking for the sleep/awake events?
Sorry I am not more helpful. Maybe you can tell us more about your application and someone might give you a better direction.
Pesc