03Electronics & wiring

Two custom PCBs tie every actuator onto one local network: CAN for the motor buses, TTL serial for the hands and neck, Ethernet and USB 3 for the bandwidth. One battery powers everything — nothing trails behind the robot. Pinouts and harness drawings: MABEL_Wiring_Guide.pdf.

Bus map

BusPhysicalDevicesOwner MCU / link
Base CANCAN, 120 Ω both ends6 × SPARK (IDs 1–6)Base Teensy 4.1 → Ethernet
Arm leftCAN can07 × DaMiao (IDs 1–7)Arms Teensy → Ethernet
Arm rightCAN can17 × DaMiao (IDs 1–7)
Body CANCANTorso DM-J10422P + neck yaw DaMiaothe arms Teensy’s third CAN bus (since 2026-07-28). USB-CAN dongles are the documented fallback, not the primary path
Hand left1 MHz half-duplex TTL17 × Feetech (16 finger + wrist)USB serial adapter (CH340)
Hand right1 MHz half-duplex TTL17 × FeetechUSB serial adapter (CH340)
Neck TTL1 Mbaud half-duplex TTL2 × Dynamixel XC330-T181 (roll, pitch)U2D2 on the Jetson
LiftUSB serialBTS7960 + encoderRP2040 Pico
The two hand adapters are identical CH340s — the USB serial number is the only stable discriminator. Record each adapter's serial (ls -l /dev/serial/by-id/) and register it left/right in hardware_bridge/mabel_hw/config.py; the software then binds sides correctly no matter which port they land on.

Install order

  1. Land both custom PCBs — the base board in the chassis, the body board on its printed mount. The gerbers are NOT released yet (tracked in BOM/data/open_items.csv).
  2. Fan power out from the single pack. The bus is 24 V with a 24→12 V buck for the low rails, distributed through a blade-fuse box — fuse per the wiring guide. A 6-port 2.5 GbE switch is the onboard network spine.
  3. Bring up the CAN buses — base (6 SPARK), body (torso + neck yaw), and the two arm buses. Terminate every chain at both ends.
  4. Bring up the serial buses — one TTL chain per hand, the neck pair through the U2D2, the lift Pico over USB.
  5. Connect the sensing — head stereo camera (USB 3), wrist cameras, 2D lidar, and (Maximum tier) the base depth camera.
  6. Wire Ethernet — base Teensy and arms Teensy to the Jetson (directly or through the Ethernet expansion board — see network plan).
Keep the wrist cameras pinned by hub port on one powered USB 3 hub. Identical UVC cameras enumerate in arrival order; a fixed hub port is what makes left stay left across reboots.

Network plan

The robot's internal network is a flat 192.168.124.0/24:

NodeAddressNotes
Jetson (host)192.168.124.2assigned on whichever wired port answers
Base Teensy192.168.124.10swerve + lift relay
Arms Teensy192.168.124.11both arm CAN buses

The Teensys are port-agnostic: each may plug into the Jetson's direct NIC, a QSFP breakout lane, or the Ethernet expansion board (a small switch that puts several devices behind one port). The bring-up script discovers which port a Teensy actually answers on (ARP probe) and pins a host route to it at runtime — you do not hand-configure interfaces. A 100M link speed means a Teensy is plugged straight in; 10G means it is behind the expansion board.

Service ports (host)

Every client — browser, iPhone, Vision Pro — speaks to these; identical for the simulator and the real robot:

PortService
9090teleop WebSocket — the one wire contract (control + state + map)
8080camera video (MJPEG per camera, + /cameras.json roster, + web console)
9091 / 9092UDP-JPEG / H.264 low-latency video
9600telemetry plane — joints/control/status/lidar JSON (read-only)
9601–9605pointclouds per camera + SLAM mesh/pose/grid (read-only)
9610audio duplex (robot mic up / operator voice down)
9620–9623dedicated per-camera video tees
8094Control Center web studio

Audio

A USB sound card (VID:PID 0c76:1203) drives an 8 Ω / 5 W speaker pair and the microphone. It is identified by USB identity, not port — replug it anywhere and it reconnects. (Its serial number is hard-coded by the vendor, which is why identity is VID:PID here, unlike the hands.)

Power, and the one thing that is not wired

One 24 V supply, one buck converter, and a 12 V rail under it. Three loads get their own line straight from the supply, and the reason is the same in each case: motor spikes must not reach the compute.

LoadRailTaps from
Jetson Thor24 Vthe supply, on its own line
Torso bus24 Vthe supply — feeds both arms and the neck yaw
Arms, per joint group24 Vthe torso bus: J1+J2, J3+J4, J5+J6+J7
Lift controller24 Vthe supply, on its own line — the biggest current spike on the robot
6 base motor drivers12 Vthe buck
Ethernet board (and both Teensies)12 Vthe buck
USB expansion board12 Vthe buck — ten devices; never run it bus-powered
Left / right hand12 Vthe buck. Power only; data goes over USB
Neck Dynamixel bus12 Vthe buck. The U2D2 itself is USB-powered

Never share a return run: Thor, the lift controller and the torso bus each get their own pair. And the buck converter is a single point of failure — if the hands, the base and the whole USB tree die at once, check it first.

There is no hardware E-stop in this guide, because there is not one in the build. What exists is a software stop — hw.estop() on /mabel/hw/base/estop, lease-free and bypassing arbitration by design — and that is not the same thing as a switch that de-energises the actuators independently of the host. The safety notes assume the hardware path; the BOM tracks the switch and contactor as an uncosted open item at $30–80. Fit one before you first energise the arms.

Things that will cost you an evening

Wiring completion check