Universal UI on-screen help framework for Nextion HMI

How it began…

In the Nextion user forums, a participant from Europe, let’s call him M., asked an interesting question. What he wants to achieve is activating a “Help” mode on his Nextion project. That means that after activating this help mode, the user would click on an arbitrary component and instead of executing the component’s event code, a help screen with explanations would be displayed.

Since in his project, there are nearly 1000 components on several screens, reworking each single component’s event code to decide if the event code should be executed or the help screen displayed, is definitively not an option. So, he thought that he’d use a TouchCap component to intercept the event chain before the component’s own event code was executed, to decide if, in case the help mode was active, the help screen would be displayed. But his problem was that the component’s own TouchPress and/or TouchRelease event code would still be executed afterwards, probably going to a different page, which would prevent displaying the help text correctly.

Basically, the challenge is to branch or break the Nextion’s event chain before each component’s unmodified event code is executed. And as far as it is known, the only way to do so is to unload the current page and to display another one. But how to do this in a way that it looks and feels like a help screen popping up?

The universal help page is born

My idea was to use a nice effect of the Nextion’s firmware which makes that if a page whose .sta attribute is set to “no background” is loaded, the previous page remains visible and serves as a background image. If, on this transparent page, we place two text components, one as a title bar, and another bigger one as a container to display the actual help text, it can be made to look like a nice popup window. The text component for the help text would need to be global, so that on the calling page, if the “help” mode is active, a TouchCap component can already set the help text beforehand as soon as a component is clicked. Remember, the TouchCap’s .val attribute holds the id of the last clicked component which allows to identify it. Then, before being called, the help page will also have to know to which page it will have to return when the help screen is closed. For this, there is a simple and invisible but global variable component called retpage on the help page which will also have to be set before our help page is displayed.

Now, all we still need is a way to close the help screen and to return to the calling page. For this, similar to how many things work nowadays on mobile devices, you’ll have to click in the empty space around the virtual popup window. This will trigger a TouchPress event for the help page itself, even if it is transparent in that zone. And that’s all the code on the help page:

help (Page) Touch Press Event (1)
page retpage.val

Now, to the calling page(s)

As requested, we will not touch at the components on the calling page(s), nor at their event code. But we have to add several things (to each, if we want to call the help from multiple pages): First, we need a dual state button which we name hb like help button. By default, it is not pressed, thus its value is 0. When the user activates it by pressing it, it changes its color and its value becomes 1. This allows our TouchCap component to “see” if the help mode is active. Then, it has also to exclude any “help” action for the hb button itself, so that the user can disable the help mode by clicking it again without getting a help screen displayed. Next is to tell the help page the id of the calling page. Then, the corresponding help text has to be found, depending on the clicked component, and copied over the the help screen’s text display component, which we named tw like text window.

Where do the help texts come from? Instead of a multitude of if / else if / else if /… in the TouchCap’s event code, I decided to place a huge text container, a local variable component whose .sta is “String” and whose .txt_maxlen is big enough to hold all the texts and to place all the help texts there, separated by a vertical bar “|”. Thus, it looks symbolically like Help text for component with id 1|Help text for component with id 2|Help text for component with id 3 and so on. Thanks to the spstr function, we can now address all the texts as if they were in an array and we use the TouchCap’s .val attribute to get the index, not without subtracting 1 because the indexing of the spstr function is zero-based.

And that’s it. Once the help mode activated by clicking the hb button, and then clicking an arbitrary component (other than the hb button) will cause the TouchCap to execute the code as follows:

tc0(TouchCap) Touch Press Event (6)
  help.retpage.val=dp  // set the page id to return to
  spstr ht.txt,help.tw.txt,"|",tc0.val-1  // retrieve and set the help text for the actually clicked component
  page help // branch to help page which will break event code execution

Once the help button hb the TouchCap tc0 designed on one page, they can simply the copied over to as many pages as you like. The only thing which has not only to be copied over but also to get a customized .txt attribute with the help texts for the components on that specific page is the ht help text variable.

One demo project says more than 1000 words

That’s why I made a small demo project. It has, besides the help page, a single page with some components. Some simple text labels, a number component to display a numeric color code, a text field without text whose .bco attribute shows the corresponding color to the number above, and 3 buttons for red, green, and blue with individual event code (for demo’s sake) which allow to toggle the corresponding color component.

And there is naturally the help button in the top right corner.

When playing with this demo, you’ll see that you can easily modify the whole help system’s behavior to taste: If you leave the hb button’s .vscope to “local”, the help mode is again disabled after returning from the help screen because the calling page is reloaded and hb.val will return to its default value which is 0. But if you make it global, it will keep its state and the help mode will remain active when returning from the help page – until you disable the help mode manually by clicking again ob the hb button.

Here is the .hmi file to play with: help-demo.HMI

For today, thank you for reading and happy Nextioning!

Questions, comments, critics, suggestions? Just send me an email to thierry (at) itead (dot) cc! 🙂

And, by the way, if you like what I write, and you are about to order Nextion stuff with Itead, please use my referral link! To you, it won’t make a change for your order. But it will pay me the one or the other beer or coffee. And that will motivate me to write still more interesting blogs 😉