A guide for receiving and sending
commands from Nextion displays


If this is your first getting in touch with Nextion, before continuing, you must read the:
Nextion Editor Guide, by following the link. https://nextion.tech/editor_guide/
Or from Nextion Editor, by clicking the “Help” button on the top left corner and then, clicking the “Editor Guide” option button.
For using Nextion displays we have to deal with two things:


Contents:


  • How we send commands to Nextion and what commands can we send? ...Go to
    • The Design Editing commands ...More
    • The Nextion Instruction Set is the second command category ...More
  • The way to Send commands (Return Data) from Nextion to MCU (Arduino in most cases) ...Go to
    • Commands print and prints ...More
    • Command printh ...More
    • Nextion’s Return Data protocol format ...More

How we send commands to Nextion and what commands can we send?


"The various combinations of attribute choices provide a wide range of expected behaviors with many combinations.
This combined with the Nextion Instruction Set creates the opportunity for very powerful HMIs."


There are 2 categories of commands:

  • The Design Editing commands
  • The Nextion Instruction Set command category


NOTE: As these commands are using the Serial port to read and write, it is more preferred not to run them in the loop() without delay(); or some other method of not running them with the frequency of the loop and use them only when it is needed.
Using them in a loop, a delay in the loop can be noticed, especially when reading from the Serial. A Serial buffer overflow can also be caused.

Also NOTE: (From the Nextion Editor Guide) “ In an HMI project a page is a localized unit. When changing pages, the existing page is removed from memory and the > > requested page is then loaded into memory. As such components with a variable scope of local are only accessible while the page they are in is currently loaded. Components within a page that have a variable scope of global are accessible by prefixing the page name to the global component .objname. As an Example: A global Number component n0 on page1 is accessed by page1.n0. A local Number component n0 on page1 can be accessed by page1.n0 or n0, but there is little sense to try access a local component if the page is not loaded. Only the component attributes of a global component are kept in memory. Event code is never global in nature.”


1. The Design Editing commands

Those commands are used to chance the attribute of the components (button, text box, timer, numeric etc.) while Nextion is on run.
NOTE: Any attribute in green can be both read and changed by user code at runtime.
NOTE: Any attribute in black is read only at runtime (with the exception of .objname which remains inaccessible). Attribute panel

When we change it from Nextion’s side and the component is part of the loaded page, we can send the command from the User’s Event Code on Touch Event (Press or Release) of almost any component from the same page.

We can change the attribute of a component, either from Nextion or from MCU by following this rule:
<component name>.<attribute>=<value>


How we change those attributes from Nextion’s side and from MCU’s usually Arduino

Example: in the Touch Release Event of a button write this user code and every time the button is Released (after a Press) the code will executed

Command
Result on n0 comp.
<n0.val=30>
Sets n0 component’s value to 30
<n0.bco=63488>
Sets background color to red
<n0.font=0>
Sets font to font style with ID 0
<n0.pco=1055>
Sets font color to blue
<n0.format=0>
Sets value format to decimal

For TEXT attribute: If attribute is text, the value must be inside <" "> quotes.

Command
Result on n0 comp.
< t3.txt="HELLO" >
Sets t3 comp. Text value to HELLO

TIP: we prefer to write user code in Touch Release Event for give us time to see that the button is pressed as the button will chance color when pressed.

TIP: The exact names of the attributes and the values they can get, can be found on Nextion Editor at the attribute menu of any object when select the attr.
Also, a syntax help menu is shown when we start typing the command on Nextion Editor

To access a global component’s attributes on another page, we must prefix the component’s page number.
Example: < page0.n0.val=30 >

When we change Nextion’s attributes from Arduino’s (MCU) side, the commands are complete the same and they have the same syntax. To send them through the Serial port, we use the powerful C++ command of Serial.print as all instructions and parameters on Nextion are in ASCII

Example:

Serial.print(“n0.val=30”);
Serial.print(“n0.bco=63488”);
//etc.

NOTE: All instructions on Nextion over serial, are terminated with three bytes of 0xFF 0xFF 0xFF
So, we must send those 3 bytes after every command that we sent to Nextion.
We prefer to send the bytes in ASCII format with < Serial. print(“\xFF\xFF\xFF”); >

Example:

Serial.print(“n0.val=30”);
Serial.print(“\xFF\xFF\xFF”);

