Pybricks-style robotics, on open hardware

openbricks is a MicroPython firmware you flash to a commodity ESP32 board. Wire up off-the-shelf servos and sensors, and drive robots with a clean Python API — motor control runs at 1 kHz in native C inside the firmware.

from openbricks.drivers.st3032 import ST3032Motor
from openbricks.robotics import DriveBase

left  = ST3032Motor(servo_id=1, tx=14, rx=6)
right = ST3032Motor(servo_id=2, tx=14, rx=6,
                     invert=True)

db = DriveBase(left, right,
               wheel_diameter_mm=56,
               axle_track_mm=114)

db.straight(500)  # millimetres
db.turn(90)       # degrees

See it drive

An openbricks-powered robot on a WRO-style mission mat — line following on the 10-channel reflectance bar, gyro turns on the ICM-45686, branch counting, and back to base. One minute, real time, no cuts.

Continuous mode

The same robot with the drivebase in continuous mode: each straight() and curve() ends with then=Stop.NONE, so moves hand their speed straight to the next one and the run flows through the course without stopping between segments.

A firmware, not a library

Pybricks gives LEGO users a delightful Python API, but only on LEGO hubs with LEGO motors. openbricks takes the same shape — a custom MicroPython firmware with the robotics library baked into the runtime — and targets parts you can buy anywhere.

Native control loops

The motor scheduler, trapezoidal trajectory planner, state observer, and 2-DOF drivebase controller are compiled C inside the image, ticking at 1 kHz off a hardware timer. Python is for your program, not the hot path.

Commodity hardware

ESP32-S3 and classic ESP32 boards, Feetech serial-bus servos, DC gear motors with encoders, and I2C sensors from any electronics shop. No proprietary hubs, no vendor lock-in.

Batteries-included tooling

One CLI does it all: openbricks flash over USB, then run, upload, stop, and log over BLE — plus a MuJoCo-backed simulator so you can develop without a robot on the desk.

Beyond the Pybricks feature set

Same programming model, different ceiling. Owning the whole runtime — firmware, tooling, and simulator — lets openbricks ship things a LEGO hub can't.

A flight recorder for every run

Every program run — prints, tracebacks, how it started and ended — is tee'd to flash on the hub. openbricks log pulls any of the last 10 runs back over BLE, so a failure on the competition table is debuggable after the fact, no laptop attached at the time.

A real physics simulator

The MuJoCo-backed sim runs your program unchanged — same imports, same DriveBase — against a quantitative motor model, and the color sensor reads printed mat artwork byte-accurately. Tune a line follower before the robot exists.

A serious gyro

The ICM-45686 is sampled over SPI inside the 1 kHz native control tick — heading integrates in C with no Python in the loop. Gyro bias calibrates itself whenever the robot sits still and persists across boots, so power-on-and-go starts straight.

Smarter motors

Daisy-chained serial-bus servos report position, speed, load, and temperature back over one UART — and a dead or disconnected wheel raises a loud error naming the exact motor, instead of a robot that quietly veers. Re-ID a servo from the hub itself with openbricks servo-id.

Any sensor you can buy

Reflectance bars, laser rangefinders, color sensors behind an I2C mux, OLEDs, LED strips — a dozen drivers ship frozen into the firmware, and new hardware just implements one small interface. No waiting for a vendor to bless a part.

Docs that travel

The full documentation ships inside the CLI — openbricks docs opens the same Sphinx build as docs.openbricks.dev, entirely offline. Competition venues with no Wi-Fi stop mattering.

Up and running in three steps

Full walkthrough in the installation guide.

Install the tooling

pipx install 'openbricks[sim]'

CLI + simulator. Drop [sim] for flash/run/log only.

Flash a hub

openbricks flash --name RobotA

Port and chip auto-detected; the newest signed firmware downloads itself.

Run your program

openbricks run -n RobotA main.py

Pushed over BLE, output streamed back live. Or try it first in the sim: openbricks sim run main.py

Supported components

Every driver ships frozen into the firmware — import openbricks and go. New components just implement one of the abstract interfaces. Wiring notes in the hardware guide.

ComponentTypeModule
ST-3032 (Feetech STS3032)Serial bus servo — recommended drive motordrivers.st3032
ST-3215Serial bus servo — arms / grippersdrivers.st3215
JGB37-520 / MG370DC gear motors with quadrature encodersdrivers.jgb37_520, drivers.mg370
L298N / TB6612FNGH-bridge motor driversdrivers.l298n, drivers.tb6612
ICM-456866-axis IMU on SPI — read inside the 1 kHz control tick, the use_gyro heading sourcedrivers.icm45686
BNO0559-DOF IMU (legacy I2C option)drivers.bno055
QTRX-HD-15A10-channel reflectance bar — line following & edge alignmentdrivers.qtr
TCS34725RGB + clear color sensordrivers.tcs34725
HC-SR04 / VL53L0X / VL53L1XUltrasonic & laser distance sensorsdrivers.hcsr04, drivers.vl53l0x, drivers.vl53l1x
TCA9548A8-channel I2C multiplexerdrivers.tca9548a
SSD1306OLED displaydrivers.ssd1306
WS2812 / WS2812BAddressable RGB LED strip / stickdrivers.ws2812