Grafito Innovations

CANStepper

Closed-loop stepper motion over CAN. An ESP32-C3, TMC2209 and MT6701 encoder on every motor; a clean Python library on the host.

Closed-loop by default

14-bit magnetic encoder on every axis with a 200 Hz position loop, settle detection and stall watchdog on the board itself.

One bus, 31 axes

Daisy-chain boards over 1 Mbps CAN and drive them all from Python through the USB port of any node.

Safety in three scopes

Latched emergency stop per node, per group, or the whole bus with a single broadcast frame.

Real machines, not just motors

Millimetre units, endstop and sensorless homing, dual-motor gantries coupled on-bus, CoreXY, and declarative machine.toml configs.

from canstepper import CANStepperBus

with CANStepperBus.serial("/dev/ttyACM0") as bus:
    print(bus.discover())            # {1: '1.0', 2: '1.0', ...}
    node = bus.node(1)
    node.set_run_current(40).enable()
    node.move_to(360.0, blocking=True)
    bus.estop_all()                  # one broadcast frame