# load standard Python modules
import time
# load the MicroPython modules
from machine import Pin
#--------------------------------------------------------------------------------
class A4988:
def __init__(self, DIR=16, STEP=17):
"""This class represents an A4988 stepper motor driver.
It uses two output pins for direction and step control signals."""
self._dir = Pin(DIR, Pin.OUT)
self._step = Pin(STEP, Pin.OUT)
self._dir.value(0)
self._step.value(0)
def step(self, forward=1):
"""Emit one step pulse, with an optional direction flag."""
self._dir.value(forward)
# Create a short pulse on the step pin. Note that CircuitPython is slow
# enough that normal execution delay is sufficient without actually
# sleeping.
self._step.value(1)
# time.sleep(1e-6)
self._step.value(0)
def move_sync(self, steps, speed=1000.0):
"""Move the stepper motor the signed number of steps forward or backward at the
speed specified in steps per second. N.B. this function will not return
until the move is done, so it is not compatible with asynchronous event loops.
"""
self._dir.value(steps >= 0)
time_per_step = 1.0 / speed
for count in range(abs(steps)):
self._step.value(1)
# time.sleep(1e-6)
self._step.value(0)
time.sleep(time_per_step)
def deinit(self):
"""Manage resource release as part of object lifecycle."""
self._dir.deinit()
self._step.deinit()
self._dir = None
self._step = None
def __enter__(self):
return self
def __exit__(self):
# Automatically deinitializes the hardware when exiting a context.
self.deinit()
#--------------------------------------------------------------------------------
# Stepper motor demonstration.
stepper = A4988()
print("Starting stepper motor test.")
speed = 200
while True:
print(f"Speed: {speed} steps/sec.")
stepper.move_sync(800, speed)
time.sleep(1.0)
stepper.move_sync(-800, speed)
time.sleep(1.0)
speed *= 1.2
if speed > 2000:
speed = 100