Why
Code that configures twelve nodes by hand is write-once, debug-forever. A
machine.toml names every node and axis, applies (and verifies) every
parameter at startup, and gives operations one file to review.
Example
[bus]
transport = "serial"
port = "/dev/ttyACM0"
[node.z_left]
id = 2
run_current = 40
hold_current = 15
microsteps = 16
closed_loop = 1
[node.z_right]
id = 3
run_current = 40
[node.feeder]
id = 6
max_speed = 1440.0
[axis.z]
type = "dual_motor"
primary = "z_left"
secondary = "z_right"
invert_secondary = true
rotation_distance = 8.0
max_speed = 15.0
require_homing = true
[axis.z.homing]
method = "stallguard"
direction = -1
speed = 5.0
current_percent = 25
backoff = 2.0
[axis.feed]
type = "single"
node = "feeder"
rotation_distance = 30.0Any key in a [node.*] table besides id must be a firmware parameter name
— unknown keys fail loudly with ConfigError instead of being silently
ignored.
Using it
from canstepper import Machine
with Machine.from_config("machine.toml") as m:
m.enable_all()
m.home("z") # uses [axis.z.homing]
m.axes["z"].move_to(50.0, blocking=True)
m.axes["feed"].run(12.0)
m.estop_all() # broadcast, everything halts- Parameters are applied volatile on load; call
m.save_all()to persist them to the boards' flash. m.check()reads back every parameter from every node — snapshot it in CI or before a production run to catch drift.- Axis types:
single,dual_motor,corexy.
On Python 3.9/3.10 reading TOML needs pip install tomli
(3.11+ uses the standard library). Passing a dict works everywhere.