425 Human Interface: Nextion Display - k3ng/k3ng_rotator_controller GitHub Wiki

Introduction

The K3NG Arduino Rotator Controller support Nextion displays. As of this writing the Nextion display functionality is in development on a Nextion NX4832TO35 3.5" display.

If you are unfamiliar with Nextion displays, this is an excellent tutorial on using them with Arduinos. Some of the steps below are covered in more detail in this tutorial.

Adam, VK4GHZ leads Nextion display development; Goody, K3NG, created and maintains the API described below.

https://vk4ghz.com/k3ng-rotator-controller-nextion-development/

Installation and Configuration

Please note that the Nextion Arduino library is not utilized by the Arduino Rotator Controller

  1. Download and install the Nextion Editor. Unfortunately there is no Mac OSX or Linux version. I run it within Windows 10 on a VirtualBox virtual machine on a MacBook with no issues. You can skip installing Nextion Editor if you want to use a pre-compiled TFT file and aren't going to customize your display (see next step).

  2. Select an HMI file, compile a TFT file, and install on your Nextion display. This is covered in detail in this tutorial. Various pre-built HMI files which define the Nextion screen are in the Nextion directory from the K3NG Arduino Rotator Controller GitHub download. The Nextion_HMI_Files directory also contains font .ZI files and pre-compiled TFT files.

  3. Uncomment this line in your features file and save (default file: rotator_feature.h )

    #define FEATURE_NEXTION_DISPLAY

  4. In your settings file, update this line to reflect the Arduino serial port you are going to connect your Nextion to:

    #define nexSerial Serial3

Note that this line should normally be set for 115200 baud:

#define NEXTION_SERIAL_BAUD 115200  
  1. Physically connect your Nextion display to the Arduino. Using the wiring harness supplied with the Nextion display:

Red: +5V

Black: Ground

Yellow: Serial TX on the Arduino (Settings file defaults to Serial3, so pin TX3)

Blue: Serial TX on the Arduino (Settings file defaults to Serial3, so pin RX3)

  1. Compile and upload the code to the Arduino. Shortly after boot up the Nextion display should show a "K3NG Rotator Controller" splash screen and then go to the Main display page.

HMI Files

As of this writing, one HMI display definition file is being developed. This contains the foundational API variables for building customized displays.

Creating or Customizing A Display

