Files
hexapod-robot/2026-current/remote/README.md
T
mangavalk dfd4d34512 Fold LEGACY into the generation folders
The LEGACY copies of HexapodRobot, Hexapod_NEW, Hexapod_Teensy and the old remote sketch were identical to the imported repos and are removed. The old Nextion design moves to 2019-teensy-nrf24/remote-nextion/, the 2019 remote case files to 2019-teensy-nrf24/remote-case/. Paths in CLAUDE.md, READMEs, remote/ comments, sim/build.ps1, the Unity DLL message and .vscode/settings.json now point to the new places. robot/ is not touched (its CLAUDE.md asks to check with the owner first).
2026-10-25 17:30:35 +01:00

123 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hexapod remote firmware (Teensy 4.1)
Handheld transmitter for the hexapod. It reads two 3-axis twist-grip
joysticks and an MPU6050, takes operator commands from a Nextion
touchscreen, and sends a `CmdPacket` (defined in
`../shared/HexapodProtocol/HexapodProtocol.h`) to the robot over nRF24L01
at 100 Hz.
## Building
From the `2026-current` folder: `pio run -e remote`, flash with
`pio run -e remote -t upload`, monitor with `pio device monitor -e remote`.
## Wiring (from the old remote sketch in `../../2019-teensy-nrf24/remote/`; edit `Config.h` if yours differs)
| Part | Signal | Teensy 4.1 pin |
|------|--------|----------------|
| nRF24L01 | MOSI / MISO / SCK | 11 / 12 / 13 (SPI0) |
| nRF24L01 | CE / CSN | 9 / 10 |
| nRF24L01 | VCC | 3.3 V, with a 10–100 µF cap right at the module |
| MPU6050 | SDA / SCL | **25 / 24 (Wire2)**: not 18/19, those are stick pins A4/A5 |
| Nextion | TX → RX1, RX ← TX1 | 0 / 1 (Serial1), 5 V supply |
| Sticks | 6 axes | A0–A5. Which axis is on which pin isn't known yet: reorder `STICK_PINS` until the `p` dump reads right |
**MPU6050 rewiring:** the old remote had its MPU code switched off, probably
because A4/A5 double as Wire's pins. Move the MPU's SDA/SCL to pins 25/24.
Stick pots are wired 3.3 V – wiper – GND. **Never feed 5 V into a Teensy
4.x analog pin.**
## Control scheme
| Input | Packet field | Meaning on the robot |
|-------|--------------|----------------------|
| Left stick forward/back | `vx` | walk forward/back |
| Left stick left/right | `vy` | strafe (mode A); heading target direction (mode B) |
| Left stick twist | `yaw_rate` | turn rate (mode A only; ignored in mode B) |
| Right stick, **ROTATE** (default) | `rx/ry/rz` | body roll / pitch / yaw |
| Right stick, **MOVE** (`FLAG_RSTICK_XLATE`) | `rx/ry/rz` | body X / Y / Z (height, via twist) offset |
| Handset tilt | `remote_roll/pitch` | extra body roll/pitch while REMOTE GYRO is on |
| Height slider | `body_height` | standing height, default ± `STANCE_HEIGHT_RANGE_MM` (robot rate-limits the change) |
In **HEADING** mode the left stick steers, relative to where the robot
faces at that moment. Forward/back walks forward/back, and sideways
steers: forward+left or back+left walk while turning left, and left alone
turns on the spot for as long as you hold it. Let go and the robot holds
its heading.
Touchscreen: ARM / DISARM, SIT/STAND, TRIPOD/WAVE, DIRECT/HEADING,
R: ROTATE/MOVE, REMOTE GYRO, ROBOT GYRO, speed slider, LEVEL (re-zero the
handset tilt), CAL / CANCEL CAL. `NEXTION.md` has the HMI build guide.
### Safety interlocks (in `RemoteState`)
- **Arming** is refused unless every stick axis is centered, and never
allowed during calibration.
- **Disarming** always clears the stand request. The robot arms into SIT,
so re-arming never stands it up by itself.
- **Link loss:** if no ack arrives for `LINK_LOST_MS` (300 ms, matching the
robot's failsafe), the remote disarms itself. When the link comes back
the robot stays down until you re-arm deliberately.
- **Sit/stand** requests are only accepted while armed. `FLAG_WALK` is only
sent while standing is requested.
- While disarmed or calibrating, all motion fields are sent as zero.
### Smoothing
- **Speed scale** ramps toward the slider at `SPEED_SCALE_RATE_PER_SEC`.
The robot uses speed scale directly on the walking twist, so a slider
jump would otherwise be a velocity step.
- **Remote tilt** fades in/out over ~0.5 s when REMOTE GYRO is toggled, and
the handset re-zeroes its "level" at the moment you enable it.
- **FLAG_WALK** lingers 250 ms after the left stick centers, so hovering at
the deadzone edge doesn't make the robot chatter between STAND and
WALKING.
- Body pose smoothing is left to the robot's `BodyPose` rate limiters.
## Stick calibration
1. Power on with both sticks released and the remote held still. Each
axis's resting center is captured automatically.
2. For full calibration, disarm, then tap **CAL** (or press `c` on the
serial console). Move every axis of both sticks to both limits, release
them, and tap **SAVE CAL** (`c`). The result is saved to EEPROM.
3. If any axis moved less than `CAL_MIN_HALF_SPAN` either side of center,
the save is refused and you stay in calibration mode. **CANCEL CAL**
(`x`) aborts.
4. `p` prints the calibration in a form you can paste into `Config.h`
defaults. `R` wipes EEPROM back to the `Config.h` defaults.
## Serial console (USB, 115200, single keystrokes)
Every touchscreen control is available here, so you can bench-test with no
display attached.
| Key | Action | Key | Action |
|-----|--------|-----|--------|
| `a` | toggle arm | `k` | disarm |
| `s` | toggle sit/stand | `g` | tripod ↔ wave |
| `m` | direct ↔ heading-hold | `t` | right stick rotate ↔ translate |
| `r` | remote gyro on/off | `b` | robot gyro on/off |
| `+` / `-` | speed ±25 | `z` | zero handset level |
| `]` / `[` | height up / down 10% | | |
| `c` | start / save calibration | `x` | cancel calibration |
| `p` | print status (raw + mapped sticks, IMU, link, state, cal) | `d` | toggle 10 Hz packet dump |
| `R` | reset stick cal to Config defaults | `U` | Nextion upload mode (USB ↔ display; power-cycle to leave) |
## Bench-check checklist
1. **Stick directions:** with `p`, confirm each logical axis reads
positive for right / forward / counterclockwise twist. Flip it in
`STICK_INVERT[]` if not.
2. **IMU mounting:** with `p`, dip the right edge down to get +roll, and
tip the far edge down to get +pitch. If not, fix `IMU_AXIS_FROM_CHIP` /
`IMU_AXIS_SIGN`.
3. **Nextion baud:** `bauds=115200` must be in Program.s, or the display
shows nothing useful.
4. **Radio:** with the robot powered, `tLink` / `p` should show ~100%. If
it reads NO LINK, check that both boards were built from the same
`HexapodProtocol.h`. The static payload size is part of the handshake.
5. **End to end with the robot on a stand:** use `d` to dump packets and
confirm each field changes the way the table above says.