Stepper Motor Examples - Raspberry Pi Pico¶
The following short Python programs will demonstrate essential operation of the
Raspberry Pi Pico board. These assume one or more binary input or output circuits are
externally attached. Each can be run by copying the program into code.py
on
the CIRCUITPY drive offered by the board. The text can be pasted directly from
this page, or each file can be downloaded from the CircuitPython sample code
folder on this site.
Related Pages
Sample A4988 Stepper Driver Circuit¶
A4988 Stepper Driver Demo¶
Direct download: a4988_demo.py.
1# a4988.py
2#
3# Raspberry Pi Pico - stepper motor driver support
4#
5# This module provides a class for controlling an Allegro 4988 stepper motor
6# driver. This device can drive one bipolar stepper motor up to 2A per coil
7# using microstepping current control.
8
9# A typical usage requires two digital outputs. The defaults assumes a Pololu
10# A4988 stepper driver has been wired up to the Pico as follows:
11#
12# Pico pin 21, GPIO16 -> DIR
13# Pico pin 22, GPIO17 -> STEP
14# any Pico GND -> GND
15
16# A4988 carrier board: https://www.pololu.com/product/1182
17
18# This implementation bit-bangs the step line and so is limited to about 1000
19# steps/sec as a result of CircuitPython execution speed. This solution is is
20# only suitable for low-speed stepper motion.
21
22# Likely a better long-term solution will be to use the RP2040 programmable IO
23# peripheral (PIO) to cycle the step output.
24
25################################################################
26# CircuitPython module documentation:
27# time https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/index.html
28# board https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/index.html
29# digitalio https://circuitpython.readthedocs.io/en/latest/shared-bindings/digitalio/index.html
30#
31# Driver lifecycle documentation:
32# https://circuitpython.readthedocs.io/en/latest/docs/design_guide.html#lifetime-and-contextmanagers
33#
34################################################################################
35# load standard Python modules
36import time
37
38# load the CircuitPython hardware definition module for pin definitions
39import board
40
41# load the CircuitPython GPIO support
42import digitalio
43
44#--------------------------------------------------------------------------------
45class A4988:
46 def __init__(self, DIR=board.GP16, STEP=board.GP17):
47 """This class represents an A4988 stepper motor driver. It uses two output pins
48 for direction and step control signals."""
49
50 self._dir = digitalio.DigitalInOut(DIR)
51 self._step = digitalio.DigitalInOut(STEP)
52
53 self._dir.direction = digitalio.Direction.OUTPUT
54 self._step.direction = digitalio.Direction.OUTPUT
55
56 self._dir.value = False
57 self._step.value = False
58
59 def step(self, forward=True):
60 """Emit one step pulse, with an optional direction flag."""
61 self._dir.value = forward
62
63 # Create a short pulse on the step pin. Note that CircuitPython is slow
64 # enough that normal execution delay is sufficient without actually
65 # sleeping.
66 self._step.value = True
67 # time.sleep(1e-6)
68 self._step.value = False
69
70 def move_sync(self, steps, speed=1000.0):
71 """Move the stepper motor the signed number of steps forward or backward at the
72 speed specified in steps per second. N.B. this function will not return
73 until the move is done, so it is not compatible with asynchronous event
74 loops.
75 """
76
77 self._dir.value = (steps >= 0)
78 time_per_step = 1.0 / speed
79 for count in range(abs(steps)):
80 self._step.value = True
81 # time.sleep(1e-6)
82 self._step.value = False
83 time.sleep(time_per_step)
84
85 def deinit(self):
86 """Manage resource release as part of object lifecycle."""
87 self._dir.deinit()
88 self._step.deinit()
89 self._dir = None
90 self._step = None
91
92 def __enter__(self):
93 return self
94
95 def __exit__(self):
96 # Automatically deinitializes the hardware when exiting a context.
97 self.deinit()
98
99#--------------------------------------------------------------------------------
100# Stepper motor demonstration.
101
102stepper = A4988()
103print("Starting stepper motor test.")
104
105speed = 200
106
107while True:
108 print(f"Speed: {speed} steps/sec.")
109 stepper.move_sync(800, speed)
110 time.sleep(1.0)
111
112 stepper.move_sync(-800, speed)
113 time.sleep(1.0)
114
115 speed *= 1.2
116 if speed > 2000:
117 speed = 100