Start a new topic

JavaScript library for Nextion

Hi, I'm working on a Node.js library to interface with a Nextion device. My aim is to deploy an application to a Tessel 2 which uses the library for communication. It's not entirely built out yet--the API is not complete nor documented--but if anyone else is interested in this, I'm eager to work together. Minimum requirements are Node.js v4, but this code could conceivably run in a Chrome or ChromeOS app--or an Electron-based desktop client. It should work with an Onion Omega or Omega2 (assuming Node v4 is working) or any Pi-like SBC.

I neglected to mention the URL: https://github.com/boneskull/nextion

Why so complicated?  Nextion is just a simple serial device.


Corrections you could make:

Enhanced Nextion has 8 Digital IO,

 - only 4 of which (io4-io7) are PWM capable at common pwmf

 - no guessing required about ADC - it does not exist

 - firmware does not have support for I2C, SPI, UART over IO,

  (whatever is implemented is speed limited, interpreted via HMI)


Understanding Nextion Return Codes (loosely Events, very loosely)

 -  An event should mean to react to upon occurrance

    Powering on / reset -> these two 0x00 and 0x88 are paired,

         (sometimes serial not ready to catch first 6 bytes sent)

    - 0x00 0x00 0x00 0xFF 0xFF 0xFF is missing from your list

         (Nextion has rebooted / poweron or rest command)

    - 0x88 0xFF 0xFF 0xFF Nextion ready,

         (only ever follows above 6 byte 0x00 0x00 0x00 0xFF 0xFF 0xFF)


    - 0x89 0xFF 0xFF 0xFF (microSD upgrade never sent

         - firmware just jumps to upgrade before hand)


    - 0x66 pageID only is sent in response to "sendme" command.

         - sendme can be embedded in any HMI page (usually pre/post init)

         - but not really an "event" if sent in response to serial "sendme" command


     - 0x68 wake is incorrect -  Touch event in sleep mode - incorrect

         - it is not a waking up event, it is sending touch coordinate when in sleep mode.

         - https://github.com/boneskull/nextion/blob/master/src/codes.js

           - here you defined more closely, but its touchCoordinateWhileAsleep


     Like wise 0xFD and 0xFE are not an "event",

         they are states to addt, wept, rept commands


     Again, is 0x70 and 0x71 an "event" they are responses to a get command.

        - sure it is possible to use print and printh to push bytes to the MCU,

        - but if the MCU has no "event" that is catching these

              all you have is stray data without context

        - 0x70 and 0x71 are also success responses to get commands


The hardest part of making a library from simple commands is each HMI is different

 It becomes what is common amongst HMI projects that makes it a library

  - ie: DCC++ train enthusiasts are dealing with the same protocol and similar needs

     therefore, most DCC++ HMIs will be so extremely similar - such a library works.


Johnny Five supports Input, Output and PWM in common with Nextion modes

- and certainly many many things could be done with this, what's connected?

- but, commands sent serially just to have remote capabilities are super slow.

  (enter argument for "slow is better than no")


But I would certainly question hooking so many in between components.

- each additional becomes one more breaking point (was it needed)

- hardware differences, connection differences, all play into this library

  and the result is a library that is

       ? too bloated for many MCUs

       ? too specific to a given HMI design


So while I certainly commend undertaking yet another language/platform

 - careful not to over complicate, Nextion is mostly straight, just simple


You can ask your Nextion related questions, those I can answer

- but javascript isn't my language, but wish you well


This is not a general-purpose library for HMI devices. Thanks for your input on the events. The README needs updating. Have you tried the library? My aim is to provide a high-level abstraction using common JavaScript patterns. This is why it may seem "complicated".

Hey Chris,


First, my aim is to provide you what I can from Nextion aspect for your project (response to your call).


To clarify "not general-purpose library for HMI devices", Nextion is an HMI device, so I assume it needs to be at least "general-purpose" for the Nextion HMI device.  It is in this "general-purpose" for the Nextion specific HMI device that user HMI designs are so varied ...


As far as using it, I have to admit I haven't.  I only have one MCU Node.js capable (Edison), but as that is a Linux server in a soc, I honestly never went down the path of Node.js and just went for Kylix3 and native Intel code with many readily available software packages already Intel Linux server ready.


Abstraction increases code size, this is where I mentioned bloated for many MCUs.  It also increases branches and costs a few more cycles.  Most MCUs are limited in both cycles and resources, not all can have so many resources like an Edison.


So on smaller MCUs, this means tightening things up so that it will fit and have a quicker response.  Generally speaking, many such abstractions get traded in for space and performance, and it starts to become more target HMI design specific (like not worrying about Johnny Five for the Enhanced models, though I think much could be done with the IO, just slow as I mentioned above).  Itead now has the Nextion IO breakout available on the end of an Flex Cable.


