Start a new topic

Need some help with button callback, can't get it to work

 In absence of dbserial (uno/nano) i created a text field (LOG, id=11) on my screen.

Based on the nexgauge and nexbutton examples created 2 callback routines


MTRPopCallback and MODEPopCallback.

If pushed want to write text in LOG field as alternative logging. No problem during developments.


Have other VFO text field and writing to this field works ok.

Frequency is via sprintf formated in following format 7.100.000

So writing to a text field is working.

But seem not to get pushbutton reactions/callbacks activated.

Will attach my HMI and Arduino sketch so you can read what i am doing.

If you help me with MODE callback the rest i will manage.

Thanks in advance.

HMI
ino

forgot nexLoop(nex_listen_list); in the loop of the sketch, corrected, but still not callback's activated......

 

Hi,


There are a few issues that I've found and possibly more.


Push/Pop equate to Touch Press/Touch Release and a corresponding marker 0x01 or 0x00 is used in the Send Component ID string to identify each.


So for a Pop callback you need to check the Touch Release (Send Component ID) box in the HMI.


These events need to be listened for, essentially as loop interrupts, so just like the examples, this line needs to be in loop()  


nexLoop(nex_listen_list); 


Last, the page ID's (1st figure in brackets) in all these should be 1 surely ?


NexGauge nex_needle = NexGauge(0, 1, "NEEDLE");

NexButton nex_mode = NexButton(0, 2, "MODE");

NexButton nex_meter = NexButton(0, 5, "MTR");

NexText nex_vfo = NexText (0,10, "VFO");

NexScrolltext nex_log = NexScrolltext (0,11,"LOG");


Steve.

nexLoop i alread did, also checked the TouchRelease Send Component but think i already checked that also.

Will now correct the page id's. But actually in the editor pages always have id=0.

And writing text to objects on this page works ok. But will try correcting them to 1.

 

And the eagle has landed again :)

Thanks again for your great support.

One quick question is there a way to define the build output directory in settings/ini files?? It's a bit strange location now, found it but not very logic.

 

"But actually in the editor pages always have id=0."


Yeah, bit confusing that. The page is a component in itself with the default ID of 0


Like Page 2 component 0 if you see what I mean.


The global Page "ID" is the one given in the upper right pane listing, to the left of each instance.


Can't help with the 'build output directory' thing.

Ok, notice it now, always thought it was just sort of index.

Thanks again, you made my day. Will post some on W5KUB (fb) regarding these developments. Hope more follow this easy to use lcd.

 

Coming back to the callback functions.
See some examples where the 'record' is passed to the callback routine instead of a void ptr.
Does this mean that NexListen passes the latest information from the lcd to this callback function?
E.g. would this imply that i don't have to do a get call within the callback?

 

Nextion Touch Return Data is formatted 0x65 0x02 0x05 0x01 0xFF 0xFF 0xFF

The first byte of 0x65 identifies this as a touch event, triple 0xFF termination
  from page 0x02 component 0x05 and touch 0x01
  (touch 0x01 pressed = push  and 0x00 released = pop)

So when you define a bunch of Nextion Components
    NexGauge nex_needle = NexGauge(0, 1, "NEEDLE");
    NexButton nex_mode = NexButton(0, 2, "MODE");
    NexButton nex_meter = NexButton(0, 5, "MTR");
    NexText nex_vfo = NexText (0,10, "VFO");
    NexScrolltext nex_log = NexScrolltext (0,11,"LOG");
The Arduino Library can use this to build its listen list,
  - but this isn't where the listen list is built

NexTouch *nex_listen_list[] = {
   &nex_needle, &nex_meter, NULL
}

This NULL terminated list says to listen for nex_needle and nex_meter

 and skipping the rest of the components not in this list.


Using the first and second parameters it will now be on the lookout for

  NexGauge(0, 1, "NEEDLE");

     0x65 0x00 0x01 0x01 0x0FF 0x0FF 0x0FF  // needle pressed (push)

     0x65 0x00 0x01 0x00 0x0FF 0x0FF 0x0FF // needle preleased (pop)

  NexButton(0, 5, "MTR")

     0x65 0x00 0x05 0x01 0x0FF 0x0FF 0x0FF // meter pressed (push)

     0x65 0x00 0x05 0x00 0x0FF 0x0FF 0x0FF // meter preleased (pop)

