The Sunday Blog: The enhanced “K” HMIs

Part1: RTC and GPIO

First of all: Happy 2021 to all my readers! And thank you for all your constructive suggestions and remarks regarding this blog!

There is a huge positive feedback for the previous episodes where we started developing an ultra-compact alternative universal Nextion library for Arduino which overcomes some restrictions of the official library. For example the ability to handle multiple Nextion HMIs on one single MCU and without needing a specific object for each component type, and, and and… I for myself do not yet know how far this will finally go.

But there are also other readers who wrote me that they were more interested in learning about the advanced use of the Nextion programming language. Although nearly everybody seems happy that everything I told and taught over the last 30 episodes runs on a standard “T” HMI, including very advanced mathematics and drawing algorithms, people want to know what the enhanced models bring in addition, besides more memory.

Thus, I decided to write one week about specific and advanced Nextion features and every other week, we’ll move on with our newNextion library.

Nextion GPIO basics

The enhanced or “K” series HMIs have 8 GPIO ports. These are not easy to see at a first glance, they are accessible through a 10pin flat ribbon cable connector on the opposite edge from the power and Serial connector. To make the GPIO ports easily accessible, there is the small Nextion IO Adapter which comes with the needed cable and gives you the 8 GPIO pins plus 5V and GND on a 10pin header with 2.54mm spacing. If you want a ready-to-use extension, go rather for the Nextion Expansion board, which gives you 6 push buttons, connected to pio0 to pio5, a LED on pio6 and a buzzer on pio 7.

Nextion IO Adapter

Nextion IO Adapter

Nextion Expansion Board

Nextion Expansion Board

The pins can be individually configured as input (pull-up), output (push-pull), bound input, PWM and output (open drain). The cfgpio command will help us with this. We’ll see that later in this article.

Nextion RTC basics

The RTC of the enhanced or “K” models is simple to use. There are 7 system variables from rtc0 (year) to rtc6 (dayOfTheWeek) which can easily be read and written. It’s just important to place a CR1220 battery into the holder on the Nextion’s back side. It keeps the RTC running even when the main power is off.

Today’s demo project

We’ll start with displaying the RTC values. The HMI file for the Enhanced 3.5″ Nextion HMI NX4832K035_11 can be downloaded here: rtc_gpio_demo.HMI . For this purpose, there are 6 number fields for the year, month, day, hour, minute and second. It’s just important that these keep under all circumstance the consecutive id values from 1 to 6 to allow indirect addressing later, when we’ll adjust the clock. To make it easier to read, I put short text components containing a “/”, a “-“, or a “:” in-between. For updating the display by the current time, we use a timer component which updates the 6 number fields every 333ms (thus 3 times per second), using the following simple event code:

n0.val=rtc0
n1.val=rtc1
n2.val=rtc2
n3.val=rtc3
n4.val=rtc4
n5.val=rtc5

To adjust our clock, we use 6 buttons on the GUI in a similar pattern as on the Nextion Expansion board. We give them (here for the demo purpose) identical captions: Up, Down, Left, Right, Esc, and Enter. We’ll use these as follows:

  • Enter enters the setting mode and points towards the first field, setting sys0 to 1
  • Esc leaves the setting mode, setting sys0 to 0
  • Right moves the pointer to the next field, increasing sys0 by 1, but not beyond 6
  • Left moves the pointer to the previous field, decreasing sys0 by 1, but not below 1
  • Up increases the current field by 1
  • Down decreases the current field by 1

The 6 corresponding buttons of the expansion board are simply bound by the following series of cfgpio commands in the page Post-Initialization event to the corresponding screen buttons:

cfgpio 4,1,b0 //up
cfgpio 3,1,b1 //down
cfgpio 5,1,b3 //left
cfgpio 2,1,b2 //right
cfgpio 0,1,b4 //esc
cfgpio 1,1,b5 //enter

