Start a new topic
Not Taken

timers stops if the page is inactive

Timer run only when the side of the timer is active. This applies regardless of whether the timer is local or global.

Thus, it is not possible to use the timer for background work if the page is not active.

The only way is that each side has its own timer with the identical Timer Event.

This is very error prone and costs unnecessary memory.

I am now reviewing all of the Feature Requests, this will take some time, patience please.

Although this wasn't a real feature request, it is now marked as reviewed.

Future questions should be posted to the Free Chat Section


I forgot to mention with regards to the GLCD font system not having been implemented.  It stems from the fact the source is using the simplified Chinese GB2312 character set, a square dimensioned font matrix in a 94x94 grid with 87 panes of 94 characters and a 95 character half-width subset (32 to 126) of the lower ASCII for a total  8273 characters in their .zi font file.  The internals of such needs to address various state mechanisms used in narrowing down towards their final character selection.  This requirement for their main, larger and therefore more important market has led them to choose a zimo format that helps facilitate their requirements where the GLCD system doesn't contain any of the necessary mechanisms.

What they have found in trying to branch out to the International Markets is that the iso-8859 definitions can be piggybacked within their existing zimo format and required fewer of the existing mechanism to implement.  Therefore iso-8859 was able to be implemented as you now see in the Nextion Editor in around version 0.30  The full Unicode is a much larger set unable to be accommodated and the UTF I can read here on the board was being considered but would have required even more mechanisms than zimo and was abandonded.

@Edwin, No, I am not part of the Nextion Team, I am a user with an agreement for me to work on ZI font editor.  I only have roughly 4 month head start on you as to picking apart their processes.  So given the same amount of time, you'd be where I am at or further.  Other than a senior contact, it boils down to the older school skills which you also possess.

I do subscribe to the Chinese Edition of the Editor as it comes out first, (about five or six days ago v38 was released) and just like the delay between v36-v37 of the Nextion Editor, we are seeing the delays needed for translating and training that is going on behind the scenes here so that Nextion can release the translated International version.  So I have already been picking apart the Radio Buttons that act like round check boxes as they have no grouping attribute to perform a radio button function.

It is the Editor that does all your coding, from what was flexible in the Editor to hardcoding in the output you upload into your Display, but once in the display - it is laid out in hardcoded branches without the Interrupt and InterruptingWaiting the STM32F0 considered.  So looking at the STM32F0 there is 8K of RAM, and so the bootloader of course loads the firmware into place, and then starts with loading your first page.  So version 32 of the Editor was a bit more visual on how much space you were using, v38 will begin again to be a bit more visual from v37, but less than v32. 

Most possibilities of what could go wrong is caught in the editor, and uploading a malformed segment will not have any check performed.  The fact the names are there actually does get used in a ref t0 or a renamed text component, to locate ref myTitle.  But there is no search for myTitle, it is located in a fixed offset in a fixed record size with the starting offset recorded for quicker access, so  a offset + itemnor * recordsize is the start of each record, iterate from start to section end and check each, if not check next ... etc.  Also on almost every command that can use the object name, the ability to do it by number is also there.  If t0 is third component with ID of 2, I can call ref 2

Now, again, except for a contact and an indirect access to both Itead and the source company as some perceived advantage - it actually may be a waste of time.  With the exception of an agreed upon font project for which is currently and directly mine, (that I do have the say for, and the responsibilities of) but I am limited in that I can not override what the source company decides and creates for the HMI Editor.  Now considering little successes with the font project, the next will probably be an RTOS version, but again I won't be able to override the what the source chooses to do in the HMI Editor.  It will probably be stand alone from the production HMI edition.

But here is where I see it may indeed be a waste of time (and I will make some assumptions as I do not have any access to actual accurate internal company data).  My guess is that the International version represents less than 2% of the source market.  They have the current version (say like v38) long before we even get to see it.  My guess is that v39 may come out before we have even seen v38.  My guess is that their internal market represent 98% of the requests and long before we get to make our 2% of the  requests. These items probably have been requested already by a much larger and more valuable set of the customers than from us here on the International side.  I would assume that all the changes for their next edition have already been selected and queued - if not 75% completed.  So how many requests posted here were truly original and the one that actually made the edition cut first.

