Simulation - sim/: the unchanged robot firmware compiled into hexapod_sim.dll against PC stand-ins (Arduino, Servo, Wire + register-level MPU6050, RF24 with matching-config radio), a kinematic body model (support plane + planted-foot odometry) that also drives the simulated IMU, and a headless smoke test (sim_smoke). build.ps1 builds and tests. - Hexapod_Simulation_Unity/ folded in (history kept in a bundle outside the repo). Assets/HexapodSim loads the DLL, drives the existing leg rig, and offers joystick / keyboard / robot-serial input plus a test panel. Robot (all found or confirmed in the simulation) - Config.h geometry taken from the Unity model. - IK femur elevation sign, gait stance direction, body pose rotation direction, yaw lever arm. - Stance feet integrated from the current command; gait restarts at mid-stance; heading integrates the applied turn rate, only while walking. - Leg clearance and reach checks (Limits::feetFeasible); walk command and body pose scaled as a whole, pose scale rate-limited, planted feet guarded so the body never snaps or legs collide. - Robot-gyro self-leveling as an integrator. - Heading mode: steering relative to the body; S walks backward. - Standing height from the remote (STANCE_HEIGHT_RANGE_MM). Protocol v3 (reflash both boards) - CmdPacket gains body_height (22 bytes). Remote - Height slider (Nextion hHeight/nHeight, serial [ ]). - Fixed unspecified I2C read order in RemoteIMU. LEGACY/: owner's old Nextion HMI and remote hardware assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.6 KiB
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 repo root: pio run -e remote, flash with
pio run -e remote -t upload, monitor with pio device monitor -e remote.
Wiring (placeholders; edit Config.h to match)
| 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 | 18 / 19 (Wire) |
| Nextion | TX → RX2, RX ← TX2 | 7 / 8 (Serial2), 5 V supply |
| Left stick | X / Y / twist | A0 / A1 / A2 |
| Right stick | X / Y / twist | A3 / A6 / A7 |
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_WALKis 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
BodyPoserate limiters.
Stick calibration
- Power on with both sticks released and the remote held still. Each axis's resting center is captured automatically.
- For full calibration, disarm, then tap CAL (or press
con 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. - If any axis moved less than
CAL_MIN_HALF_SPANeither side of center, the save is refused and you stay in calibration mode. CANCEL CAL (x) aborts. pprints the calibration in a form you can paste intoConfig.hdefaults.Rwipes EEPROM back to theConfig.hdefaults.
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 |
Bench-check checklist
- Stick directions: with
p, confirm each logical axis reads positive for right / forward / counterclockwise twist. Flip it inSTICK_INVERT[]if not. - IMU mounting: with
p, dip the right edge down to get +roll, and tip the far edge down to get +pitch. If not, fixIMU_AXIS_FROM_CHIP/IMU_AXIS_SIGN. - Nextion baud:
bauds=115200must be in Program.s, or the display shows nothing useful. - Radio: with the robot powered,
tLink/pshould show ~100%. If it reads NO LINK, check that both boards were built from the sameHexapodProtocol.h. The static payload size is part of the handshake. - End to end with the robot on a stand: use
dto dump packets and confirm each field changes the way the table above says.