NOTE: If attribute is text, the value must be inside <" "> quotes
If we want to send to component t3 the text < HELLO > the command for Nextion is < t3.txt="HELLO" >.
From Arduino, we write < Serial.print("t3.txt=\"HELLO\"");>

Serial.print("t3.txt=\"HELLO\"");
Serial.print(“\xFF\xFF\xFF”);

When we type <\"> means that <"> is a character and it's going to print it over serial as ASCII character. Else <"> is a STRUCTURE.


The various combinations of attribute choices provide a wide range of expected behaviors with too many combinations to cover in any manual(s).
This combined with the Nextion Instruction Set creates the opportunity for very powerful HMIs.
Nextion Editor Guide


2. The Nextion Instruction Set is the second command category

What is the instruction set:
“An instruction set, also called ISA (instruction set architecture), it is a group of commands for a CPU in machine language. The term can refer to all possible instructions for a CPU or a subset of instructions to enhance its performance in certain situations.
All CPUs have instruction sets that enable commands to the processor directing the CPU to switch the relevant transistors. Some instructions are simple read, write and move commands that direct data to different hardware. An example of an instruction set is the x86 instruction set, which is common to find on computers today.”
Source: https://whatis.techtarget.com/definition/instruction-set
Nextion uses a simple and complete instruction set that can be found Here: https://nextion.tech/instruction-set/

The Nextion Instruction Set

These are the set of commands that Nextion can use.
They are categorized into only a few categories

A Legend is used in front of every command to show in which display model referred

Basic
Basic
Basic
Enhanced
Basic
Intelligent
Basic
All
Basic
Basic And Enhanced
Basic
Enhanced And Intelligent

The most used set is the Operational commands. In there, we can find Description and Usage/Parameters/Examples for all the commands.
These commands can be used just like the Design Editing commands that we mentioned above.
NOTE: The ONLY commands that we cannot send from Arduino side (MCU), are: <if>, <while>, <for>, as their block of code is enclosed within braces { }.

Nextion's side
Arduino's side
Result
page 1
Serial.print(“page 1”);
Serial.print(“\xFF\xFF\xFF”);
0 Loads page 1 in Nextion
ref 0
Serial.print(“ref 0”);
Serial.print(“\xFF\xFF\xFF”);
Refreshes all components on the current page
click b0,1
Serial.print(“click b0,1”);
Serial.print(“\xFF\xFF\xFF”);
Trigger Touch Press Event of component with .objname b0

With the above rule, every command can be used, for either Operational Commands or GUI Designing Commands.


The way to Send commands (Return Data) from Nextion to MCU
(Arduino in most cases)


To send Data over Serial, Nextion uses 3 commands: print, prints and printh we are not going to engage with get and sendme commands as they use Nextion’s Return Data format.

print command Parameter Count: 1

Send raw formatted data over Serial to MCU
print/printh do not use Nextion Return Data, user must handle MCU side
– quantity of data may be limited by serial buffer (all data < 1024)
– numeric value sent in 4 byte 32-bit little endian order
value = byte1+byte2*256+byte3*65536+byte4*16777216
– text content sent is sent 1 ASCII byte per character, without null byte.
Usage:
print attr
attr is either component attribute, variable or constant
print t0.txt // return 1 byte per char of t0.txt without null byte ending
print j0.val // return 4 bytes for j0.val in little endian order
print “123” // return 3 bytes for text “123” 0x31 0x32 0x33
print 123 // return 4 bytes for value 123 0x7B 0x00 0x00 0x00

prints command Parameter Count: 1

Send raw formatted data over Serial to MCU
– prints does not use Nextion Return Data, user must handle MCU side
– qty of data may be limited by serial buffer (all data < 1024)
– numeric value sent in 4 byte 32-bit little endian order
value = byte1+byte2*256+byte3*65536+byte4*16777216
– text content sent is sent 1 ASCII byte per character, without null byte.
Usage:
print attr
attr is either component attribute, variable or constant
prints t0.txt,0 // return 1 byte per char of t0.txt without null byte ending
prints t0.txt,4 // returns first 4 bytes, 1 byte per char of t0.txt without null byte ending.
prints j0.val,0 // return 4 bytes for j0.val in little endian order
prints j0.val,1 // returns 1 byte of j0.val in little endian order
prints “123”,2 // return 2 bytes for text “12” 0x31 0x32
prints 123,2 // returns 2 bytes for value 123 0x7B 0x00

