Metadata-Version: 2.4
Name: grafito-canstepper
Version: 0.1.0
Summary: Host library for Grafito CANStepper boards (GCSP v1): multi-node CAN stepper control with encoders, homing, groups and coordinated motion
Author-email: Grafito Innovations <grafito.innovations@gmail.com>
License: Apache-2.0
Project-URL: Documentation, https://docs.grafito.in
Project-URL: Homepage, https://docs.grafito.in
Project-URL: Source, https://github.com/Grafito-Innovations/Grafito-Edge-Services/tree/main/can_stepper
Project-URL: Issues, https://github.com/Grafito-Innovations/Grafito-Edge-Services/issues
Keywords: stepper,CAN,motion-control,esp32,tmc2209,encoder
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Manufacturing
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Hardware :: Hardware Drivers
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: pyserial>=3.4
Provides-Extra: toml
Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "toml"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "dev"
Dynamic: requires-python

# Grafito CANStepper

Closed-loop stepper motor control over CAN. Each board carries an ESP32-C3,
a TMC2209 driver, an MT6701 14-bit magnetic encoder and a CAN transceiver;
up to 31 boards daisy-chain on one 1 Mbps bus and are driven from Python
through the USB port of any board on the chain.

```
can_stepper/
├── firmware/GrafitoCANStepper_C3/   # node firmware (GCSP v1)
├── canstepper/                      # Python package (grafito-canstepper)
├── examples/                        # runnable examples + machine.toml
├── tests/                           # pytest suite (runs on a software sim)
└── docs/
    ├── PRD.md                       # product requirements
    ├── protocol.md                  # GCSP v1 wire protocol reference
    └── quickstart.md                # unboxing -> moving motor
```

## Highlights

- **Layered Python API** — raw frames → `StepperNode` → `NodeGroup` →
  `Axis` (mm units via `rotation_distance`) → `DualMotorAxis` / `CoreXY` /
  `MotionGroup` → declarative `machine.toml`.
- **Safety scopes** — `node.estop()`, `group.estop()`, `bus.estop_all()`
  (single broadcast frame); e-stop is latched until re-enabled.
- **Homing** — physical endstop on IO8, sensorless (StallGuard), or
  set-zero; configurable current, backoff and timeout.
- **Closed loop** — firmware ≥1.2 plans a rest-to-rest **trapezoidal**
  trajectory with **velocity feedforward** and a light tracking PID on the
  MT6701 encoder (settle + stall watchdog). All motion limits are
  *configurable defaults*, never hard clamps.
- **On-bus leader/follower** — dual-motor gantries stay coupled with no
  host in the loop.
- **Simulator included** — `canstepper.sim.SimNetwork` implements the whole
  protocol in software; the test suite and the examples run without hardware.

## Install & first spin

The package is **`grafito-canstepper`** on the index; you `import canstepper`.

```bash
# Works today (GitHub monorepo subdirectory — not yet on PyPI):
pip install "git+https://github.com/Grafito-Innovations/Grafito-Edge-Services.git#subdirectory=can_stepper"

# Development (from this directory):
pip install -U pip setuptools && pip install -e ".[dev]"

# After publishing to PyPI:
# pip install grafito-canstepper
```

Docs: **https://docs.grafito.in**

```python
from canstepper import CANStepperBus

with CANStepperBus.serial("/dev/ttyACM0") as bus:
    print(bus.discover())
    node = bus.node(1)
    node.set_run_current(40).enable()
    node.move_to(360.0, blocking=True)
```

Continue with:

- [docs/quickstart.md](docs/quickstart.md) — first motion
- [docs/closed_loop_tuning.md](docs/closed_loop_tuning.md) — trapezoid + v_ff,
  hardware matrix + 10 min soak on **PR42HS40-1204AF-02** (NEMA 17 1.2 A)
- [docs/protocol.md](docs/protocol.md) — GCSP v1 wire protocol

## Development

```bash
cd can_stepper
python3 -m pytest            # simulator suite
python3 tools/cl_speed_validate.py /dev/ttyACM0 1 70 8   # hardware OL vs CL
```

Firmware builds with Arduino IDE or `arduino-cli` (ESP32C3 Dev Module, USB
CDC On Boot = Enabled; libraries: FastAccelStepper, TMC2209 janelia-arduino):

```bash
arduino-cli compile --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc \
  firmware/GrafitoCANStepper_C3
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32c3:CDCOnBoot=cdc \
  firmware/GrafitoCANStepper_C3
```

## Legacy note

`CANStepperNode_C3/` and `canbus.py` are the earlier bring-up firmware and
host script based on a third-party protocol. They are superseded by the
clean-room GCSP v1 stack above and kept only for reference during migration.