Integration of the Nextion display is implemented via the use of several "API variables". The BASE HMI file in the Github repository provides API variable definitions and a sample Nextion user interface implementation. This HMI file can be used as is, or customized. If a user wants to create a new Nextion HMI file, the variable definitions that are in the BASE HMI file API page, along with the global variables in Program.s (prefixed with a 'g'), should be copied to the new HMI file. (If it is desired to create a new display definition, it's highly recommended and more convenient to use the BASE HMI file as a starting point and delete all the pages except for the API page.)

API Variables

vSS1        String[32]            Status String 1 - Most important status messages relating to rotation and targets

vSS2        String[16]            Status String 2 - Parking, Parked, Overlap messages

vSS3        String[16]            Status String 3 - Deprecated as of version 2020.08.12.01

vAz         String[6]             The real azimuth heading in degrees (0.00 - 360.00)

gAz         Integer               The real azimuth heading in degrees, integer
                                    (0 - 360, no decimal places)

gAzR        Integer               The raw azimuth heading in degrees, integer
                                    (0 - 450, no decimal places)

vEl         String[6]             The elevation in degrees (0 - 180)

gEl         Integer               The elevation in degrees, integer
                                    (0 - 180, no decimal places)

gX          Integer               Heading Cartesian coordinates - X (0,0 is upper left; 180,180 is lower right)

gY          Integer               Heading Cartesian coordinates - Y

gAOS        Integer               Azimuth overall status
                                        NOT_DOING_ANYTHING 0
                                        ROTATING_CW 1
                                        ROTATING_CCW 2

gADS        Integer               Azimuth detailed status
                                        IDLE 0
                                        SLOW_START_CW 1
                                        SLOW_START_CCW 2
                                        NORMAL_CW 3
                                        NORMAL_CCW 4
                                        SLOW_DOWN_CW 5
                                        SLOW_DOWN_CCW 6
                                        INITIALIZE_SLOW_START_CW 7
                                        INITIALIZE_SLOW_START_CCW 8
                                        INITIALIZE_TIMED_SLOW_DOWN_CW 9
                                        INITIALIZE_TIMED_SLOW_DOWN_CCW 10
                                        TIMED_SLOW_DOWN_CW 11
                                        TIMED_SLOW_DOWN_CCW 12
                                        INITIALIZE_DIR_CHANGE_TO_CW 13
                                        INITIALIZE_DIR_CHANGE_TO_CCW 14
                                        INITIALIZE_NORMAL_CW 15
                                        INITIALIZE_NORMAL_CCW 16

gEOS        Integer               Elevation overall status
                                        NOT_DOING_ANYTHING 0                                            
                                        ROTATING_UP 3
                                        ROTATING_DOWN 4   

gEDS        Integer               Elevation detailed status
                                        IDLE 0
                                        SLOW_START_UP 1
                                        SLOW_START_DOWN 2
                                        NORMAL_UP 3
                                        NORMAL_DOWN 4
                                        SLOW_DOWN_DOWN 5
                                        SLOW_DOWN_UP 6
                                        INITIALIZE_SLOW_START_UP 7
                                        INITIALIZE_SLOW_START_DOWN 8
                                        INITIALIZE_TIMED_SLOW_DOWN_UP 9
                                        INITIALIZE_TIMED_SLOW_DOWN_DOWN 10
                                        TIMED_SLOW_DOWN_UP 11
                                        TIMED_SLOW_DOWN_DOWN 12
                                        INITIALIZE_DIR_CHANGE_TO_UP 13
                                        INITIALIZE_DIR_CHANGE_TO_DOWN 14
                                        INITIALIZE_NORMAL_UP 15
                                        INITIALIZE_NORMAL_DOWN 16

vClk        String[13]            The clock time

gCS         Integer               Clock Status
                                        FREE_RUNNING 0 
                                        GPS_SYNC 1
                                        RTC_SYNC 2
                                        SLAVE_SYNC 3
                                        SLAVE_SYNC_GPS 4  
                                        NOT_PROVISIONED 255

vGPS        String[16]            GPS Status

vGrid       String[6]             Grid Locator

vCrd        String[25]            Coordinates

gGF         Integer               GPS fix age in mS

gVS         Integer, Bit Mapped   Various States
                                        Bit Values
                                           brake_az_engaged 1  
                                           brake_el_engaged 2   
                                           az_request_queue_state
                                             IN_QUEUE 4
                                             IN_PROGRESS_TIMED 8
                                             IN_PROGRESS_TO_TARGET 16
                                           el_request_queue_state
                                             IN_QUEUE 32
                                             IN_PROGRESS_TIMED 64
                                             IN_PROGRESS_TO_TARGET 128
                                           park_status
                                             PARK_INITIATED 256
                                             PARKED 512
                                           autocorrect_state_az
                                             AUTOCORRECT_WAITING_AZ 1024
                                             AUTOCORRECT_WATCHING_AZ 2048
                                           autocorrect_state_el
                                             AUTOCORRECT_WAITING_AZ 4096
                                             AUTOCORRECT_WATCHING_AZ 8192
                                           overlap_indicator 16384
                                           autopark_active 32768
                                           configuration_dirty 65536

gV2         Integer, Bit Mapped   Various States 2, The Sequel
                                        Bit Values
                                          audible_alert_enabled 1

gSC         Integer, Bit Mapped   System Capabilities  (variable definition is in Nextion Program.s)
                                        Bit Values
                                           GS_232A 1
                                           GS_232B 2
                                           EASYCOM 4
                                           DCU_1 8
                                           ELEVATION 16
                                           CLOCK 32
                                           GPS 64
                                           MOON 128
                                           SUN 256
                                           RTC 512  
                                           SATELLITE 1024
                                           PARK 2048
                                           AUTOPARK 4096
                                           AUDIBLE_ALERT 8192

gL         Integer, Bit Mapped  Language    
                                           ENGLISH 1
                                           SPANISH 2
                                           CZECH 4
                                           PORTUGUESE_BRASIL 8
                                           GERMAN 16
                                           FRENCH 32

vMAS         String[6]             Moon Azimuth String

vMES         String[6]             Moon Elevation String          

vSAS         String[6]             Sun Azimuth String

vSES         String[6]             Sun Elevation String 

vSAT         String[16]            Current Satellite Name

vTAS         String[6]             Satellite Azimuth String

vTES         String[6]             Satellite Elevation String 

vTLA         String[7]             Satellite Latitude String

vTLO         String[7]             Satellite Longitude String

vADF         String[11]            Satellite Next AOS Full Date String (YYYY-MM-DD)

vADS         String[5]             Satellite Next AOS Short Date String (MM-DD)

vATS         String[5]             Satellite Next AOS Time String (HH:MM)

vLDF         String[11]            Satellite Next LOS Full Date String (YYYY-MM-DD)

vLDS         String[5]             Satellite Next LOS Short Date String (MM-DD)

vLTS         String[5]             Satellite Next LOS Time String (HH:MM)

vALI         String[13]            Satellite AOS/LOS In String (Examples: "AOS in 1d13h","LOS in 30m12s","LOS in 5s")

vS1-vS34     String[15]            Satellite #x in Stored TLEs (x = 1 to 34, 34 variables total)
                                   (Sample Data: "AO-07" Available for tracking with \$ command.  Example Cmd: "\$AO-070x0D" )

vSatNx       String                List of satellites next AOS, Satellite Name; x = 1 to NEXTION_NUMBER_OF_NEXT_SATELLITES setting
                                   Example: "AO-07"

vSatOx       String                List of satellites next AOS, AOS / LOS string; x = 1 to NEXTION_NUMBER_OF_NEXT_SATELLITES setting
                                   Example: "AOS in 5m"

vSatAx       Integer               List of satellites next AOS; Satellite AOS status; x = 1 to NEXTION_NUMBER_OF_NEXT_SATELLITES setting
                                   0 = Not in AOS, 1 = In AOS

gMSS         Integer, Bit Mapped   Moon, Sun, and Satellite Status
                                        Bit Values
                                           moon_tracking_active 1
                                           moon_visible 2
                                           sun_tracking_active 4
                                           sun_visible 8
                                           satellite_tracking_active 16
                                           satellite_visible 32

gDP          Integer               Number of decimal places used in various heading variables (set by DISPLAY_DECIMAL_PLACES)

vPA          Integer               Park azimuth setting

vPE          Integer               Park elevation setting

vAT          Integer               AutoPark time setting, in minutes

gTS          Integer               Satellite tracking check interval (mS)

gTU          Integer               Sun tracking check interval (mS)

gTM          Integer               Moon tracking check interval (mS)

gTX          Integer               Satellite tracking rotation interval (mS)

gTY          Integer               Sun tracking rotation interval (mS)

gTZ          Integer               Moon tracking rotation interval (mS)

vTA          String[5]             Satellite tracking degrees difference threshold

vTB          String[5]             Sun tracking degrees difference threshold

vTC          String[5]             Moon tracking degrees difference threshold

vConResult   String                Result of backslash commands sent to the Arduino

vRCVersion   String                The Arduino Rotator Controller's code version 

vRCAPIv      Integer               The Arduino Rotator Controller's API version (DEPRECATED IN VERSION 2020.09.01.03)

It is not necessary to copy all API variables to all display pages, however it's highly recommended. The reason for this is that the Arduino Rotator Controller attempts to periodically update all API variables, regardless of what display page is active or what API variables exist on that page. Attempts to update an API variable that doesn't existing on a page results in the Nextion display returning an error code back to the Arduino. This is not a fatal event but creates additional unnecessary serial port traffic.

Currently the Arduino Rotator Controller does not trap and/or recognize error codes coming from the Nextion display.

Commands from the Nextion display to the Arduino Rotator Controller are accomplish through backslash commands. Controls should use the Nextion prints and printh commands to send commands to the Arduino via the serial port. Commands must be terminated with a carriage return (decimal 13 / 0x0D). Here is sample Nextion code for implementing a CCW (rotate left) button:

prints "\\?RL",0
printh 0D

This code would be placed in the Touch Press or Touch Release event of the button to send the serial data when the user interacts with the Nextion display button.

Backslash commands are documented here.

The output from backslash commands is returned immediately via the vConResult string API variable.

Start Up

Upon startup the display can / should send the ?NG command. This will prompt the Arduino to immediately send the gSC variable, giving the Nextion display the necessary information to determine what features are activated in the Arduino, and adjust the user interface accordingly.

User Contributions

The provided HMI display definition files are examples, fully functional and usable in production. However, there is so much more than can be done using the Nextion displays, and it's difficult to satisfy everyone's needs. Creative radio artisans can undoubtedly more elaborate displays that other users may find useful. If you create a customized display, please consider contributing it so others may benefit from it. You will receive credit and kudos from your fellow radio artisans.

Debugging and Troubleshooting

Uncomment the following lines in rotator_debug_log_activation.h:

#define DEBUG_NEXTION_DISPLAY
#define DEBUG_NEXTION_DISPLAY_SERIAL_SEND
#define DEBUG_NEXTION_DISPLAY_SERIAL_RECV

Notes

Do not attempt to use this display with an Arduino Uno or Nano. Just. Don't. You need a serial port dedicated to the Nextion display serial port, so it would be difficult from a hardware perspective to do. (SoftwareSerial is buuuuuugy.) Also, the regular and extended backslash commands are required in the Rotator Controller. These eat up a lot of memory.

It is highly recommended to use an external 5 volt power supply to power your Nextion display. Avoid using the Arduino 5 volt power, unless perhaps you're powering the Arduino with an external power supply and not just USB power. (I haven't tried this, your mileage may vary, not responsible if you damage something.)

