Python library for MKS SERVO42D RS485 stepper drivers
Project description
mks-servo
Python library for MKS SERVO42D RS485 stepper drivers (NEMA17 / NEMA23 form factors), with a Servo-style high-level API and per-motor YAML profiles.
Why
The MKS SERVO42D ships with a 14-bit closed-loop encoder and a rich serial
protocol (~30 opcodes), but no Python library wrapping it at a "set angle,
read angle" level. mks-servo does:
- Servo-style API:
motor.write(90),motor.read(). - YAML profiles per motor — software limits, mechanical info, calibration results travel with the file.
mks-servoCLI for creating, snapshotting, validating, and inspecting profiles.
Install
Pre-1.0 — not yet on PyPI. Install from source:
git clone https://github.com/sammyriccardi/mks-servo.git
cd mks-servo
pip install -e ".[dev,bench]" # quote the extras; zsh/bash both need it
Requires Python 3.10+. The only runtime dependency you'll actually notice
is pyserial; everything else is optional or used by the CLI / tests.
See CONTRIBUTING.md for the development setup and TDD workflow.
Quick start
-
Connect your MKS SERVO42D over RS485 to a USB-RS485 adapter.
-
Snapshot the driver into a profile:
mks-servo profile from-driver --port /dev/ttyUSB0 --addr 1 --as wrist
-
Move it from Python:
from mks_servo import Motor with Motor.from_profile("wrist") as m: m.set_origin() m.position_limits = (-90, 90) for angle in [0, 45, 90, -45, 0]: m.write(angle, rpm=300) print(f"target={angle}° read={m.read():+.2f}°")
Multi-motor (v0.2.0+)
Coordinate N motors on the same RS485 bus:
from mks_servo import MotorBus
with MotorBus("/dev/ttyUSB0", baud=38400) as bus:
wrist = bus.add("./profiles/wrist.yaml") # slave_addr=1
elbow = bus.add("./profiles/elbow.yaml") # slave_addr=2
wrist.write(45)
elbow.write(90)
Discover what's on the bus and auto-generate profiles for each driver:
mks-servo bus discover --port /dev/ttyUSB0 --range 1-16 --create-profiles
See examples/dual_motor_bus.py and docs/multi-motor.md for more.
Characterization (v0.3.0+)
Run empirical tests and persist results into the profile:
mks-servo characterize wrist --suite=mvp --update-profile --save
Or programmatically:
from mks_servo import Motor, CharacterizationSuite
with Motor.from_profile("wrist") as m:
suite = CharacterizationSuite(m)
suite.run_mvp()
suite.update_profile()
m.profile.save()
See examples/characterize_motor.py and docs/characterization.md.
API levels
mks-servo exposes four progressively richer surfaces. Pick the lowest one
that lets you express what you need:
| Level | Surface | When to use |
|---|---|---|
| 0 | Motor.attach/detach/write/read/error/is_moving/emergency_stop |
"Arduino Servo, but more powerful" |
| 1 | motor.work_current_ma, set_origin, calibrate, move_relative, properties |
Day-to-day robotics code |
| 2 | motor.advanced.*, motor.diagnostics.* |
Flash-rewriting config + health checks |
| 3 | motor.raw.* |
1:1 protocol-level control |
MotorBus and CharacterizationSuite live alongside these on the same
import path.
Project layout
mks_servo/— library sourcemotor.py,profile.py— Level 0 + 1 surface and the profile systembus.py,transport.py—MotorBusand the shared, lock-protected RS485 transportnamespaces.py— Level 2 (advanced,diagnostics) attached toMotorcharacterize.py—CharacterizationSuiteprogrammatic P1/P3/P5/S2 testsraw.py,protocol.py,constants.py,exceptions.py— Level 3 + framingcli/—mks-servocommand-line tool
benchmarks/— characterization scripts (CSV + PNG output underresults/<timestamp>/)tests/— pytest test suite (~312 mocked tests + an opt-in HIL suite undertests/hil/)docs/— design docs, specs, characterization reports
Documentation
- CHANGELOG — release notes for every version
- CONTRIBUTING — dev setup, TDD workflow, HIL rig info
- CODE_OF_CONDUCT — Contributor Covenant 2.1
- Profile schema reference
- Multi-motor on one bus
- Characterization
- v0.3.0 design spec
- v0.2.0 design spec
- v0.1.0 design spec
- Long-term vision
- HIL test report (2026-05-09)
- MKS SERVO42D firmware manual
Status
Pre-1.0 (currently 0.3.1). The Level 0 / 1 / 3 surface is HIL-validated
and the API is stable. Level 2 has two corners explicitly marked
experimental in their docstrings (flash-rewriting calls deliberately
excluded from the HIL suite). The 1.0 release is gated on a soak test, full
Sphinx docs, and PyPI publication — see docs/superpowers/specs/ for the
roadmap.
License
Licensed under the Apache License 2.0. See NOTICE for the attribution notice. The Apache 2.0 patent grant is intentional: this library is meant to be safe to use in hardware and robotics products.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mks_servo-1.0.0.tar.gz.
File metadata
- Download URL: mks_servo-1.0.0.tar.gz
- Upload date:
- Size: 65.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6e71c38b3db6dbf23dd04da38470024c9f74acee14c3ca3fd3e62486095ed8b
|
|
| MD5 |
262752742898f9dcf17bd0e43fcff637
|
|
| BLAKE2b-256 |
12be81a8d7db48885f432eca9e25679115c3d396b1775a12983f8281ecfc52e9
|
File details
Details for the file mks_servo-1.0.0-py3-none-any.whl.
File metadata
- Download URL: mks_servo-1.0.0-py3-none-any.whl
- Upload date:
- Size: 44.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5863ea6177d5af910684e6b0dbc1c190424e97620649a43df1b96b23ac9ec6a8
|
|
| MD5 |
33510adccd5dd91ffaf83960edcd4ba1
|
|
| BLAKE2b-256 |
7c43aa39c56ea9b20b8974fc9c6dc19e5cbdb870e4d9143b7a4df303878aaa77
|