2026-09-28 18:14:00 +02:00
# Nextion HMI build guide
2026-10-25 17:30:35 +01:00
Start from your existing HMI (`../../2019-teensy-nrf24/remote-nextion/remote.HMI` , the servo
2026-10-01 15:29:21 +02:00
monitor) and **add one page named `control`** with the components below.
Your existing pages keep working:
| Existing | What the firmware does with it |
|----------|--------------------------------|
| page 1 `t1` , page 3 `t1` | writes `connected` / `not connected` , as the old firmware did. Set both to **vscope = global** , and put their real names (`page1.t1` , …) in `NEXTION_STATUS_TEXTS` in `Config.h` |
| page 1 `b2` (id 5) | **upload mode** : keep "Send Component ID" ticked on it. The remote shows `uploadscreen` and passes USB straight through to the display, so Nextion Editor can upload over the remote's USB port. Power-cycle to leave. Serial key `U` does the same |
| page 4 `uploadscreen` | shown on entering upload mode |
| page 3 sliders `h0` – `h17` | not driven yet: the robot doesn't send servo positions back (that needs the planned telemetry channel) |
2026-09-29 00:37:12 +02:00
2026-09-28 18:14:00 +02:00
The firmware drives the display by **component name** , and the display
talks back with small custom frames sent from each button's touch event.
2026-10-01 15:29:21 +02:00
Layout, fonts and colors are up to you. The names and event code must
match exactly.
**Set every component on `control` to vscope = global.** The firmware
writes them as `control.<name>` and keeps them current whichever page is
showing. A local component on another page can't be written from outside,
and with `bkcmd=0` the display ignores those writes silently.
2026-09-28 18:14:00 +02:00
The remote is authoritative. Use **plain Button** components (not
Dual-state buttons) and don't toggle anything locally in the HMI. The
remote repaints every label and color from its own state, including a
full redraw every 2 s and whenever the display reboots.
## Program.s / page setup
In **Program.s** , before `page 0` , add:
```
bauds=115200
```
This sets the display to the `NEXTION_BAUD` in `remote/Config.h` . The
2026-10-01 15:29:21 +02:00
display ships at 9600, and `bauds=` persists across power cycles. The old
firmware used the ITEAD library at 9600, so your HMI probably runs at 9600
today.
2026-09-28 18:14:00 +02:00
2026-10-01 15:29:21 +02:00
Name the new page `control` . The firmware never changes pages, except
into `uploadscreen` for upload mode. Add buttons on your other pages to
switch to it (`page control` ).
2026-09-28 18:14:00 +02:00
## Components
Text components need **txt_maxl** at least as large as the longest string
the firmware writes. Button bounds here allow some slack.
| Name | Type | txt_maxl | Firmware writes |
|----------|---------|----------|----------------------------------------------|
| `bArm` | Button | 10 | `ARMED` / `DISARMED` , bco red / gray |
| `bKill` | Button | – | nothing (static "DISARM" label, make it red) |
| `bStand` | Button | 6 | `STAND` / `SIT` , bco green / gray |
| `bGait` | Button | 8 | `TRIPOD` / `WAVE` |
| `bMode` | Button | 8 | `DIRECT` / `HEADING` |
| `bRs` | Button | 10 | `R: ROTATE` / `R: MOVE` |
| `bRGyro` | Button | – | bco green / gray (label it "REMOTE GYRO") |
| `bBGyro` | Button | – | bco green / gray (label it "ROBOT GYRO") |
| `hSpeed` | Slider | – | `val` 0..255 (set **maxval = 255** ) |
| `nSpeed` | Number | – | `val` 0..100 (speed %) |
2026-09-29 00:37:12 +02:00
| `hHeight` | Slider | – | `val` 0..200, 100 = default (set **maxval = 200** ) |
| `nHeight` | Number | – | `val` -100..100 (height offset %) |
2026-09-28 18:14:00 +02:00
| `bCal` | Button | 9 | `CAL` / `SAVE CAL` , bco orange while active |
| `bCalX` | Button | – | nothing (static "CANCEL CAL") |
| `bZero` | Button | – | nothing (static "LEVEL") |
| `tLink` | Text | 10 | `LINK 97%` / `NO LINK` , pco green / red |
| `tMsg` | Text | 40 | status / rejection messages |
## Touch events
Put this in each component's **Touch Release Event** (the Speed slider
uses **Touch Move** as well so the value tracks your finger). Frame format:
`'#'` (0x23), length, command byte, optional value byte.
| Component | Event code | Command |
|-----------|------------------------------------------|--------------------------------|
| `bArm` | `printh 23 01 41` | `A` toggle arm (needs sticks centered) |
| `bKill` | `printh 23 01 4B` | `K` disarm, always accepted |
| `bStand` | `printh 23 01 53` | `S` toggle sit/stand |
| `bGait` | `printh 23 01 47` | `G` tripod ↔ wave |
| `bMode` | `printh 23 01 4D` | `M` direct ↔ heading-hold |
| `bRs` | `printh 23 01 58` | `X` right stick rotate ↔ translate |
| `bRGyro` | `printh 23 01 52` | `R` remote-gyro tilt on/off |
| `bBGyro` | `printh 23 01 42` | `B` robot self-stabilize on/off |
| `hSpeed` | `printh 23 02 56` <br>`prints hSpeed.val,1` | `V` + speed byte |
2026-09-29 00:37:12 +02:00
| `hHeight` | `printh 23 02 48` <br>`prints hHeight.val,1` | `H` + height byte (Touch Move + Release) |
2026-09-28 18:14:00 +02:00
| `bZero` | `printh 23 01 5A` | `Z` zero handset level |
| `bCal` | `printh 23 01 43` | `C` start / save stick calibration |
| `bCalX` | `printh 23 01 51` | `Q` cancel calibration |
2026-10-01 15:29:21 +02:00
**Uncheck "Send Component ID"** on every component on `control` : those
standard touch frames only add serial traffic. The one exception is the old
page 1 `b2` upload button (see the top).
2026-09-28 18:14:00 +02:00
Protocol details and the parser live in `NextionUI.h/.cpp` . To add a
control, pick an unused command byte, add it to `NextionUI::decodeCustom()`
and `UiCmd` , handle it in `RemoteState::handle()` , and add a row here.