- LEGACY/remote/teensy/: old remote sketch from https://mangavalk.com/Hexapod/remote.git @ 492dece (reference only). - remote/Config.h: sticks on A0-A5, Nextion on Serial1 (0/1), as in the old sketch; MPU6050 moved to Wire2 (25/24) since A4/A5 are Wire's pins. - NextionUI: controls on a vscope-global "control" page added to the old HMI; keeps the old t1 status texts; the old page-1 b2 button (and serial 'U') enter Nextion upload passthrough, following the PC's baud. - Docs: NEXTION.md, remote README wiring, CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
100 lines
5.8 KiB
Markdown
100 lines
5.8 KiB
Markdown
# Nextion HMI build guide
|
||
|
||
Start from your existing HMI (`LEGACY/remote/remote.HMI`, the servo
|
||
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) |
|
||
|
||
The firmware drives the display by **component name**, and the display
|
||
talks back with small custom frames sent from each button's touch event.
|
||
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.
|
||
|
||
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
|
||
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.
|
||
|
||
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`).
|
||
|
||
## 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 %) |
|
||
| `hHeight`| Slider | – | `val` 0..200, 100 = default (set **maxval = 200**) |
|
||
| `nHeight`| Number | – | `val` -100..100 (height offset %) |
|
||
| `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 |
|
||
| `hHeight` | `printh 23 02 48`<br>`prints hHeight.val,1` | `H` + height byte (Touch Move + Release) |
|
||
| `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 |
|
||
|
||
**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).
|
||
|
||
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.
|