The Nextion display can be used in parallel with an LCD display. Not sure why anyone would want to do this for a production system, but it can be put in place during Nextion display development to provide additional user feedback and help troubleshoot Nextion GUI issues.

Design Choices

In case K3NG gets hit by a bus and someone wonders why certain design choices were made, here are some notes...

  • After three development iterations consuming a lot of time were done and lots of hair was pulled out, it was decided to forgo using the Nextion Arduino library. The need to define each Nextion object the Arduino touches was maddening. Having to link Nextion object IDs made creating an API so that users could easily create their own displays made things very klunky

  • I had problems with lost Nextion display events using the Nextion Arduino library. After diving in the Nextion Arduino library code, I found what I think was the culprit. When a command is sent from the Arduino to the Nextion unit using the library, the command send routine dumps any bytes sitting in the Arduino serial send buffer. So if a Nextion display event occurs while a command is being sent by the Arduino to the Nextion unit, the event is lost.

  • I could not get the Nextion 'get' command to work via the serial port and ended up using prints.

  • The API variable objects in the Nextion unit are defined as local variables and placed on all pages. I originally tried to implement these as global and kept them just in the API page, however I discovered that global variables cannot be written to by serial port commands unless the Nextion page containing them is currently displayed. WHY????? They're global variables, for f---- sake. Global variables defined in Program.s can be accessed via the serial port at any time, so some of the API variables are implemented there (these are prefixed with a 'g', rather than a 'v' like the local variable objects are). However, I was not able to read a global variable defined in Program.s via the serial port.

  • The Nextion IDE doesn't let you change object IDs and if you delete an object it renumbers all the object IDs of objects created after the deleted object. WHY????? This is another reason trying to create a stable API that was easy for users to use was nearly impossible with the Nextion Arduino library.

  • I had a few instances where the Nextion IDE Debug simulation didn't match what the hardware would do in real life. I didn't keep a list, but keep this in mind when you're developing a new display definition. You're not crazy. Some things that work as expected in the simulator won't work on your display.

  • Nextion documentation is hokey.