Out of that, we want some additional functionality:

  • Entering the setting mode shall light the LED on the Expansion Board, exiting shall switch it off.
  • Each button press shall give us a short beep from the buzzer if it is meaningful, or a long beep if it’s erroneous. An error should occur for example when pressing one of the Left, Up, Right, or Down buttons without having entered the setting mode before.

So, we need to set up pio6 for the LED and pio7 for the buzzer as output by adding the following to the Page PostInitialize event:

cfgpio 7,2,0 //beeper
cfgpio 6,2,0 //led

Since we do not like repetitive code, we “hide” the subroutines for short and long beeps in the Touch Press and Touch release events of a small hidden m0 hotspot. Placed in the bottom left corner of the screen. Thus, we can “call” a short beep with “click m0,0” and a long beep with “click m0,1”

//short beep (ok) in m0 Touch Release
pio7=1
delay=50
pio7=0
//short beep (ok) in m0 Touch Press
pio7=1
delay=50
pio7=0

The text color (pco) of our RTC number fields is white by default. We want to change the active field to cyan. Since sys0 keeps all the info (0 => no setting, 1-6 => setting the corresponding variables rtc0 to rtc5), we need another subroutine which actualizes the text color and enables or disables the LED. A second hidden miniature hotspot m1 acts as a container in its Touch Release event:

//m1 Touch Release
for(sys2=1;sys2<7;sys2++)
{
  if(sys2==sys0)
  {
    // Set the active field's pco to cyan
    b[sys2].pco=24283
  }else
  {
    // Set all but the active field's pco to white
    b[sys2].pco=65535
  }
}
if(sys0==0)
{
  pio6=0 // LED off: no edit
}else
{
  pio6=1 // LED on: edit mode
}

Now the Touch Press event code for the Enter button:

if(sys0>0)
{
  //edit mode was already entered
  click m0,1 //long beep
}else
{
  click m0,0 //short beep
  sys0=1 //set edit mode on year field
}
click m1,0 //update field's pco and LED

… and for the Esc button:

if(sys0>0)
{
  sys0=0 // set edit mode off
  click m0,0 //short beep
}else
{
  //we weren't in edit mode...
  click m0,1 //long beep
}
click m1,0 //update field's pco and LED

The Right button:

if(sys0>0&&sys0<6)
{
  sys0++ // move to next edit field
  click m1,0 //update field's pco and LED
  click m0,0 //short beep
}else
{
  click m0,1 //long beep
}

… and the Left button:

if(sys0>1)
{
  sys0-- //move to previous edit field
  click m1,0 //update field's pco and LED
  click m0,0 //short beep
}else
{
  click m0,1 //long beep
}

Now the Up button. The code is slightly longer because of the indirect addressing of rtc0-rtc5, which depends on sys0’s value:

//Increase value of the current field
if(sys0==1)
{
  rtc0++
}else if(sys0==2)
{
  rtc1++
}else if(sys0==3)
{
  rtc2++
}else if(sys0==4)
{
  rtc3++
}else if(sys0==5)
{
  rtc4++
}else if(sys0==6)
{
  rtc5++
}
if(sys0==0)
{
  click m0,1 //long beep (error)
}else
{
  click m0,0 //short beep (ok)
}

… and similar for the Down button:

//Decrease value of the current field
if(sys0==1)
{
  rtc0--
}else if(sys0==2)
{
  rtc1--
}else if(sys0==3)
{
  rtc2--
}else if(sys0==4)
{
  rtc3--
}else if(sys0==5)
{
  rtc4--
}else if(sys0==6)
{
  rtc5--
}
if(sys0==0)
{
  click m0,1 //long beep (error)
}else
{
  click m0,0 //short beep (ok)
}

That’s it! You see, handling the RTC and GPIO is very easy! And the best is: You don’t have the Expansion Board or the IO Adapter? No worries, this HMI will work without, using the bound screen buttons. You’ll just not have the beeps and the LED…

Thank you for reading, have a nice week!