Start a new topic

Accessing multiple nextion page data from Arduino

First of all, I am able to access Nextion page data with no problem as long as that page is displayed or current.


In testing this, it appears you cannot grab the data from a page if it is not being displayed and that makes sense.  I thought about this and am considering these options.


Option 1:

I saw the CompPage example and thought, I could just do a page.show(), pull the data and then go back to the previous page.


Option 2:

I could look into these global variables and see if I could do something like that. I have roughly 20 variables on the page that is not being displayed.  I have a nice convenient place that I can trigger the Nextion to update the global variables.


Option 3:

I tried taking my page that has the objects I need (numbers, text, etc) and make all the variables "global" but I could not get their values from the Arduino.


I am sure someone has done this and would appreciate your thoughts and best approach for an Arduino routine to grab some objects off a page that is not the current page being displayed.


Thanks in advance !!!




Question, where did the data originate?


I realise peoples needs are different, but in my designs I forward data to the display, meaning my remote MCU (Arduino or whatever) is up to date and in full control at all times. Apart from displaying my data I can of course make adjustments to change things with a button push or something other. The changes are sent to my MCU, which would then if necessary update the display. 


This kind of logic means the Nextion doesn't generate and hold data that later needs recovering by the MCU. My MCU is all knowing, the Nextion is just a dumb display (in the nicest possible way :-) and all is just a matter of how you program the application.


I think like this...My PC monitor is a nice 21" 1920 x 1080 touchscreen, but it knows nothing that my Windows applications need to ask for at some time. It is however a multi touch input device that can influence the output of my Windows applications. 



This process is totally controlled by the MCU. Recipes are supplied to the MCU. So this piece of data is sourced by the nextion. It is mo problem because I put a save button on the recipe page and i can get the data to the MCU. I created a button to START the control process. It is no big deal and I can rely on saving the recipe from the recipe page. I do try to foolproof things and the idea was to grab the recipe data when I start the process. So my Nextion does house the recipe data.

An example...


Say you wanted to design a swish looking home thermostat control.


You come up with some nice looking graphics to use in your HMI on Nextion. You add some buttons to increment and decrement the temperature value in a text or number box. Your whole application will be much more complex than this, so you decide to offload the processing to an Arduino.


Some approaches to how you keep the Arduino in the loop so to speak.

You could send the new value of the dispay 'box' as it is changed to Arduino. But who knows it got there correctly???  And don't forget Arduino is adjusting your heating system, not Nextion!

You could program Arduino to ask for the value later. Who knows it got a proper answer, or ever asked in the first place???

Or my preferred method, the up down keys don't update Nextion, they increment a value on Arduino. Arduino sends the latest value it has back to the 'dumb' Nextion 'box'. If the displayed value isn't changing something is broken, right?

I would love to just update my arduino variables directly from the nextion. When a value is changed on the nextion just update the mcu. I trigger a button to the arduino and the mcu grabs the data. I did not think the display could update an arduino variable direct. I put a page on my display called ARDUINO. There is a button called refresh and it sends a callback to the arduino. The arduino updates the display with important technical data to see. I agree in that I want my mcu to rule the kingdom. This project does have the need to adjust the recipe from the display.

Run this on Arduino, in Serial Monitor send a bunch of +++'s and -----'s


The prints could be much tidier with printf but you should get the idea.

No library required.

You can test on Nextion by building an HMI with a textbox t0

2 buttons + and -

Button press event print "+" and print "-" respectively, make sure Send Component ID is unchecked 

and delete the Serial.println() at the end of the respective code blocks in Arduino code then run it to Nextion. 

uint16_t variable = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();
  Serial.println("Hello World");
}

void updateTextBox () {

  while (Serial.available()) {
    char inChar = Serial.read();
    if (inChar == '+') {
      variable++;
      Serial.print("t0.txt=\"");
      Serial.print(variable);
      Serial.write(0x22);
      Serial.write(0xFF);
      Serial.write(0xFF);
      Serial.write(0xFF);
      Serial.println();//Delete for Nextion run
    }
    if (inChar == '-') {
      variable--;
      Serial.print("t0.txt=\"");
      Serial.print(variable);
      Serial.write(0x22);
      Serial.write(0xFF);
      Serial.write(0xFF);
      Serial.write(0xFF);
      Serial.println();//Delete for Nextion run
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  updateTextBox();
}

 


When you want a Nextion side variable to persist across pages

 - you need to change the source .vscope attribute from local to global

 - you need to prefix calls to your variable with the pagename.

 - consider using a Nextion timer in the pages

    - which pulls from the global variable to display in the component


So if I am understanding correctly, lets take two temperature values

in integer degrees as numeric variables and make an example

  a) tempA is for the actual temperature

  b) tempD is for the desired temperature


Create a page in your HMI called globals

- add a Variable called tempA - set this .vscope to global

- add a Variable called tempD - set this .vscope to global


This will allow you to access tempA's value with globals.tempA.val

and tempD's value with globals.tempD.val from any page


When updating the value from within a 1000ms timer on a page to local n0 and n1

    n0.val=globals.tempA.val  // Display Actual in n0

    n1.val=globals.tempD.val  // Display Desired in n1


When defining the Number Component MCU side

    NexNumber Actual = NexNumber(0,1,"globals.tempA");

    NexNumber Desired = NexNumber(0,2,"globals.tempD");


Your MCU side updates to the Nextion

    Actual.setValue(numberActual);

    Desired.setValue(numberDesired);

This would be populated by the page's 1000ms timer on the Nextion to your page components

To get a value from the Nextion to Arduino


In the button code that accepts the Desired temperature say b2

  globals.tempD.val=n1.val

In the appropriate Touch Pressed or Touch Released Event

   check Send Component ID checkbox to send 0x65 touch codes


On the Arduino Side

a) ensure to define MCU side global scope variable for Desired

     uint32_t desiredTemp;

b) ensure button to be listened for is defined 

   NexButton b2 = NexButton(0,1,"b2"); // with proper page and id

c) ensure that button is in the nex_listen_list[]

     &b2,

d) ensure to use the appropriate attachPop or attachPush in setup()

     b2.attachPop(b2PopCallback, &b2);

e) ensure to define the declared b2PopCallback function

    void b2PopCallback(void) {

        // get variables from globals page

        Desired.getVaue(&desiredTemp);

    }


This transfers Nextion side Desired to MCU side desiredTemp

as Desired is defined with page specific prefix "globals.tempD"

and transferred in the button Nextion side that "accepts" temp value

And as a quick note:


The component .setValue() and .getValue() functions will actually parse out to the code format that indev2 has shown.  (with the exception I was demonstrating prefix the pagename for global variables)

I have played around with both of your responses. 


@indev2, that is a very simple solution and quite easy to follow. Many thanks.  I do like how easy it was get and set text fields. 


@Patrick, I got all the variables setup on a global a page and it works like a champ also.  The timer function does work nicely.   I have one question.   All the number variables work very nice and so easy to just manage them off a global page.  The whole text/string variable just has me so confused.   If I have string variable on the global page, can I access it as simple as a the number fields?  It is a 1 character field.  I just want to pop it off the global page as the setValue and getValue works.  I thought there would be a setText and getText.

I figured it out.  It helps if it the reference is correct.  The definition of the variable was not prefixed by the page globals.  Changed it and everything works nicely.   Thank you for all your help.  It is unbelievable getting the fantastic support on this site.

Login or Signup to post a comment