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):

Video of a Adafruit DRV8833 DC/Stepper Motor Driver Breakout Board connected to a half sized white board powering a stepper motor with a adabot head spinning on it.
Spin two DC motors or step one bi-polar or uni-polar stepper with up to 1.2A per channel using the DRV8833. This motor driver chip is a nice alternative to the TB6612 driver. Like that...
$5.95
In Stock
Video of a spinning motor driver connected to a Adafruit TB6612 1.2A DC/Stepper Motor Driver Breakout Board.
Spin two DC motors, step one bi-polar or uni-polar stepper, or fire off two solenoids with 1.2A per channel using the TB6612. These are perhaps better known as "
$6.95
In Stock

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)

This guide was first published on Feb 17, 2021. It was last updated on Feb 17, 2021.

This page (Stepper Motor) was last updated on May 26, 2023.

Text editor powered by tinymce.