However, I still take note of the requests because many suggestions will make sense if the next project is granted me is the RTOS version - though I can tell you, I'd be changing the conflicting formats super quick so, like you said, maybe a waste of time.   A complaint about a format that won't exist would be a waste.

 @Patrick, resources are always at premium and I think you are using this as a stroman argument. Use your resources wisely. A non visual component that execute some code so it can be used as a subroutine will save ram if it’s replacing a disabled hotspot that need memory for it’s coordinates.

A global variable with an on change event will save memory when it is replacing a timer (name, time and enabled) or a hotspot.

Regarding the variable width fonts I wonder why the GLCD font system is not implemented. I used a ascii based oled library using GLCD fonts that including SPI or I2C took less then 3kb of memory and 60 bytes of ram. Adding variable width is nothing more then an extra lookup array in the font file. (I also wonder why you can’t define a color as transparent)

By looking at the content and structure of the tft file my guess how the Nextion works is that the compiler is actually a linker that combines the interpreter, fonts, pictures and events (interpreted strings) together and the bootloader puts the interpreter in the 64kb programming memory and the rest in the 16Mb SPI memory (3.5”display) So when loading a page a data structure in ram must be build containing the properties with vectors to the events and data in the SPI memory. It looks like part of these properties is the actual name of the component. If this is the case converting these names to Id’s would save ram depending on the length of those names.

Now I am wondering if you are part of the Nextion team. If so please think about the above, discuss this with your team as this is a product that got a lot of potential. If you are not involved in the development I can only hope that someone from Nextion is reading this otherwise I am wasting my time.


I have seen some of your coding techniques, and answers to some questions, so with full respect of course, I believe we could have a meaningful dialog.

1) We can agree resources are premium?

I want 224 bytes of addition space for Variable Width Fonts, so that the displays can use resources more efficiently.  Currently pictures are being used at 2 bytes per pixel as the norm because of the quality of a generated font set is so poor.  Reducing this to 1/16 resource usage via a mono-bit pixel format, would benefit the entire ecosystem - but I need that extra byte per character in a .txt string to do so.  Now my request is MOSTLY .DATA space in Flash with an added string length of SRAM.  Firmware .CODE space I think would be increase minimally.

Now the Internals of a component is already bloated to 180 bytes to define it, and attempting an onChange as an event would certainly bloat that further.  But an onChange requires an actual object, and to trigger it requires an event class.  The current Nextion internals are data records with the firmware coding the logic.  It isn't an independent object by any stretch of the imagination - hence x,y,w,h is hardcoded in the HMI and no means of change. 

Should a hardcoded method be found and implemented to simulate this onChange, it increases the byte count on every single component and that is going to result in pure bloating.

I wonder if the point of these being data records and not objects is getting through, that nothing in the Nextion is dynamic, but precoded in the Editor to hard coded machine code in the Nextion Display.

So maybe it is the methodology of what is being proposed.  Maybe if it were under a different name as a non visual component where precious resource space isn't further bloated. 

Perhaps "A Value Watch Point", load it with an initial value, when value changes from old, run user code.  But as an independent non-visual and not an extension of the Components

1 person likes this

I would be very surprised if the timers are using all of the hardware timers. I expect that this is implemented in the idle loop of the device.

I see no reason why the processor can’t execute some additional code when the value it has to write to a variable is different then the content of that variable in the same way as the initialize and timer events are handled. And this will make an improvement. I don’t want to be bothered to find out which page the device is displaying to change a displayed value. Now I’m using timers to do that trick ( and the click command in the near future) and that work’s great but an onChange event would simplify things greatly.

What you are missing is the advantage of this approach, if I design my interface with the Nextion correctly (sent data to and receive commands from the user), I can let another designer do the user interface. If that designer want to display a temperature not only on page 1 and 3 but also on page 5, he doesn’t have to get back to me with the request to handle an addition page to display that temperature value. And if you want to use a different size device with a different page layout or another orientation I don’t have to change the MCU code. And that makes life easy :)

I think that one day people might actually look deeper into the internals of the Nextion, and of course without the source code in hand to pour through that leaves very few that will actually do so.  And it is without that understanding of the internals that these type of requests come.

