Great question — I traced the source in ./lerobot/, and the key thing is:
LeRobot is not hardcoding “7.4V motor with 12V supply” checks itself.
It relies on the motor firmware status error bits returned in Feetech status packets.
lerobot/pyproject.toml → lerobot-setup-motors="lerobot.scripts.lerobot_setup_motors:main"lerobot/src/lerobot/scripts/lerobot_setup_motors.pylerobot/src/lerobot/robots/so_follower/so_follower.py → SOFollower.setup_motors()self.bus.setup_motor(motor)lerobot/src/lerobot/motors/motors_bus.py → SerialMotorsBus.setup_motor()_find_single_motor(...)lerobot/src/lerobot/motors/feetech/feetech.py_find_single_motor_p0() → broadcast_ping()broadcast_ping() collects per-motor status/error and logs:
Some motors found returned an error status: ...[RxPacketError] Input voltage error!In SDK (not LeRobot core logic):
.venv/lib/python3.12/site-packages/scservo_sdk/protocol_packet_handler.py
ERRBIT_VOLTAGE = 1getRxPacketError() maps that bit to:
"[RxPacketError] Input voltage error!"So physically, the motor firmware detects out-of-range voltage, sets error bit in status byte, and LeRobot surfaces it.
{id, error_byte, payload}error & 0x01 => voltage)Present_Voltage, Min_Voltage_Limit, Max_Voltage_LimitLeRobot currently mostly does:
If you want, next I can help you add a debug patch in LeRobot so setup-motors prints:
Present_Voltage,Perfect — I wrote a read-only diagnostic script here:
scripts/inspect_feetech_voltage_readonly.pyIt does not write any registers. It only:
It should help answer exactly your question: is there extra info beyond the UX-level message?
(especially raw error byte and multiple flags, not just the first mapped string).
If you want, I can run one of these now — but I’ll wait for your go-ahead as requested.
Done — scan mode ran successfully.
sts3215)0x01 = Input voltage errorPresent_Voltage: 122 → ~12.2VMax_Voltage_Limit: 80 → ~8.0VMin_Voltage_Limit: 40 → ~4.0VSo yes, there is more information than the UX message:
Also confirmed: this script performed only ping/read operations (no writes).
If you want, next I can extend the script to decode bitfields like Unloading_Condition and LED_Alarm_Condition into human-readable flags too.
Implemented ✅ — I added a PR-ready change in LeRobot to do exactly what you asked:
In broadcast_ping(), it still logs the original message first:
"Some motors found returned an error status: ..."If any motor has ERRBIT_VOLTAGE, it now logs:
Then it performs extra register reads (second round trip) and logs:
StatusPresent_VoltageMin_Voltage_LimitMax_Voltage_Limitwith raw comm/error fields and derived volts.
So this is exactly the staged behavior you requested:
lerobot/src/lerobot/motors/feetech/feetech.py
VOLTAGE_DIAGNOSTIC_REGISTERS_has_voltage_error(...)_read_voltage_diagnostics(...)broadcast_ping(...) to do two-stage reportinglerobot/tests/motors/test_feetech.py
test_broadcast_ping_voltage_error_logs_extra_diagnostics(...)You were exactly right to ask this:
The initial broadcast ping status packet does not include min/max/present voltage register values.
So we must do a second read pass to fetch those details.
I compiled modified files successfully (py_compile), but couldn’t run full pytest locally because this environment is missing test tooling/deps (pytest, serial in that test env).
If you want, I can also draft the exact PR title + description text for you to paste into GitHub.
Yep — quick source list:
CLI entrypoint
lerobot/pyproject.toml
lerobot-setup-motors="lerobot.scripts.lerobot_setup_motors:main"Command flow
lerobot/src/lerobot/scripts/lerobot_setup_motors.pylerobot/src/lerobot/robots/so_follower/so_follower.py (setup_motors)lerobot/src/lerobot/motors/motors_bus.py (setup_motor)Where your exact log comes from
lerobot/src/lerobot/motors/feetech/feetech.py (broadcast_ping)Some motors found returned an error status: ...Why message string is exactly that
.venv/lib/python3.12/site-packages/scservo_sdk/protocol_packet_handler.py
ERRBIT_VOLTAGE = 1getRxPacketError() → "[RxPacketError] Input voltage error!"Where voltage registers/addresses come from
lerobot/src/lerobot/motors/feetech/tables.py
Present_Voltage = (62, 1)Min_Voltage_Limit = (15, 1)Max_Voltage_Limit = (14, 1)Status = (65, 1)Evidence in tests that voltage error is expected behavior
lerobot/tests/motors/test_feetech.py
"[RxPacketError] Input voltage error!" for ERRBIT_VOLTAGEHardware confirmation from your actual device
scripts/inspect_feetech_voltage_readonly.py on your port:
Present_Voltage = 122 (~12.2V)Max_Voltage_Limit = 80 (~8.0V)0x01 (voltage bit)