But there are two more things that need to be setup


The Arduino Library includes procedure ptrs to be added

  nex_needle.attachPush will setup what should be run

    when this 0x65 0x00 0x01 0x01 0x0FF 0x0FF 0x0FF is encountered

    nex_needle.attachPush(nameofmypushcallback);

  - this means you need to have a nameofmypushcallback function


   void nameofmypushcallback(void *ptr) {

     // code for when nex_needle page 0 comp .id 01 is pressed

   }


Likewise and attachPop can be setup for the release


So when we look in nexLoop inside NexHardware.cpp


 

void nexLoop(NexTouch *nex_listen_list[])
{
    static uint8_t __buffer[10];
    
    uint16_t i;
    uint8_t c;  
    
    while (nexSerial.available() > 0)
    {   
        delay(10);
        c = nexSerial.read();
        
        if (NEX_RET_EVENT_TOUCH_HEAD == c)
        {
            if (nexSerial.available() >= 6)
            {
                __buffer[0] = c;  
                for (i = 1; i < 7; i++)
                {
                    __buffer[i] = nexSerial.read();
                }
                __buffer[i] = 0x00;
                
                if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6])
                {
                    NexTouch::iterate(nex_listen_list, __buffer[1], __buffer[2], (int32_t)__buffer[3]);
                }
                
            }
        }
    }
}

 

When the Nextion sends your needle pressed

   0x65 0x00 0x01 0x01 0xFF 0xFF 0xFF

When it encounters 0x65 as first byte on line 13

it reads the incoming and parses through to line 29

catching the 0xFF 0xFF 0xFF termination on line 24

and passes 0x00 0x01 0x01 to NexTouch::iterate


Iterate in NexTouch.cpp

  checks its nex_listen_list for

     pid (page id) 0x00 and cid (Component id) 0x01

     from your NexGauge nex_needle = NexGauge(0, 1, "NEEDLE");

 then checks if the return data 0x01

    if this 0x01 is a NEX_EVENT_PUSH 0x01 then

       if you set up an .attachPush it calls your function from

       nex_needle.attachPush(nameofmypushcallback);

    if this 0x01 is a NEX_EVENT_POP 0x00 then

       if you set up an .attachPop it calls your function from

       nex_needle.attachPop(nameofmypopcallback);


NexTouch.cpp default push and default pop is type void


So all of this is to handle if Send Component ID is checked

   in either Nextion Editor component Touch Press or Release


Do you have to respond to it?  No

   there is a .detachPush and .detachPop

   and it never needed to be included in the list

But the whole point of having all this set up was to know MCU side

  when a user pressed or released a component Nextion side


When that Send Component ID is checked

  Nextion will send its corresponding 0x65 0x--0x-- 0x-- 0xFF 0xFF 0xFF

  - other than this send component ID, there is no 0x65 notices


But to not react on the event when the event occurs

  - why bother sending the info in the first place?

 


On the note of records being passed to your callback functions

That is a bit more advanced than the stock Arduino Nextion Library

Some segments of the Library may need custom tailoring


But it is possible for sure,

  pass an MCU side data record and alter that record in your routine


All of such record handling is MCU side, and independent of Nextion's 0x65 notice

 - other than the record would be altered in response to the event

 - the coding of such is within the users domain, but indeed possible


Patrick,
Thanks. Not sure where i saw it, not sure if it was in the examples.
The callback is working. But thought i saw, somewhere, an example where the parameter to the callback was a defined record, where in the code record->value was used. Can't directly find it in the examples with the library, maybe it was on the forum somewhere.

Never mind, no problem to explicitly do a get in the MCU side and callback routine related to the object and retrieve the value and act upon this value. That's the concept, MCU behaves based on user input/settings on the lcd.

 

Let's say I had some type of time stamp defined in my MCU code

Lets say this time stamp record structure was tracking last interaction


Then perhaps knowing which variable structure is to be updated on the event

one could indeed set up a callback with a record parameter


But in thinking about it

 - it would be specific to a particular component's callback

 - not global to the object component class


But I say it is indeed possible, just need a bit more code to do


Login or Signup to post a comment