Stepper motors -- much like their name implies, they "step" along.
These come with four, five or six wires.
Like DC motors, they rotate all the way around. But they do so very slowly, because of the little steps they have to take
Like Servos, they have precision motion. But not the way servos do, where you can set a specific angle. Instead you can rotate forward and back by little steps.
Learn more about steppers here.
You'll need a stepper motor driver (a.k.a a dual H-Bridge):


The DRV8833 motor controller can control the two motor coils inside the stepper motor (think of it like a circular bucket brigade passing the power around A-B-A-B-A-B and so on) by receiving signals from four digital output pins on the Pico.
Wire it up as shown in the diagram here.
Pico
- Pico pin 27 (GP21) to driver pin BIN1
- Pico pin 26 (GP20) to driver pin BIN2
- Pico pin 25 (GP19) to driver pin AIN2
- Pico pin 24 (GP18) to driver pin AIN1
- Pico GND to driver GND
- Pico 3v3 to driver VM
- Pico pin 30 (RESET) to reset button to GND
- Pico pin 5 (GP3) to mode button to GND
Power
- Power supply 5V+ to driver SLP
- Power supply GND to common ground
Motor (wiring color varies by motor)
- Orange motor wire to driver AOUT1
- Pink motor wire to driver AOUT2
- Blue motor wire to driver BOUT1
- Yellow motor wire to driver BOUT2
Code
Copy the code from the element below, and paste it into a fresh file in Mu. Save the file to your Pico's CIRCUITPY drive as code.py It will automatically run the code!
Press the mode button to have the stepper run through a single revolution forward and then a single revolution backward.
# SPDX-FileCopyrightText: 2021 jedgarpark for Adafruit Industries # SPDX-License-Identifier: MIT # Pico stepper demo # Hardware setup: # Stepper motor via DRV8833 driver breakout on GP21, GP20, GP19, GP18 # external power supply # Button on GP3 and ground import time import board from digitalio import DigitalInOut, Direction, Pull from adafruit_motor import stepper print("Stepper test") led = DigitalInOut(board.LED) led.direction = Direction.OUTPUT led.value = True def blink(times): for _ in range(times): led.value = False time.sleep(0.1) led.value = True time.sleep(0.1) # Mode button setup button = DigitalInOut(board.GP3) button.direction = Direction.INPUT button.pull = Pull.UP mode = -1 # track state of button mode # Stepper motor setup DELAY = 0.006 # fastest is ~ 0.004, 0.01 is still very smooth, gets steppy after that STEPS = 513 # this is a full 360º coils = ( DigitalInOut(board.GP21), # A1 DigitalInOut(board.GP20), # A2 DigitalInOut(board.GP19), # B1 DigitalInOut(board.GP18), # B2 ) for coil in coils: coil.direction = Direction.OUTPUT stepper_motor = stepper.StepperMotor( coils[0], coils[1], coils[2], coils[3], microsteps=None ) def stepper_fwd(): print("stepper forward") for _ in range(STEPS): stepper_motor.onestep(direction=stepper.FORWARD) time.sleep(DELAY) stepper_motor.release() def stepper_back(): print("stepper backward") for _ in range(STEPS): stepper_motor.onestep(direction=stepper.BACKWARD) time.sleep(DELAY) stepper_motor.release() def run_test(testnum): if testnum is 0: stepper_fwd() elif testnum is 1: stepper_back() while True: if not button.value: blink(2) mode = (mode + 1) % 2 print("switch to mode %d" % (mode)) time.sleep(0.8) # big debounce run_test(mode)
How It Works
Libraries
First, the libraries are imported for time
, board
for pin definitions, digitalio
to use buttons as input and control pins as outputs to the driver board, and the stepper
module from adafruit_motor
for easy servo motor control.
import time import board from digitalio import DigitalInOut, Direction, Pull from adafruit_motor import stepper
LED
The on-board LED is set up and turned on to show that the code is running, and will blink when the button is pressed.
led = DigitalInOut(board.LED) led.direction = Direction.OUTPUT led.value = True def blink(times): for _ in range(times): led.value = False time.sleep(0.1) led.value = True time.sleep(0.1)
Button
The button is set up on pin GP3 as an input with internal pull up resistor. When the button is pressed the mode
variable will increment to set the servo test state.
button = DigitalInOut(board.GP3) button.direction = Direction.INPUT button.pull = Pull.UP mode = -1 # track state of button mode
Stepper Setup
The stepper is set up next. DELAY
sets the speed of the stepper, and the STEPS
value is the number of steps in the motor.
The coils to be controlled by the driver board are set up on four of the Pico's digital output pins, next, and then the stepper object is created with these pins.
DELAY = 0.006 # fastest is ~ 0.004, 0.01 is still very smooth, gets steppy after that STEPS = 513 # this is a full 360º coils = ( DigitalInOut(board.GP21), # A1 DigitalInOut(board.GP20), # A2 DigitalInOut(board.GP19), # B1 DigitalInOut(board.GP18), # B2 ) for coil in coils: coil.direction = Direction.OUTPUT stepper_motor = stepper.StepperMotor( coils[0], coils[1], coils[2], coils[3], microsteps=None )
Stepper Functions
Two functions are made to control the stepper in a full revolution -- one forward, one backward -- and then a helper function is made to call those.
def stepper_fwd(): print("stepper forward") for _ in range(STEPS): stepper_motor.onestep(direction=stepper.FORWARD) time.sleep(DELAY) stepper_motor.release() def stepper_back(): print("stepper backward") for _ in range(STEPS): stepper_motor.onestep(direction=stepper.BACKWARD) time.sleep(DELAY) stepper_motor.release() def run_test(testnum): if testnum is 0: stepper_fwd() elif testnum is 1: stepper_back()
Main Loop
The main loop of the program watches for the button to be pressed and then runs the run_test()
function alternating forward or backward with each button press.
while True: if not button.value: blink(2) mode = (mode + 1) % 2 print("switch to mode %d" % (mode)) time.sleep(0.8) # big debounce run_test(mode)
Page last edited January 22, 2025
Text editor powered by tinymce.