So my question becomes how "general-purpose" for Nextions are you aiming for, or more specific to a grouping of HMI designs (ie: DCC++, MMDVM, etc), or more project specific.  Model support to just basic or enhanced as well.


Again, Nextion related questions - those I can help answer.

I apologize, I'm not entirely sure how to format these posts. Maybe it's because I was doing it on a phone.  I hope this goes well.


 It is in this "general-purpose" for the Nextion specific HMI device that user HMI designs are so varied 


Correct.  It is "general-purpose" meaning I aim to provide abstractions for the entire documented command set.  A user of this library needn't know anything about the command set.


Abstraction increases code size, this is where I mentioned bloated for many MCUs.  It also increases branches and costs a few more cycles.  Most MCUs are limited in both cycles and resources, not all can have so many resources like an Edison.


Indeed!


Any device that *can run Node.js* can consume the library.  If a device can run Node.js, it can run Linux, and then is reasonable to assume it is not "most MCUs".  Don't quote me on the terminology, but as I understand, microcontrollers were not "meant to" run Linux.  The devices I am supporting are of the SoC variety which do.  Maybe that's Raspbian or OpenWRT, etc.


With that in mind, I am not targeting MCUs.  I am not targeting performance, unless it's unreasonably slow.  I am not targeting memory consumption unless we start to run OOM.  I am targeting ease-of-use by JavaScript developers.


Even though the Nextion is "simple", UART itself is not a particularly efficient protocol.  It could be faster using I2C or SPI.  But it was chosen for ease-of-use, which is what makes the device unique.  My library has the same aim.


I have an "enhanced" device, but I would support basic devices as well.  This is the scope.  


It seems obvious to me that my intent with the library is unclear--how could I improve the README so that there's no confusion?   Certainly I can start by removing my "thinking out loud".  Does "general purpose" mean something to you that it doesn't to me?


Please keep in mind this is a very new project.  I may split it into multiple projects--the binary protocol ("codes" and parsing thereof) is a candidate to be its own module, for example.  Then, if a consumer does not want the "Object-level" abstractions, a consumer could leverage this new module only to parse/serialize data coming & and out.


The reason I'm posting here is to ask if others would like to assist in the development of the library or some portion thereof.  I may be the only individual here who wants to actually use a Nextion with JavaScript, but in case I'm not, here I am.  :D


(My mentioning of J5 in the README was mostly just thinking aloud.  I am not intending to provide an adapter, given the limited capabilities of the Nextion's GPIO pins, and complete lack thereof on the "basic" model.)

(To anyone at ITEAD listening: paragraph formatting for this text editor doesn't seem to work on iOS.)

Another aspect that you can quickly implement and check off your list


Understanding Nextion Response Data from Table 1.

These are all in response to commands sent to Nextion according to the bkcmd setting (default 2).


if bkcmd=0 there are no responses returned except for

   get command

       0x70 and 0x71 success


if bkcmd=1 only success responses are returned

  if get command

      either 0x70 string or 0x71 number

  else on other command

      0x01 0xFF 0xFF 0xFF // success or no return at all

this means no 0x00, 0x02..0x23 returns


if bkcmd=2 only failed are returned

   if get command

       0x70 String or 0x71 Number is still a success

   else

      is_OpFailure Nextion side (includes 0x1C, 0x1D, 0x1F)

      is_ProgrammingError_Debug // user coding errors

         (0x02,0x03,0x04,0x05,0x11,0x12,0x1A,0x1B,0x1E,0x20,0x23)

this means no 0x01 returns - no response, 0x70, 0x71 is success


if bkcmd=3 // all codes are in play

  if get command

       0x70 String or 0x71 Number is still a success

  else

     if not get and success

        0x01 response

     else

        is_OpFailure Nextion side (includes 0x1C, 0x1D, 0x1F)

        is_ProgrammingError_Debug // user coding errors     

          (0x02,0x03,0x04,0x05,0x11,0x12,0x1A,0x1B,0x1E,0x20,0x23)    


But, I am almost certain that 0x00 code is expanded out and never used

Thinking out loud is alright - useful to establish understandings.


Just a side note on UART for a bit of relief

UART is not necessarily so slow, certainly their beginnings of 110 and 300 baud were painful,

(unless a six hour drive up the coast and back were deemed to be more painful).

Modern MCU UART speeds can sometime blow I2C and SPI implementations out of the water.

(granted SPI is bidirectional and can have several data lines contributing to its throughput).


The GD32 and STM32 USART modules are certainly more capable, but the Interpreted nature of the Nextion running HMI design would not keep pace with.  So standard 2400 to 115200 is used, but Mbps is certainly within their capabilities.  The GD32 at 108MHz to another GD32 at 108MHz could in theory hit near 6.75Mbps ... certainly could be configured for it.


Login or Signup to post a comment