Ramp the step rate up and down
What this example shows
The motor speeding up and then slowing back down. The module has no built-in acceleration curve, so the example builds one the simple way: it shortens the delay between steps a little more each time round, then lengthens it again.
Only DIR and STEP are used here. ENABLE, RESET and SLEEP are left out of
begin(), so RESET and SLEEP must be tied high in hardware for this sketch to
run: both have internal pulldowns and would otherwise hold the driver in reset
and asleep.
The example's pin numbers, GPIO4 for DIR and GPIO5 for STEP, are both broken out on the NULA DeepSleep ESP32-S3, so this code runs unchanged.
The example code
from drv8825 import DRV8825 # Import the DRV8825 motor driver module
from time import sleep # Import sleep function for timing delays
# Define GPIO pins for motor control
DIR_PIN = 4 # GPIO pin used for direction control
STEP_PIN = 5 # GPIO pin used for step pulses
# Create a DRV8825 motor instance
motor = DRV8825()
# Initialize the motor with the specified DIR and STEP pins
motor.begin(DIR=DIR_PIN, STEP=STEP_PIN)
# Set the number of steps the motor takes per full rotation (usually 200 for a 1.8° stepper motor)
motor.setStepsPerRotation(200)
# Set the length of each step pulse in microseconds
motor.setStepPulseLength(1000)
# Set motor rotation direction to clockwise
motor.setDirection(DRV8825.CLOCK_WISE)
# Enable the motor driver (turns on output)
motor.enable()
print("Accelerating")
# Gradually increase the step frequency (i.e., speed up the motor)
accelerationFactor = 1
while accelerationFactor < 2000:
motor.step() # Send a single step pulse to the motor
sleep(
1 / accelerationFactor
) # Delay inversely proportional to the factor (higher = faster)
accelerationFactor += 1 # Increase acceleration factor
print(accelerationFactor) # Print current acceleration factor
# Gradually decrease the step frequency (i.e., slow down the motor)
while accelerationFactor > 1:
motor.step() # Send a single step pulse
sleep(1 / accelerationFactor) # Delay increases as acceleration factor decreases
accelerationFactor -= 1 # Decrease acceleration factor
print(accelerationFactor) # Print current acceleration factor
Expected result:
Accelerating
2
3
4
...
2000
1999
1998
...
2
The counter is printed by the example on every step, so the shape is exact: it climbs from 2 to 2000, then counts back down to 2.
The motor starts almost stationary and speeds up. The first step waits a full second, and the pace picks up quickly from there, so most of the run time is spent in the first handful of steps. Expect the whole ramp to take tens of seconds rather than a moment.
This example calls enable() but never passes an enable pin to begin(), so
that call returns False and does nothing. It does not matter here: the
driver's ENABLE input is active low with an internal pulldown, so an unwired
pin sits low and the outputs are enabled anyway.
Functions used
DRV8825()returns DRV8825Creates the driver object. It configures nothing on its own; every pin is set up by begin().
ReturnsA new driver instance with no pins assigned.
Parameters
This constructor takes no parameters.
begin(DIR, STEP, EN=None, RST=None, SLP=None)returns boolAssigns the control pins and configures them as outputs. Called here with only DIR and STEP, which leaves EN, RST and SLP unmanaged. RESET and SLEEP must then be held high in hardware.
ReturnsTrue once the pins are configured.
Parameters
| Type | Name | Description |
|---|---|---|
int | DIR | GPIO number for the direction pin. |
int | STEP | GPIO number for the step pin. |
int | EN | GPIO number for the enable pin. Optional, defaults to None. |
int | RST | GPIO number for the reset pin. Optional, defaults to None. |
int | SLP | GPIO number for the sleep pin. Optional, defaults to None. |
setStepsPerRotation(steps)returns NoneTells the module how many steps make one full rotation, so it can track position within a rotation. A 1.8 degree motor at full step takes 200. It does not change how the motor is driven.
ReturnsNothing.
Parameters
| Type | Name | Description |
|---|---|---|
int | steps | Steps per full rotation. |
setStepPulseLength(length)returns NoneSets how long the STEP pin is held high, and then low, inside each step() call, in microseconds. This is the floor on how fast the motor can be stepped: at 1000 microseconds each step() takes at least 2 ms on its own, before any delay you add on top.
ReturnsNothing.
Parameters
| Type | Name | Description |
|---|---|---|
int | length | Pulse length in microseconds. |
setDirection(direction)returns boolSets the direction pin. Use the class constants DRV8825.CLOCK_WISE and DRV8825.COUNTER_CLOCK_WISE rather than raw numbers. Any other value is rejected and the pin is left alone. The constant names describe the DIR level, not a guaranteed shaft direction, which follows your coil wiring.
ReturnsTrue if the direction was valid, False otherwise.
Parameters
| Type | Name | Description |
|---|---|---|
int | direction | DRV8825.CLOCK_WISE (1) or DRV8825.COUNTER_CLOCK_WISE (0). |
enable()returns boolEnables the driver outputs by pulling the ENABLE pin low. Returns False if no enable pin was passed to begin().
ReturnsTrue if the pin was driven, False if no enable pin is configured.
Parameters
This function takes no parameters.
step()returns NoneAdvances the motor one step: pulses STEP high then low, waiting the configured pulse length at each level. Calling it in a loop with a shrinking delay is what produces the ramp.
ReturnsNothing.
Parameters
This function takes no parameters.
getSteps()returns intThe number of steps taken since the counter was last reset. Useful for checking how far a ramp actually got.
ReturnsTotal steps counted.
Parameters
This function takes no parameters.
resetSteps(s=0)returns intResets the step counter and hands back what it was before, so you can measure one move without losing the previous total.
ReturnsThe step count as it was before the reset.
Parameters
| Type | Name | Description |
|---|---|---|
int | s | New value for the counter. Optional, defaults to 0. |
Putting it together
sleep(1 / accelerationFactor) is the whole acceleration curve. At the start the
factor is 1, so the motor waits a full second between steps. By the end it is
2000 and the wait is half a millisecond.
At that point the delay has stopped being what sets the speed.
setStepPulseLength(1000) holds STEP high for 1 ms and low for 1 ms inside every
step() call, so no matter how small the sleep gets, a step cannot take less
than about 2 ms. The last few hundred iterations of the ramp barely differ from
each other. If you want the top end to actually be fast, shorten the pulse
length as well as the delay.
Ramping matters with steppers. Asking a loaded motor to jump straight to full speed makes it skip steps, and skipped steps mean the position you think you are at is not the position you are at. Starting slow and building up avoids that.
If you want to know how far the motor travelled, call resetSteps() before the
ramp and getSteps() after.