2PyBot is an ESP32 self-balancing robot with NEMA 17 steppers, TMC2226 drivers, MT6816 wheel encoders, and an ISM6HG256X IMU. The firmware uses LQR/LQI state feedback for balance and position hold. An EVOFOX One S gamepad pairs directly through Bluepad32. USB serial carries host drive commands, telemetry, and parameter tuning.
- 200 Hz control loop using pitch, pitch rate, wheel position, velocity, and position integral.
- 20 kHz timer ISR for STEP/DIR pulses; hardware PCNT for encoder counts.
- Encoder-differential heading hold and slew-limited steering.
- Normal hold, stiff hold, velocity tracking, and climb reference tracking.
- Terrain roughness, airborne, and landing detection with pitch-gain softening.
- 106 runtime parameters with per-value bounds and NVS save/load.
- Auto-tuning routines for wobble, trim, radius, and stall speed, with current limitations documented in the tuning guide.
- WS2812 status ring, camera pan/zoom servos, and PWM torch.
The gamepad's left stick drives and steers. The right stick pans and zooms the camera. START requests arming; SELECT stops balancing. LB toggles LOW/HIGH speed, RB toggles the torch, and the D-pad controls hold modes and torch brightness.
Fresh host V,<forward>,<steering>,<enable> commands take priority over gamepad driving. V commands do not arm the robot. Use gamepad START or serial E. With no fresh input, drive commands become zero and balancing continues.
USB serial runs at 460800 baud. The firmware emits O odometry at 50 Hz and D debug telemetry at a nominal 100 Hz. Debug starts enabled; L toggles it. See the serial protocol for fields and commands.
firmware/
BaseLink/ Robot firmware and serial protocol
BaseLink.ino State machine, control, input arbitration
config.h Pins and compiled defaults
params.h / params.cpp Runtime parameters and NVS persistence
autotune.h Calibration and tuning routines
terrain.h Roughness, airborne, and landing detection
bt_gamepad.h Bluepad32 input mapping
imu_sensor.h / .cpp Mahony attitude estimation
stepper_control.h / .cpp TMC2226 configuration, PCNT, step ISR
led_ring.h / .cpp WS2812 status display
payload.h Camera servos and torch
Controller/ Legacy ESP-NOW joystick transmitter
software/
android/ Kotlin/Compose Android app
radxa/
console/ Current browser console and Android API
deployment/ Installed services, MediaMTX, and device rules
runtime/vision_controller/ Older collision guard and person follower
gui/ Legacy PID desktop interface
tools/
controller_lab/ Browser simulation lab
tuner/ Legacy Web Serial PID tuner
docs/ Architecture, control theory, tuning, history
scripts/ Model generation and Radxa utilities
hardware/cad/enclosure/rev5/ OpenSCAD enclosure source and STL exports
models/ CAD assets
assets/ Project media
- Install the ESP32 + Bluepad32 board package and the libraries listed in the firmware setup guide.
- Select ESP32 Dev Module with the Huge APP partition scheme.
- Open
firmware/BaseLink/BaseLink.ino, review the pin assignments inconfig.h, and flash. - Open USB serial at 460800 baud with newline termination. Check the IMU and driver boot messages, then send
P?to inspect loaded parameters. - Pair the EVOFOX One S in Home+B mode. Leave both sticks centered while calibration completes.
- Verify motor and sensor signs using the configuration guide, then request arming while upright.
Saved NVS parameters take precedence over compiled defaults. PD restores defaults in RAM; PS saves them.
| Component | Current compatibility |
|---|---|
| USB terminal or custom serial client | Supports the current parameter and telemetry protocol |
software/radxa/console/ |
Current Radxa console: 460800 baud, live parameter metadata, browser UI, Android API, and WebRTC camera |
software/android/ |
Kotlin/Compose client for console HTTP/WebSocket and MediaMTX WHEP; parameter groups are dynamic |
software/runtime/vision_controller/radxa_brain.py |
Uses O and V messages, but still has 115200 baud and 0.035 m radius constants; align both before use |
gui/robot_controller_ui.py |
Legacy PID UI: 115200 baud, tab-separated telemetry, and $ commands; needs a protocol update |
tools/tuner/tuner.html |
Legacy Web Serial PID tuner; not a current parameter-store client |
firmware/Controller/Controller.ino |
Legacy ESP-NOW transmitter; current BaseLink has no ESP-NOW receiver |
The current console package was imported from the Cubie A7A. See its setup and API guide and deployment layout. Its debug parser reads the original 15 fields; terrain telemetry and a terrain parameter tab remain pending.
The older Radxa brain provides GUARD/FOLLOW modes. It owns the camera and serial port, so it cannot run alongside the console. See its setup guide.
The Android app has Live, Map, Tune, Auto, Camera, and Setup screens. It defaults to the Radxa hotspot address 10.42.0.1. Its Tune screen includes all groups reported by firmware, including TERRAIN. APK build instructions and CI artifacts are documented with the app.
The console runs from /home/radxa/projects/2PyBot. After git pull --ff-only, a systemd timer applies relevant committed changes and restarts the affected services. Android, CAD, firmware, and documentation changes do not restart the console. See repo-based deployment for installation, status, and retry commands.
| Component | Configuration |
|---|---|
| Robot controller | ESP32 DevKit |
| Wheel drive | Two NEMA 17 motors, TMC2226 drivers, 1/8 microsteps |
| Wheel feedback | MT6816 quadrature encoders, 4096 counts/revolution |
| Wheel radius | 0.050 m compiled default |
| Attitude | ISM6HG256X accelerometer/gyro, Mahony filter |
| Compass | QMC5883L, tilt-compensated yaw telemetry |
| Gamepad | EVOFOX One S through Bluepad32 |
| Status ring | 16 WS2812 LEDs on GPIO 15 |
| Camera payload | MG90S pan/zoom servos on GPIO 26/0; torch on GPIO 2 |
Revision 5 includes the base tray, shell, face plate, and left/right motor covers as OpenSCAD source and five STL exports. The enclosure is not yet printed or physically fit-tested. Estimated dimensions are marked in the source. The imported face STL has three zero-area triangles that need re-export or repair before printing.
The existing simplified STEP model remains in models/2pybot_simplified.step; it is separate from the revision-5 enclosure package.
| Document | Contents |
|---|---|
| Firmware setup | Build, wiring, pairing, controls |
| Serial protocol | Commands, parameter records, telemetry fields |
| Radxa console | Browser UI, Android API, camera pipeline, deployment |
| Android app | Build, host connection, screens, parameter and video transport |
| Radxa deployment | Git updates, selective restarts, systemd timer, health checks |
| Enclosure CAD | Revision-5 source, exports, dimensions, and current print status |
| System architecture | Sensors, control, actuation, host links |
| LQR/LQI theory | State feedback, control modes, filtering, limits |
| Configuration and tuning | Defaults, runtime settings, calibration |
| Program flow | Boot sequence and state transitions |
| Troubleshooting | Common faults and source-level checks |
| Detailed reference | 126 code-mapped checks |
| TMC2226 migration | Driver configuration and migration history |
| Project history | PID, ESP-NOW, LQR/LQI, and runtime-tuning milestones |
| Legacy transmitter | ESP-NOW joystick packet and sampling |