The Nextion is sequentially HARD CODED with only a two step interrupt - Interrupt and isInterruptWaiting, where the isInterruptWaiting allows to shave a few clock cycles off by not having to perform a full pop and return but allow it to go straight into executing the waiting interrupt.  The interrupts are hardware interrupts and not software interrupts - the timer gets away with using one of the 6 internal timers not being used by a PIN, but outside of this there is no Software Interrupts (timer is not really a software interrupt).

For those that have to yet take a Magnifying Glass (my eyes are bad enough, I certainly needed one) and check out the chip on the back of the Nextion the chip used is an STM32F030C8T6 a Cortex-M0, and there are hints that a Cortex-M1 STM32F103C8T6 might be used in the larger Enhanced Models (but not the smaller Enhanced).  So that still leaves the using the Cortex-M0 code as least common denominator where the Nextion Editor outputs identical code for Basic Models and a identical code for Enhanced Models (RTC/EEPROM/GPIO).  The manufacturing specs can be found for all chips on the Nextion.

Back to hard coding .. every object (more accurately described as a records, as objects can be modified)generates a predetermined sequence of output code.  There really isn't a capability for dynamic functions. So when old pages get wiped out - it comes as no surprise when the new pages data records come in.

Global is limited to a data storage location is SRAM, and not a code space located for functions.  So an onchange code function simply doesn't work. 

Now, what I don't get is when you don't have the ability to change the source on Nextion, why is the first thought not to make that onChange event part of your Arduino code.  IT becomes much easier to write a local routine in your host MCU where you have FULL control and can completely customize it to exactly what you desire to achieve your desired goals.

So there is some existing issue that I am not understanding.  Because the request for changes when one doesn't understand the existing structures really doesn't make sense.  There is a swap that will need to be made - "put my request in, and drop this code that has less value" in order to fulfill such requests.

Even in my approach with the zi fonts, I don't merely say "put in Variable Width fonts" without a how it is to be accomplished.  With an analysis of the how, so that it doesn't break everything else in the process.  It eludes me to why there is little thought given to this how aspect.  A suggestion without a method of how is purely empty and becomes some form of entitlement to push responsibility to others.

So, what am I missing? Is a limitation resulting from the choice of Host MCU? (I use the Intel Edison, so many resources there is no chance of limitations).  Is it the challenge of being able to see what can be done with nearly no resources? (choosing a Host MCU with 128 bytes - but then to push the responsibility for coding the handling of data changes with an onChange event onto someone else would truly defeat this kind of objective).  Maybe it is just an empty request and nothing should be thought more of it as it was never meant to be serious (in which case I stress for nothing).


Thanks for your replay.

I see, thats not only my problem.

>>A clear enhancement would be if the global variables had an onChange event.... 

>>I solved the update problem by putting a timer on each pages that is kicked on each update with tm0.en=1. 

I do the same, but i'm not happy with this;-)

>>I made a simple library for the Arduino based on this concept, see this post post

Mostly i do not work with arduino. But your lib sounds good.


>>With the click instruction you can make a procedure in the touch event of a hotspot like this:

I do exactly the same;-)

I think, Nextion still has a long way. But with a little improvisation i can use the display well.

Reiner, I have been struggling with the same issues.

Except for the variables, global or local don’t do what you expect from this property. You can read or write to a variable when it is set to global by putting the page name in front of it like page1.va2.val=10 from another page, but this doesn’t work for the rest of the components, click page1.m0,1 doesn’t work from any page as it will give you: Invalid Component ID. The same with the timers and as you found out, timers stop when the page goes out of focus.

A clear enhancement would be if the global variables had an onChange event. If that was available one could update the appropriate value on the current page (and put an update in the preinitialize event of the other pages) However there is no onChange event so I solved the update problem by putting a timer on each pages that is kicked on each update with tm0.en=1. So I write the temperature to a global variable and kick the timer to update the display. We now have a click instruction so I am going to swap the timer for a hotspot to get the same functionality without the 50 ms delay. I made a simple library for the Arduino based on this concept, see this post post

I also sent the temperature value as an integer in cC and convert the value to C with the modulo % operator. With the click instruction you can make a procedure in the touch event of a hotspot like this:


cov tmpint.val,tmptxt.txt,0
cov tmpint.val,tmptxt.txt,2

 This uses four variables, one for input, one for output and two for temp.

Now one could argue that the modulo operator is not documented but the rest of the arithmetic operators are also not documented.