printh command Parameter Count: 1

Send raw byte or multiple raw bytes over Serial to MCU
– printh is one of the few commands that parameter uses space char 0x20
– when more than one byte is being sent a space separates each byte
– byte is represented by 2 of (ASCII char of hexadecimal value per nibble)
– qty may be limited by serial buffer (all data < 1024)
– print/printh does not use Nextion Return Data, user must handle MCU side
Usage: printh <hexhex>[<space><hexhex>]...[<space><hexhex>]
<hexhex> is hexadecimal value of each nibble. 0x34 as 34
<space> is a space char 0x20, used to separate each <hexhex> pair
printh 0D // send single byte: value 13 hex: 0x0d
printh 0D 0A // send two bytes: value 13 10 hex: 0x0D0x0A


All three looks the same? They are NOT the same for sure.
print and prints commands:

print and prints have the same functionality and the only difference is that with prints we can define the length, means the number of bytes to send.
numeric value sent in 4 byte 32-bit little endian order
value = byte1+byte2*256+byte3*65536+byte4*16777216
– text content sent is sent 1 ASCII byte per character, without null byte.
– They both can extract either component attribute, values, variable or Constant
With print t0.pco will take as result 4 bytes in hex, as a numeric value representing the font color 1F 04 00 00 for blue
value = 31+4*256+byte3*65536+byte4*16777216 => value=1055
– Both can send either numeric values or Text contents, but they CANNOT send a combination of numbers and text. – “text content sent is sent 1 ASCII byte per character”, that means:
That is going to send the hexadecimal represent as a character of the ASCII character set
print “1” has a return of 0x31, that is the hexadecimal represent of digit 1 as character.
The hexadecimal represent of decimal number 1 is the 0x01
The above are the meaning of “Send raw formatted data over Serial to MCU”, when the value is a number, the bytes have a raw format of 32-bit little endian order, and when the value is text content, they formatted to represent the ASCII character set.


printh command:

With printh we do not have the ability to extract values, but we can send up to 1024 raw bytes and not row formatted, in a clear hexadecimal format using a space to separate them.
It is obviously that every byte can represent a number or character.
– “in a clear hexadecimal format”, that means:
That if we sent the hexadecimal 01 ,<printh 01> we will receive the hex 0x01 that represent the Decimal <1> and the ASCII character <SOH> start of header
Or if we sent the hexadecimal 50 ,printh 01 we will receive the hex 0x50 that represent the Decimal 80 and the ASCII character P uppercase P.
With printh command we send a hex and we receive the hex that we have sent and that is the mean of “Send raw byte or multiple raw bytes over Serial to MCU”, raw byte refers to byte that has not yet been processed and not formatted or encoded as ASCII or little endian or everything else.


Nextion’s Return Data protocol format


Nextion already has a build-in protocol of “Return codes” for sending information’s over the Serial, you can find them at the instructions set chapter 7, under the title “Format of Nextion Return Data”.
The first 18 Return codes refer mostly on error messages and the next 14 are used for operation information.
The most useful of them all is the 0x65 return format code, that send whenever a component is pressed or released, with the following format:

Return Code: 0x65 Touch Event
0x65 0x00 0x01 0x01 0xFF 0xFF 0xFF
0x00 is page number,
0x01 is component ID,
0x01 is event(0x01 Press and 0x00 Release)
data: Page 0, Component 1, Pressed


Nextion returns the following format when Touch occurs, and component’s corresponding Send Component ID is checked in the users HMI design.



By following this data return format, despite that this is the method that most Nextion libraries use, it is not necessary to follow that code format.

The reason not to use this code format, is that it is very difficult to assign the commands that you want from Arduino’s side, in every Touch Event and much more difficult to read them separately for every event from the Serial and attach the function that you want on Arduino.

It is more practical to send a specific command and then from Arduino’s Serial identify the command that is sent and assigned to the function you want, than trying to identify and assign the IDs from a big number of objects to a function, as most libraries do this with the event’s ID protocol.

And at the end you cannot modified it.

The next step after this is to make a code on Arduino to read the data, that Nextion will send and to assign them to variables, functions or whatever else you want. This is a feature of the EasyNextionLibrary built-in Custom Protocol

After all this, you can go and see the Custom Protocol of the Easy Nextion Library to make your life EASY :)