The SO-101 Low Level Console is a free, browser-only diagnostic and control
tool for the SO-101 (and SO-100) robot arm, built around the
Feetech STS3215 bus servos (the SMS/STS protocol family also used by many
LeRobot builds). It talks to the servos directly over the
Web Serial API — no Python, no LeRobot install, nothing to set up. Authorize
your USB serial adapter, autodetect the motors, and read or write any control-table register:
servo ID, baud rate, torque enable, torque limit, goal position, velocity, acceleration, and more.
You can also download a full backup of every servo's low-level configuration and restore it later.
Why is my SO-101 servo not responding?
A dead or silent Feetech STS3215 motor almost always comes down to one of four
things: the wrong baud rate (the SO-101 default is 1,000,000),
a duplicate or unexpected motor ID, another program (such as
lerobot) still holding the serial port, or loose bus wiring. Run
Autodetect above to ping IDs 1–20 across every authorized port and see exactly which
servos answer and which don't.
How do I change a Feetech STS3215 servo ID?
The servo ID lives in EEPROM at register address 5. Unlock EEPROM by writing the
Lock register to 0, write the new ID, then relock by writing Lock = 1.
Because the SO-101 leader and follower arms both ship with IDs 1–6, you must give each motor a
unique ID before chaining them on a single bus, otherwise they collide.
What baud rate does the SO-101 use?
The SO-101 and its STS3215 servos default to 1,000,000 baud (1 Mbps). If
Autodetect finds nothing, try 500,000 or 115,200 in case a
servo was reconfigured previously.
Do I need Python or LeRobot to debug SO-101 motors?
No. This console runs entirely in a Chromium-based browser (Chrome or
Edge) via Web Serial. It's a fast way to sanity-check hardware before — or
instead of — bringing up the full LeRobot stack.
Common SO-101 / LeRobot errors and how to fix them
These are the actual error messages raised by LeRobot's FeetechMotorsBus (and the
underlying Feetech / scservo SDK), with what each one usually means and where to fix it.
Could not connect on port '…'. Make sure you are using the correct port.
-
Either the wrong serial device, or the port is already taken — a serial port can have only one
owner. Close any running
lerobot process or other browser tab that has the arm open
(and check a missing CH340 / 1A86 USB driver), then retry. In this console, use
✕ Close all open ports in section 1 to release every port this page is holding.
Failed to open port '…'. / port is busy / access denied
-
The OS refused to open the device. Almost always another program still holds it, or you don't
have permission (on Linux, add yourself to the
dialout group). Free the port and
retry — only one owner at a time.
Motor '…' (model '…') was not found. Make sure it is connected.
-
The servo isn't answering a ping. Check the baud rate (SO-101 default is
1,000,000 — also try 500,000 or 115,200), confirm the motor ID,
and verify bus wiring and power. Run Autodetect here to ping IDs 1–20 across
every authorized port and see exactly which motors respond.
Failed to write '…' on id_=… after N tries. / Failed to read '…' on id_=… after N tries. / Failed to sync read '…' on ids=… after N tries.
-
LeRobot retries a packet several times (often described as "write failed after 6 retries")
before raising this. It almost always means a flaky or intermittent bus, not a software bug: a
loose servo cable or daisy-chain connector, marginal power (servos brown out under load),
electrical noise, or one motor on the wrong baud rate dragging down a group sync. Reseat every
connector, give the arm adequate 5–7.4 V power, and use
Autodetect — a servo that only answers intermittently is the bad link.
[TxRxResult] There is no status packet! / [RxPacketError] / checksum error
-
The controller sent a command but got no valid reply (or a corrupted one). Same root causes as
the retry errors above — wiring, power, noise, or a baud/ID mismatch. Toggle
show raw byte traffic in the Log to watch the actual packets and see whether the
servo replies at all.
Some motors have the same id!
-
Two servos on one bus share an ID — the SO-101 leader and follower both ship with IDs 1–6, so
chaining them collides. Give each motor a unique ID: write the
ID register (EEPROM
address 5), unlocking with Lock=0 and relocking with Lock=1. Connect one
motor at a time when reassigning so you know which one you're changing.
Found one motor on baudrate=… with id=… but it has a model number '…' different than the one expected…
-
During motor setup LeRobot found a servo but not the model it expected for that joint —
usually a wrong/swapped motor, or more than one servo on the bus while configuring. The message
tells you to be connected to only the one motor being set up.
Magnitude … exceeds … (max for sign_bit_index=…) / Value … out of range for N-byte two's complement
-
A position/value is outside the encodable range during calibration or a write —
often the arm wasn't in the correct pose, a horn was reassembled at the wrong angle, or the homing
offset is off. Use Read on
Present_Position to see the raw value and
check Min/Max_Position_Limit and the homing-offset registers.
Invalid calibration for motor '…': min and max are equal. / Some motors have the same min and max values / … has no calibration registered.
-
Calibration is missing or degenerate — you didn't move a joint through its full range (so min == max),
or the arm was never calibrated. Re-run calibration and move every joint corner-to-corner. You can
sanity-check live travel by reading
Present_Position while moving each joint by hand.
Failed to write bus baud rate.
-
A baud-rate change to the bus didn't take. Confirm the servo is reachable at its current
baud first (Autodetect across baud rates), then change it. If a servo was left at an odd baud, scan
every rate to find it before rewriting.
Some motors are incompatible with protocol_version=… / Some motors use an incompatible protocol.
-
A motor on the bus speaks a different Feetech protocol than the bus is configured for (STS/SMS use
protocol 0). Make sure every servo is the expected STS3215-family model and that the configured
protocol version matches.
- Servo "lost" after a bad EEPROM write (wrong ID or baud)
-
If you changed ID or baud and can no longer reach the servo, scan every baud rate and ID with
Autodetect to find where it moved to, then write it back. Download a config
backup first so you always have a known-good restore point.
Keywords: SO-101 servo diagnostics · Feetech STS3215 control table · change servo ID ·
some motors have the same id · motor was not found · failed to write after N tries ·
write failed after 6 retries · could not connect on port · failed to open port · port is busy ·
no status packet · min and max are equal · magnitude exceeds max · calibration · torque limit ·
baud rate · CH340 driver · dialout group · SO-100 · SO-ARM101 · SMS/STS bus servo · LeRobot ·
FeetechMotorsBus · Web Serial · scservo SDK.