This could be made redundant if the Number component is enhanced with a fake decimal point property ( hint :) )

1 person likes this
Hey, in closing:  There are many people that read these posts on this board to gain insite into how to make their project working.  If this tips are useful I am pleased to be able to contribute back (for you or the many others that will read these posts after).  Currently this site lacks good tutorials.

Two and a half hours ago your understanding of the sendme command and 0x66 replies:

>>In each page, you have a print ":state:#" printh ff ff ff

>>I get that this is your page number being sent On the MCU

i use a state machine and a "page change" must generate a "state change event". sendme sends only a number and the SM cant recognize that this is a page. 

Before that you need help on WaveForms add and addt commands

I may be misinterpreting, but your responses to the tips and advice seem like you no longer need help

So, this tutorial is over, and best of luck with your coding.

>>Choice one is to send that data into a black hole where it will be read, ignored and cleared

Yes, as long as I spend only data thats no problem. Like a broken (Touch)LCD.

>>Choice two is to receive the incoming data, interpret and respond.  

>>So a choice is being made to keep communication lines functioning.

Yes, thats the activ way.

But for the display i prefer the passive way. If i need activ data from the display, i can read it over UART.

Sure, you can write a lib, who's all objects reflected at the mcu. But that's not my intention.

I want a simple passive communication for simle application like temperatur sensor.

>>and the only time that hex 66 occurs as a leading byte value is ONLY when the next byte

Yes, i have see it.

>>NOTE: once sendme has been received and starts sending the Page Response there is no command to >>rescind it, it will always send.

An advantage of the state machine is that it ignores events, if they are of no interest in this status.

Okay, so you have posted just before me.   You have found the sendme in the Instruction Set and the corresponding Response codes.

Just NOTE: that the page response does not start automatically.  It will only start after the "sendme" command has been received and processed.  A good place to put this if you know you will always be using it throughout your design is in PageID 0 (pageConfig in your HMI) PreInitialize Event - add the line


Another NOTE: once sendme has been received and starts sending the Page Response there is no command to rescind it, it will always send.

As others read these boards looking for solutions, I am going to add for correctness

I stated:

> In each page, you have a print ":state:#" printh ff ff ff

> I get that this is your page number being sent On the MCU

> using the command sendme will accomplish the same

> The Nextion sends: 0X66 0X02 0XFF 0XFF 0XFF every page change once sendme command received.

> 0x66 - data following is page in response to sendme command. 0x02 - means page with id number 2

> has been selected - in your case dht2 has pageid 2 and 0xFF 0xFF 0xFF - data terminator

> as you are accustomed to already.

You responded:

> I use a state machine and a "page change" must generate a "state change event".

> sendme sends only a number and the SM cant recognize that this is a page.

For correctness:

If a connecting host MCU does not receive the bytes coming in over Rx/Tx from the Nextion, the functionality of the communications will break.  Therefore only two choices exist.  Choice one is to send that data into a black hole where it will be read, ignored and cleared (much like the linux port /dev/null when programming for the Internet protocols).  Choice two is to receive the incoming data, interpret and respond.  So a choice is being made to keep communication lines functioning.

You state your State Machine does not recognize this as a page. You are capturing the :state: as a page, so you are already receiving the data, interpreting and responding as you see necessary.  Choice 2.

Capturing ":state:0" as page 0, and ":state:1" as page 1 is implementing interpreting in your code already.

Nextion sends in hex "66 00 FF FF FF" as page 0, and "66 01 FF FF FF" as page 1, where hex 66 is ascii lowercase "f" ... and the only time that hex 66 occurs as a leading byte value is ONLY when the next byte represents the page ... means that interpreting this data and setting a state machine to page 0 or page 1 is easily accomplished. 

It means the mechanism is already in the Nextion Instruction Set and did not need to be reinvented.


>>sendme sends only a number and the SM cant recognize that this is a page.  

I have just found, i can use CURRENT_PAGE_ID_NUMBER_RETURN 0x66 instead.

Please don't misunderstand the break down as some sort of attack

As you stated that you are new and are still learning some of the commands and their use, to show you some examples and notated why or why not should be useful.  I could have attempted such in analogies and examples that had nothing to do with your project, but using your project provides you with a base of familiarity and possibly easier to see the connections put into practice.

Have fun coding.

Login or Signup to post a comment