embedded-stepper
no_std stepper motor library for Rust, built on
embedded-hal— and a port of the classic ArduinoStepperinterface/behavior.
This crate provides a tiny, portable stepper motor controller for bare-metal targets. It reuses the familiar Arduino Stepper API concepts (steps per revolution, setSpeed, step) while embracing Rust’s generics and the [embedded-hal] traits for GPIO and timing.
Highlights
- Port of Arduino
Stepper: same model and sequencing style, now in Rust. no_std: suitable for MCUs; no heap, no OS.embedded-hal1.0 compatible:- Pin control via
embedded_hal::digital::OutputPin - Timing via
embedded_hal::delay::DelayNs
- Pin control via
- Common wirings included: 2‑pin, 4‑pin, and 5‑pin coil drivers
- Driver trait: users can implement drivers for other types of motors
- Ergonomic builders & type aliases for shorter type signatures.
Quick Start
The following example works with the esp32-c3 development board:
//Setup clock and peripherals
let config = default.with_cpu_clock;
let peripherals = init;
//Get the 4 GPIO pins, change these values based on your wiring
let p1 = peripherals.GPIO0;
let p2 = peripherals.GPIO1;
let p3 = peripherals.GPIO2;
let p4 = peripherals.GPIO3;
//Setup the 4 pins as output, low, no pull and Push/Pull (default output config)
let op1 = new;
let op2 = new;
let op3 = new;
let op4 = new;
//Adjust these values to fit your stepper motor. See the Arduino stepper library for more info
let speed = 625;
let steps_per_rev = 48;
//Instantiate the motor with the 4 output pins
let mut motor = create_stepper_4pin;
motor.set_speed;
//Turn motor
let _ = motor.step;
//Reverse motor
let _ = motor.step;
//Deenergise coils after use
let _ = motor.deenergise;
Design Notes
- Arduino parity: The public API mirrors Arduino’s
Stepperwhere it makes sense (e.g.,set_speed,step, steps per revolution). Internally, the controller is generic and decoupled. - Blocking by design:
Stepper::stepis blocking. For tight real-time loops, consider calling it from a cooperative scheduler or extend the crate with a non-blockingtick()style API. - Wiring/Sequences: 2/4/5 pin drivers implement simple 4-state sequences. Adjust sequences if your hardware requires half-stepping or microstepping—this crate provides a foundation rather than heavy abstraction.
Current Limitations (and Roadmap)
- Error handling: The built-in drivers currently use
type Error = ()and ignore pin I/O errors (theylet _ = pin.set_*()).
Planned: bind each driver’sErrorto the underlying pin error (type Error = <P1 as OutputPin>::Error) and propagate with?for fullembedded-halcompliance. - Non-blocking control: Provide an optional non-blocking controller (
tick()), plus acceleration/deceleration profiles.
Installing
Add to your Cargo.toml:
[]
= { = "https://github.com/ray33ee/embedded-stepper", = false }
= { = "1.0", = false }
This crate is no_std by default; keep default-features = false.
License
MIT © 2025 — see LICENSE.
Acknowledgements
This work intentionally ports the behavior and ergonomics of the Arduino Stepper library to Rust, while integrating with the embedded-hal ecosystem.