Skip to content

Commit

Permalink
Merge pull request #252 from currentc57/master
Browse files Browse the repository at this point in the history
nextion_ez - Improved functionality and documentation
  • Loading branch information
PropGit authored Jul 6, 2022
2 parents e954f6e + 415efc5 commit 0809b8b
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 121 deletions.
47 changes: 26 additions & 21 deletions libraries/community/p1/All/nextion_ez/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,63 @@ Full documentation on the Arduino Easy Nextion Library and protocol, as well as

If you find this library useful, please consider supporting the author of the original Easy Nextion Library, Thanasis Seitanis at: [[email protected]](https://paypal.me/seithan)


**NOTE**: `.HMI` files for Nextion Editor are also included in the demo folder.

## The public methods
- `start()`
- `writeNum()`
- `writeStr()`
- `writeByte()`
- `pushCmdArg()`
- `sendCmd()`
- `addWave()`
- `readNum()`
- `readStr()`
- `readByte()`
- `cmdAvail()`
- `getCmd()`
- `getSubCmd()`
- `readByte()`
- `getCmdLen()`
- `getCurrentPage()`
- `getLastPage()`
- `setCurrentPage()`
- `setLastPage()`

**NOTE** previous version had a `getSubCmd` method that exactly duplicated the functionality of `readByte`, it has been removed. If you used `getSubCmd` in your code, just replace it with `readByte`

In order for the object to update the Id of the current page, you must write the Preinitialize Event of every page: `printh 23 02 50 XX` , where `XX` the id of the page in HEX.
Your code can then read the current page and previous page using the `getCurrentPage()` and `getLastPage()` methods.

Standard Easy Nextion Library commands are sent from the Nextion display with `printh 23 02 54 XX` , where `XX` is the id for the command in HEX.
Your code should call the `listen()` method frequently to check for new commands from the display. You can then use the `getAvail`, `getCmd()` and `getSubCmd` methods to parse any commands.
Your code should call the `listen()` method frequently to check for new commands from the display. You can then use the `cmdAvail`, `getCmd()` and `readByte()` methods to parse any commands.

example:
```
PRI callCommand(_cmd) 'parse the 1st command byte and decide how to proceed
```spin
PUB main()
nextion.listen ' need to run this to check for incoming data from the Nextion
if nextion.cmdAvail > 0 ' has the nextion sent a command?
callCommand(nextion.getCmd) ' get the command byte and see parse it
PRI callCommand(_cmd) ' parse the 1st command byte and decide how to proceed
case _cmd
"T" : 'standard Easy Nextion Library commands start with "T"
nx_sub := nextion.getSubCmd ' so we need the second byte to know what function to call
callTrigger(nx_sub)
"T" : ' standard Easy Nextion Library commands start with "T"
callTrigger(readByte) ' so we need the second byte to know what function to call
' custom commands can be added by expanding this case statement
PRI callTrigger(_triggerId) 'use the 2nd command byte from nextion and call associated function
PRI callTrigger(_triggerId) ' use the 2nd command byte from nextion and call associated function
case _triggerId
$00 :
trigger00
trigger00 ' the orginal Arduino library uses numbered trigger functions
$01 :
trigger01
$02 :
trigger02
$03 :
trigger03
$04 :
trigger04
runCount ' but since we are parsing ourselves, we can call any method we want
```

**NOTE**: This Spin object requires the use of a custom version of FullDuplexSerial.spin called FullDuplexSerialAvail.spin that adds a function to return the number of bytes in the rx_buffer

**NOTE**: Spin on the Proppeller 1 chip has a limit of 64 of items in a case statement. For complexe Nextion systems use of custom commands in addition to the "T" command can be used to avoid this limit. Alternatively case statements can be nested inside another structure.
Example:
```
```spin
PRI callTrigger(_triggerId) 'use the 2nd command byte from nextion and call associated function
if _triggerId < $40
case _triggerId
Expand Down Expand Up @@ -116,10 +122,9 @@ A local Number component n0 on page1 can be accessed by page1.n0 or n0, but ther


## Compatibility
* Propeller (spin version in P1 folder)
* Propeller2 (spin2 version in P2 folder)

## Releases:
* Propeller (https://github.com/parallaxinc/propeller spin version in P1 folder)
* Propeller2 (https://github.com/parallaxinc/propeller spin2 version in P2 folder)
* Arduino (https://github.com/currentc57/nextion_ez)


## Licence
Expand Down
58 changes: 37 additions & 21 deletions libraries/community/p1/All/nextion_ez/demo/nextion_ez_demo.spin
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@

'' E-mail..... [email protected]
'' Started.... 17 JUN 2022
'' Updated.... 19 JUN 2022
'' Updated.... 04 JUL 2022
''
'' =================================================================================================
{{
A simple demonstration of how to use the nextion_ez_p1 object with the Nextion display
This demo uses two serial connections. One is for communicating with the Nextion (or simulator),
the other to send debug data to a serial terminal.
The Nextion demo project has 2 pages.
The first page has 2 buttons, 1 number, 1 float and 1 text field
The Run button is dual state and when depressed it will cause
the Propeller To change the text field and increment the number and float fields.
The Page1 button will cause the Propeller to request a change to page1
The second page has 1 button, 1 slider, 1 gauge, 1 progress and 1 waveform
The slider is located on the far right of the page
Moving the slider will cause the Propeller to retrieve its position
and use that value to update the progress bar, gauge and waveform.
The Page0 button will cause the Propeller to request a change to page0
NOTE: HMI files for Nextion Editor are also included in the demo folder.
}}

Expand All @@ -22,7 +37,7 @@ CON

NX_TX_PIN = 0
NX_RX_PIN = 1
NX_BAUD = 9_600
NX_BAUD = 115_200

DB_TX_PIN = 30
DB_RX_PIN = 31
Expand Down Expand Up @@ -51,7 +66,7 @@ PUB main
repeat
waitcnt(clkfreq / 25 + cnt)

if nextion.getCurrentPage <> currentPage
if nextion.getCurrentPage <> currentPage 'has the Nextion page changed?
lastPage := nextion.getLastPage
currentPage := nextion.getCurrentPage

Expand All @@ -66,74 +81,75 @@ PUB main
serial.hex(nextion.readNum(STRING("dp")), 2)
serial.Tx(CR)

nextion.listen
if nextion.cmdAvail > 0
nx_cmd := nextion.getCmd
nextion.listen ' need to run this to check for incoming data from the Nextion
if nextion.cmdAvail > 0 ' has the nextion sent a command? '
nx_cmd := nextion.getCmd ' get the command byte

'data to serial terminal to demonstrate what is returned
serial.Str(STRING("nextion command = "))
serial.hex(nx_cmd, 2)
serial.Tx(CR)

callCommand(nx_cmd)
callCommand(nx_cmd) ' let's see what command we received

if run_count == true
disp_value++
nextion.writeNum(STRING("x0.val"), disp_value)
nextion.writeNum(STRING("n0.val"), disp_value)
nextion.writeNum(STRING("x0.val"), disp_value) ' update the nextion number
nextion.writeNum(STRING("n0.val"), disp_value) ' and float fields on page0

PRI callCommand(_cmd) 'parse the 1st command byte and decide how to proceed
case _cmd
"T" : 'standard Easy Nextion Library commands start with "T"
nx_sub := nextion.getSubCmd ' so we need the second byte to know what function to call
nx_sub := nextion.readByte ' so we need the second byte to know what function to call

'data to serial terminal to demonstrate what is returned
serial.Str(STRING("nextion subcommand = "))
serial.hex(nx_sub, 2)
serial.Tx(CR)

callTrigger(nx_sub)
callTrigger(nx_sub) ' now we call the associated function

PRI callTrigger(_triggerId) 'use the 2nd command byte from nextion and call associated function
case _triggerId
$00 :
trigger00
trigger00 ' the orginal Arduino library uses numbered trigger functions
$01 :
trigger01
$02 :
trigger02
runCount ' but since we are parsing ourselves, we can call any method we want
$03 :
trigger03
$04 :
trigger04

PRI trigger00
nextion.sendCmd(STRING("page 1"))
nextion.sendCmd(STRING("page 1")) ' nextion commands can have their arguments in the string we send

PRI trigger01
nextion.sendCmd(STRING("page 0"))
nextion.pushCmdArg(0) ' or up to 16 arguments can pe passed via a stack
nextion.sendCmd(STRING("page")) ' this allows the easy use of variables and constants

PRI trigger02
PRI runCount
run_count := NOT run_count
if run_count
nextion.writeStr(STRING("t0.txt"), STRING("Running"))
nextion.writeStr(STRING("t0.txt"), STRING("Running")) ' we can update nextion text attributes with writeStr
else
nextion.writeStr(STRING("t0.txt"), STRING("Stopped"))
nextion.readStr(STRING("t0.txt"), @txt)
nextion.readStr(STRING("t0.txt"), @txt) ' and we can read text attributes with readStr

'data to serial terminal to demonstrate what is returned
serial.str(STRING("t0.txt = "))
serial.str(@txt)
serial.tx(CR)

PRI trigger03 | slidder, wave, guage
slidder := nextion.readNum(STRING("h0.val"))
slidder := nextion.readNum(STRING("h0.val")) ' number attributes can be read with readNum
guage := slidder * 36 / 10
wave := slidder * 255 / 100

nextion.writeNum(STRING("j0.val"), slidder)
nextion.writeNum(STRING("j0.val"), slidder) ' and number attributes an be updated on the nextion with writeNum
nextion.writeNum(STRING("z0.val"), guage)
nextion.addWave(1, 0, wave)
nextion.addWave(1, 0, wave) ' the addWave method makes it easy to add to a nextion waveform

'data to serial terminal to demonstrate what is returned
serial.str(STRING("h0.val = "))
Expand Down
77 changes: 59 additions & 18 deletions libraries/community/p1/All/nextion_ez/nextion_ez.spin
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,27 @@
If you find this library useful, please consider supporting the author of the original
Easy Nextion Library, Thanasis Seitanis at: [[email protected]](https://paypal.me/seithan)
Differences between the Arduino library and Spin object:
Differences between the Arduino library and Spin object:
1) The Arduino implementation automatically calls trigger functions, stored in a separate file,
in response to Nextion commands.
This object provides the methods cmdAvail(), getCmd(). getSubCmd() and readByte()
This object provides the methods cmdAvail(), getCmd(), and readByte()
to retreave the command packets sent from the Nextion.
2) The Arduino C++ library uses a single overloaded function writeStr() to send commands and
update string values on the Nextion.
This object uses separate methods sendCmd() and writeStr().
3) The the equivilent of the Arduino NextionListen() function has been named listen()
3) A argument fifo has been added to allow a new method pushCmdArg() that can be used to
provide a variable number of arguments to sendCmd().
4) The the equivilent of the Arduino NextionListen() function has been named listen()
in this implementation.
4) This object adds a method called addWave() to address the special syntax of the
5) This object adds a method called addWave() to create a quick and easy interface to the
Nextion waveform add command.
5) In this object the currentPageId and lastCurrentPageId variables can be accessed with the
methods getCurrentPage() and getLastPage()
6) In this object the currentPageId and lastCurrentPageId variables can be accessed with the
methods getCurrentPage(), getLastPage(), setCurrentPage() and setLastPage()
}}

Expand All @@ -55,9 +58,11 @@ VAR
long current_page_id
long last_current_page_id
byte cmd
byte sub_cmd
byte cmd_len
byte cmd_avail
long cmd_fifo[16]
byte cmd_fifo_head
byte cmd_fifo_tail

OBJ
_nextion : "FullDuplexSerialAvail" 'a special version of FullDuplexSerial that provides an available method like Arduino and FullDuplexSerial
Expand Down Expand Up @@ -101,15 +106,53 @@ PUB writeStr(ptr_component, ptr_txt) 'send a string value t
repeat 3
_nextion.tx($FF)

PUB writeByte(val) 'send raw data byte (not ASCII formated) to Nextion
{{
Main purpose and usage is for sending the raw data required by the addt command
where we need to write raw bytes to serial
example: nextion.writeByte(0)
}}
_nextion.tx(val)

PUB pushCmdArg(argument) 'load the argument FIFO with numeric arguments that are to be sent with the command using sendCmd()
{{
Used to load the argument FIFO with numeric arguments that are to be sent with the command using sendCmd()
example: to send the command "page 1" to the nextion
nextion.pushCmdArg(1)
nextion.sendCmd(STRING("page"))
}}
cmd_fifo[cmd_fifo_head] := argument
cmd_fifo_head++
if cmd_fifo_head > 15
cmd_fifo_head := 0

PUB sendCmd(ptr_command) 'send a command to nextion
PUB sendCmd(ptr_command) | count, x, argument 'send a command to nextion
{{
send a command to nextion
ptr_command should be a pointer to a string containing the command to be sent
example: nextion.sendCmd(STRING("page 0"))
}}
if(cmd_fifo_head < cmd_fifo_tail)
count := (cmd_fifo_head + 16) - cmd_fifo_tail
else
count := cmd_fifo_head - cmd_fifo_tail

_nextion.str(ptr_command)

if(count > 0)
_nextion.tx(" ")
x := 0
repeat count
if x > 0
_nextion.tx(",") 'only need commas between arguments, not between command and 1st argument
argument := cmd_fifo[cmd_fifo_tail]
_nextion.dec(argument)
cmd_fifo_tail++
if(cmd_fifo_tail > 15)
cmd_fifo_tail := 0

repeat 3
_nextion.tx($FF)

Expand Down Expand Up @@ -327,33 +370,31 @@ PUB listen | _char, _time, _ms, _len, _cmdFound, _cmd 'check for incoming s
last_current_page_id := current_page_id
current_page_id := _nextion.rx

"T" :
cmd_avail := true 'normal Easy Nextion Library style 2 byte commands start with "T"
cmd := _cmd ' so we pull both bytes and hold them for the main code
sub_cmd := _nextion.rx

OTHER : 'custom commands can be variable length, we pull just the first and leave the rest for main code to deal with
OTHER : 'commands can be variable length, we pull just the first and leave the rest for main code to deal with
cmd_avail := true
cmd := _cmd
return

PUB getCurrentPage : _page 'returns the current page id
return current_page_id

PUB setCurrentPage(_page) 'sets the current page id
current_page_id := _page

PUB getLastPage : _page 'returns the previous page id
return last_current_page_id

PUB cmdAvail : _avail 'returns the number of commands in the buffer
PUB setLastPage(_page) 'sets the previous page id
last_current_page_id := _page

PUB cmdAvail : _avail 'returns true if commands in the buffer
_avail := cmd_avail
cmd_avail := false
return

PUB getCmd : _cmd 'returns the 1st command byte
return cmd

PUB getSubCmd : _sub 'returns the 2nd command byte
return sub_cmd

PUB getCmdLen : _len 'returns the number of command bytes (for use in custom commands)
return cmd_len

Expand Down
Loading

0 comments on commit 0809b8b

Please sign in to comment.