Expand description
Stepper - Universal Stepper Motor Interface
Stepper aims to provide an interface that abstracts over stepper drivers and motion control chips, exposing high-level hardware features directly where available, or providing software fallbacks where hardware support is lacking.
Right now, Stepper supports the following ICs:
Please check out the documentation of Stepper
, which is the main entry
point to this API.
§Example
use stepper::{
fugit::NanosDurationU32 as Nanoseconds,
motion_control, ramp_maker,
Direction, Stepper,
};
// We need some `embedded_hal::digital::OutputPin` implementations connected
// to the STEP and DIR signals of our driver chip. How you acquire those
// depends on the platform you run on. Here, we'll use a mock implementation
// for the sake of demonstration.
let step = Pin;
let dir = Pin;
// We also need a timer (that implements `embedded_hal::timer::CountDown`),
// since there are time-critical aspects to communicating with the driver
// chip. Again, how you acquire one depends on your target platform, and
// again, we'll use a mock here for the sake of demonstration.
let mut timer = Timer::<1_000_000>::new();
// Define the numeric type we're going to use. We'll use a fixed-point type
// here, as that's the most widely supported. If your target hardware has
// support for floating point, it might be more convenient (and possibly
// efficient) to use that instead.
type Num = fixed::FixedI64<typenum::U32>;
// Define the target acceleration and maximum speed using timer ticks as the
// unit of time. We could also use seconds or any other unit of time
// (Stepper doesn't care), but then we'd need to provide a conversion from
// seconds to timer ticks. This way, we save that conversion.
//
// These values assume a 1 MHz timer, but that depends on the timer you're
// using, of course.
let target_accel = Num::from_num(0.001); // steps / tick^2; 1000 steps / s^2
let max_speed = Num::from_num(0.001); // steps / tick; 1000 steps / s
// We want to use the high-level motion control API (see below), but let's
// assume the driver we use for this example doesn't provide hardware
// support for that. Let's instantiate a motion profile from the RampMaker
// library to provide a software fallback.
let profile = ramp_maker::Trapezoidal::new(target_accel);
// Now we need to initialize the stepper API. We do this by initializing a
// driver (`MyDriver`), then wrapping that into the generic API (`Stepper`).
// `MyDriver` is a placeholder. In a real use-case, you'd typically use one
// of the drivers from the `stepper::drivers` module, but any driver that
// implements the traits from `stepper::traits` will do.
//
// By default, drivers can't do anything after being initialized. This means
// they also don't require any hardware resources, which makes them easier
// to use when you don't need all features.
let mut stepper = Stepper::from_driver(MyDriver::new())
// Enable direction control
.enable_direction_control(dir, Direction::Forward, &mut timer)?
// Enable step control
.enable_step_control(step)
// Enable motion control using the software fallback
.enable_motion_control((timer, profile, DelayToTicks));
// Tell the motor to move 2000 steps (10 revolutions on a typical stepper
// motor), while respecting the maximum speed. Since we selected a
// trapezoidal motion profile above, this will result in a controlled
// acceleration to the maximum speed, and a controlled deceleration after.
let target_step = 2000;
stepper
.move_to_position(max_speed, target_step)
.wait()?;
// Here's the converter that Stepper is going to use internally, to convert
// from the computed delay value to timer ticks. Since we chose to use timer
// ticks as the unit of time for velocity and acceleration, this conversion
// is pretty simple (and cheap).
use num_traits::cast::ToPrimitive;
pub struct DelayToTicks;
impl<const TIMER_HZ: u32> motion_control::DelayToTicks<Num, TIMER_HZ> for DelayToTicks {
type Error = core::convert::Infallible;
fn delay_to_ticks(&self, delay: Num)
-> Result<fugit::TimerDurationU32<TIMER_HZ>, Self::Error>
{
Ok(fugit::TimerDurationU32::<TIMER_HZ>::from_ticks(Num::to_u32(&delay).expect("the delay to convert")))
}
}
Re-exports§
pub extern crate embedded_hal;
pub extern crate fugit;
pub extern crate ramp_maker;
Modules§
- compat
- Compatibility code to help use Stepper on more platforms
- drivers
- Parent module for all driver implementations
- motion_
control - Software implementation of motion control capability
- step_
mode - Types related to working with a driver’s microstepping mode
- traits
- Traits that can be implemented by Stepper drivers
- util
- Utility module for miscellaneous stuff that the rest of the crate needs
Structs§
- Move
ToFuture - The “future” returned by
Stepper::move_to_position
- SetDirection
Future - The “future” returned by
Stepper::set_direction
- SetStep
Mode Future - The “future” returned by
Stepper::set_step_mode
- Step
Future - The “future” returned by
Stepper::step
- Stepper
- Unified stepper motor interface
Enums§
- Direction
- Defines the direction in which to rotate the motor
- Error
- Unified error type
- Signal
Error - An error that can occur while using this API