initial library and examples
This commit is contained in:
parent
18d73e6f0c
commit
9d2c40df66
6 changed files with 562 additions and 13 deletions
15
README.rst
15
README.rst
|
|
@ -92,7 +92,20 @@ Usage Example
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
import adafruit_stspin
|
||||
import time
|
||||
import adafruit_stspin220
|
||||
import board
|
||||
|
||||
STEPS_PER_REVOLUTION = 200
|
||||
|
||||
STEP_PIN = board.D5
|
||||
DIR_PIN = board.D6
|
||||
motor = adafruit_stspin220.STSPIN220(STEP_PIN, DIR_PIN, STEPS_PER_REVOLUTION)
|
||||
motor.speed = 60
|
||||
|
||||
total_microsteps = STEPS_PER_REVOLUTION * motor.microsteps_per_step
|
||||
|
||||
motor.step(total_microsteps)
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
|
@ -16,22 +15,403 @@ Implementation Notes
|
|||
|
||||
**Hardware:**
|
||||
|
||||
.. todo:: Add links to any specific hardware product page(s), or category page(s).
|
||||
Use unordered list & hyperlink rST inline format: "* `Link Text <url>`_"
|
||||
* `Adafruit STSPIN220 Stepper Motor Driver Breakout Board <https://www.adafruit.com/product/6353>`_
|
||||
|
||||
**Software and Dependencies:**
|
||||
|
||||
* Adafruit CircuitPython firmware for the supported boards:
|
||||
https://circuitpython.org/downloads
|
||||
|
||||
.. todo:: Uncomment or remove the Bus Device and/or the Register library dependencies
|
||||
based on the library's use of either.
|
||||
|
||||
# * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
|
||||
# * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
|
||||
"""
|
||||
|
||||
# imports
|
||||
import time
|
||||
|
||||
from digitalio import DigitalInOut, Direction, Pull
|
||||
from micropython import const
|
||||
|
||||
try:
|
||||
from typing import Literal, Optional
|
||||
except ImportError:
|
||||
from typing_extensions import Literal
|
||||
|
||||
__version__ = "0.0.0+auto.0"
|
||||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STSPIN.git"
|
||||
|
||||
__version__ = "0.0.0+auto.0"
|
||||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STSPIN220.git"
|
||||
|
||||
|
||||
# Timing characteristics
|
||||
TOFF_MIN_US = const(9) # Minimum OFF time with ROFF=10kΩ (μs)
|
||||
TOFF_MAX_US = const(125) # Maximum OFF time with ROFF=160kΩ (μs)
|
||||
STCK_MIN_PULSE_NS = const(100) # Minimum STCK pulse width (ns)
|
||||
DIR_SETUP_TIME_NS = const(100) # DIR input setup time (ns)
|
||||
DIR_HOLD_TIME_NS = const(100) # DIR input hold time (ns)
|
||||
STCK_MAX_FREQ_MHZ = const(1) # Maximum STCK frequency (MHz)
|
||||
|
||||
|
||||
class Modes:
|
||||
"""Valid microstepping modes for STSPIN220.
|
||||
|
||||
Each mode value encodes the state of MODE1-MODE4 pins:
|
||||
- Bits 0-1: MODE1, MODE2 (physical pins if connected)
|
||||
- Bits 2-3: MODE3, MODE4 (multiplexed with STEP/DIR during reset)
|
||||
"""
|
||||
|
||||
STEP_FULL = const(0b0000) # Full step mode
|
||||
STEP_1_2 = const(0b0101) # 1/2 step mode
|
||||
STEP_1_4 = const(0b1010) # 1/4 step mode
|
||||
STEP_1_8 = const(0b0111) # 1/8 step mode
|
||||
STEP_1_16 = const(0b1111) # 1/16 step mode (default)
|
||||
STEP_1_32 = const(0b0010) # 1/32 step mode
|
||||
STEP_1_64 = const(0b1011) # 1/64 step mode
|
||||
STEP_1_128 = const(0b0001) # 1/128 step mode
|
||||
STEP_1_256 = const(0b0011) # 1/256 step mode
|
||||
|
||||
_MICROSTEPS = {
|
||||
STEP_FULL: 1,
|
||||
STEP_1_2: 2,
|
||||
STEP_1_4: 4,
|
||||
STEP_1_8: 8,
|
||||
STEP_1_16: 16,
|
||||
STEP_1_32: 32,
|
||||
STEP_1_64: 64,
|
||||
STEP_1_128: 128,
|
||||
STEP_1_256: 256,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def microsteps(cls, mode: int) -> int:
|
||||
"""Get number of microsteps for a given mode.
|
||||
|
||||
:param int mode: Step mode constant
|
||||
:return: Number of microsteps per full step
|
||||
:rtype: int
|
||||
"""
|
||||
return cls._MICROSTEPS.get(mode, 16) # Default to 16
|
||||
|
||||
@classmethod
|
||||
def is_valid(cls, mode: int) -> bool:
|
||||
"""Check if a mode value is valid.
|
||||
|
||||
:param int mode: Mode value to check
|
||||
:return: True if valid mode
|
||||
:rtype: bool
|
||||
"""
|
||||
return mode in cls._MICROSTEPS
|
||||
|
||||
|
||||
class STSPIN220:
|
||||
"""Driver for the STSPIN220 Low Voltage Stepper Motor Driver.
|
||||
|
||||
:param ~microcontroller.Pin step_pin: The pin connected to STEP (step clock) input
|
||||
:param ~microcontroller.Pin dir_pin: The pin connected to DIR (direction) input
|
||||
:param int steps_per_revolution: Number of steps per full motor revolution
|
||||
:param ~microcontroller.Pin mode1_pin: The pin connected to MODE1 input (optional)
|
||||
:param ~microcontroller.Pin mode2_pin: The pin connected to MODE2 input (optional)
|
||||
:param ~microcontroller.Pin en_fault_pin: The pin connected to EN/FAULT pin (optional)
|
||||
:param ~microcontroller.Pin stby_reset_pin: The pin connected to STBY/RESET pin (optional)
|
||||
"""
|
||||
|
||||
def __init__( # noqa: PLR0913, PLR0917
|
||||
self,
|
||||
step_pin,
|
||||
dir_pin,
|
||||
steps_per_revolution: int = 200,
|
||||
mode1_pin=None,
|
||||
mode2_pin=None,
|
||||
en_fault_pin=None,
|
||||
stby_reset_pin=None,
|
||||
) -> None:
|
||||
# Initialize pins
|
||||
self._step_pin = DigitalInOut(step_pin)
|
||||
self._step_pin.direction = Direction.OUTPUT
|
||||
self._step_pin.value = True
|
||||
|
||||
self._dir_pin = DigitalInOut(dir_pin)
|
||||
self._dir_pin.direction = Direction.OUTPUT
|
||||
self._dir_pin.value = True
|
||||
|
||||
# Optional pins
|
||||
self._mode1_pin = None
|
||||
self._mode2_pin = None
|
||||
if mode1_pin is not None:
|
||||
self._mode1_pin = DigitalInOut(mode1_pin)
|
||||
self._mode1_pin.direction = Direction.OUTPUT
|
||||
self._mode1_pin.value = True
|
||||
|
||||
if mode2_pin is not None:
|
||||
self._mode2_pin = DigitalInOut(mode2_pin)
|
||||
self._mode2_pin.direction = Direction.OUTPUT
|
||||
self._mode2_pin.value = True
|
||||
|
||||
self._en_fault_pin = None
|
||||
if en_fault_pin is not None:
|
||||
self._en_fault_pin = DigitalInOut(en_fault_pin)
|
||||
self._en_fault_pin.direction = Direction.INPUT
|
||||
self._en_fault_pin.pull = Pull.UP
|
||||
|
||||
self._stby_reset_pin = None
|
||||
if stby_reset_pin is not None:
|
||||
self._stby_reset_pin = DigitalInOut(stby_reset_pin)
|
||||
self._stby_reset_pin.direction = Direction.OUTPUT
|
||||
self._stby_reset_pin.value = True
|
||||
|
||||
# Motor parameters
|
||||
self._steps_per_revolution = steps_per_revolution
|
||||
self._step_delay = 0.001 # Default 1ms between steps
|
||||
self._step_number = 0
|
||||
self._last_step_time = 0
|
||||
self._step_mode = Modes.STEP_1_16 # Default to 1/16 microstepping
|
||||
self._enabled = True
|
||||
|
||||
# Set initial step mode if mode pins are available
|
||||
if self._mode1_pin and self._mode2_pin:
|
||||
mode_bits = self._step_mode
|
||||
self._mode1_pin.value = bool(mode_bits & 0x01)
|
||||
self._mode2_pin.value = bool(mode_bits & 0x02)
|
||||
|
||||
@property
|
||||
def speed(self) -> float:
|
||||
"""Motor speed in revolutions per minute (RPM).
|
||||
|
||||
:return: Current speed in RPM
|
||||
:rtype: float
|
||||
"""
|
||||
if self._step_delay >= 1.0:
|
||||
return 0.0
|
||||
|
||||
microsteps = self.microsteps_per_step
|
||||
steps_per_second = 1.0 / self._step_delay
|
||||
steps_per_minute = steps_per_second * 60.0
|
||||
rpm = steps_per_minute / (self._steps_per_revolution * microsteps)
|
||||
return rpm
|
||||
|
||||
@speed.setter
|
||||
def speed(self, rpm: float) -> None:
|
||||
"""Set motor speed in revolutions per minute (RPM).
|
||||
|
||||
:param float rpm: Desired speed in RPM (must be positive)
|
||||
"""
|
||||
if rpm <= 0:
|
||||
self._step_delay = 1.0
|
||||
else:
|
||||
# Account for microstepping
|
||||
microsteps = self.microsteps_per_step
|
||||
steps_per_minute = rpm * self._steps_per_revolution * microsteps
|
||||
steps_per_second = steps_per_minute / 60.0
|
||||
self._step_delay = 1.0 / steps_per_second
|
||||
|
||||
# Enforce minimum step delay (1 MHz max frequency = 1 μs minimum)
|
||||
if self._step_delay < 0.000001:
|
||||
self._step_delay = 0.000001
|
||||
|
||||
@property
|
||||
def step_mode(self) -> int:
|
||||
"""Current microstepping mode.
|
||||
|
||||
:return: Current step mode constant from Modes class
|
||||
:rtype: int
|
||||
"""
|
||||
return self._step_mode
|
||||
|
||||
@step_mode.setter
|
||||
def step_mode(self, mode: int) -> None:
|
||||
"""Set the microstepping mode.
|
||||
|
||||
:param int mode: Step mode constant from Modes class (e.g., Modes.STEP_1_16)
|
||||
:raises ValueError: If mode is invalid or cannot be set with available pins
|
||||
"""
|
||||
if not Modes.is_valid(mode):
|
||||
raise ValueError(f"Invalid step mode: {mode}")
|
||||
|
||||
if self._stby_reset_pin is None:
|
||||
raise ValueError("Cannot set step mode without STBY/RESET pin")
|
||||
|
||||
mode_bits = mode
|
||||
|
||||
# Check if we can set this mode with available pins
|
||||
if (self._mode1_pin is None) or (self._mode2_pin is None):
|
||||
# If mode1/mode2 pins not available, only allow modes where those bits are high
|
||||
if (mode_bits & 0x01) == 0 or (mode_bits & 0x02) == 0:
|
||||
raise ValueError(
|
||||
"Cannot set mode requiring low MODE1/MODE2 without those pins connected"
|
||||
)
|
||||
|
||||
# Put device into standby/reset
|
||||
self._stby_reset_pin.value = False
|
||||
time.sleep(0.001) # 1 ms
|
||||
|
||||
# Set all available mode pins (MODE1, MODE2, STEP/MODE3, DIR/MODE4)
|
||||
if self._mode1_pin is not None:
|
||||
self._mode1_pin.value = bool(mode_bits & 0x01)
|
||||
if self._mode2_pin is not None:
|
||||
self._mode2_pin.value = bool(mode_bits & 0x02)
|
||||
self._step_pin.value = bool(mode_bits & 0x04)
|
||||
self._dir_pin.value = bool(mode_bits & 0x08)
|
||||
|
||||
# Come out of standby to latch the mode
|
||||
self._stby_reset_pin.value = True
|
||||
|
||||
self._step_mode = mode
|
||||
|
||||
@property
|
||||
def microsteps_per_step(self) -> int:
|
||||
"""Number of microsteps per full step for current mode.
|
||||
|
||||
:return: Microsteps per full step (1, 2, 4, 8, 16, 32, 64, 128, or 256)
|
||||
:rtype: int
|
||||
"""
|
||||
return Modes.microsteps(self._step_mode)
|
||||
|
||||
@property
|
||||
def fault(self) -> bool:
|
||||
"""Check if a fault condition exists.
|
||||
|
||||
:return: True if fault detected, False if normal operation
|
||||
:rtype: bool
|
||||
"""
|
||||
if self._en_fault_pin is None:
|
||||
return False
|
||||
|
||||
return not self._en_fault_pin.value
|
||||
|
||||
@property
|
||||
def position(self) -> int:
|
||||
"""Current motor position in steps (0 to steps_per_revolution-1).
|
||||
|
||||
:return: Current position in steps
|
||||
:rtype: int
|
||||
"""
|
||||
return self._step_number
|
||||
|
||||
def step(self, steps: int) -> None:
|
||||
"""Move the motor a specified number of steps.
|
||||
|
||||
:param int steps: Number of steps to move (positive = forward, negative = reverse)
|
||||
"""
|
||||
steps_left = abs(steps)
|
||||
self._dir_pin.value = steps > 0
|
||||
time.sleep(0.000001) # 1 μs setup time
|
||||
|
||||
while steps_left > 0:
|
||||
now = time.monotonic()
|
||||
|
||||
if (now - self._last_step_time) >= self._step_delay:
|
||||
self._step()
|
||||
|
||||
if steps > 0:
|
||||
self._step_number += 1
|
||||
if self._step_number >= self._steps_per_revolution:
|
||||
self._step_number = 0
|
||||
elif self._step_number == 0:
|
||||
self._step_number = self._steps_per_revolution - 1
|
||||
else:
|
||||
self._step_number -= 1
|
||||
|
||||
steps_left -= 1
|
||||
self._last_step_time = now
|
||||
|
||||
def _step(self) -> None:
|
||||
"""Perform a single step pulse."""
|
||||
self._step_pin.value = False
|
||||
time.sleep(0.000001) # 1 μs pulse width
|
||||
self._step_pin.value = True
|
||||
|
||||
def step_blocking(self, steps: int, delay_seconds: float = 0.001) -> None:
|
||||
"""Move the motor with blocking delay between steps.
|
||||
|
||||
:param int steps: Number of steps to move (positive = forward, negative = reverse)
|
||||
:param float delay_seconds: Delay between steps in seconds
|
||||
"""
|
||||
steps_left = abs(steps)
|
||||
self._dir_pin.value = steps > 0
|
||||
time.sleep(0.000001) # 1 μs setup time
|
||||
|
||||
for _ in range(steps_left):
|
||||
self._step()
|
||||
time.sleep(delay_seconds)
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Motor power stage enable state.
|
||||
|
||||
:return: True if enabled, False if disabled
|
||||
:rtype: bool
|
||||
"""
|
||||
if self._en_fault_pin is None:
|
||||
return True # If no enable pin, assume enabled
|
||||
return self._enabled
|
||||
|
||||
@enabled.setter
|
||||
def enabled(self, state: bool) -> None:
|
||||
"""Enable or disable the motor power stage.
|
||||
|
||||
:param bool state: True to enable, False to disable
|
||||
"""
|
||||
if self._en_fault_pin is None:
|
||||
return
|
||||
|
||||
# Ensure pin is configured as output
|
||||
if self._en_fault_pin.direction != Direction.OUTPUT:
|
||||
self._en_fault_pin.direction = Direction.OUTPUT
|
||||
|
||||
# Set pin high to enable, low to disable
|
||||
self._en_fault_pin.value = state
|
||||
self._enabled = state
|
||||
|
||||
@property
|
||||
def standby(self) -> bool:
|
||||
"""Device standby state.
|
||||
|
||||
:return: True if in standby mode, False if active
|
||||
:rtype: bool
|
||||
"""
|
||||
if self._stby_reset_pin is None:
|
||||
return False # If no standby pin, assume active
|
||||
return not self._stby_reset_pin.value # Low = standby, High = active
|
||||
|
||||
@standby.setter
|
||||
def standby(self, state: bool) -> None:
|
||||
"""Put the device into standby mode or wake it up.
|
||||
|
||||
:param bool state: True to enter standby (ultra-low power), False to wake up
|
||||
"""
|
||||
if self._stby_reset_pin is None:
|
||||
return
|
||||
|
||||
if state:
|
||||
# Going into standby/reset - pull pin low
|
||||
self._stby_reset_pin.value = False
|
||||
else:
|
||||
# Coming out of standby/reset - pull pin high
|
||||
self._stby_reset_pin.value = True
|
||||
# After waking up, we need to restore the step mode
|
||||
# by reconfiguring the MODE pins
|
||||
if hasattr(self, "_step_mode"):
|
||||
# Re-apply the current step mode
|
||||
self.step_mode = self._step_mode
|
||||
|
||||
def clear_fault(self) -> None:
|
||||
"""Clear fault condition by toggling enable pin."""
|
||||
if self._en_fault_pin is None:
|
||||
return
|
||||
|
||||
# Ensure we're in output mode to control the pin
|
||||
self._en_fault_pin.direction = Direction.OUTPUT
|
||||
|
||||
# Toggle the pin low then high to clear the fault
|
||||
self._en_fault_pin.value = False
|
||||
time.sleep(0.001) # 1 ms
|
||||
self._en_fault_pin.value = True
|
||||
|
||||
self._enabled = True
|
||||
|
||||
def reset(self) -> None:
|
||||
"""Reset the device by toggling the STBY/RESET pin."""
|
||||
if self._stby_reset_pin is None:
|
||||
return
|
||||
|
||||
self.standby(True)
|
||||
time.sleep(0.001) # 1 ms
|
||||
self.standby(False)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ extensions = [
|
|||
# Uncomment the below if you use native CircuitPython modules such as
|
||||
# digitalio, micropython and busio. List the modules you use. Without it, the
|
||||
# autodoc module docs will fail to generate with a warning.
|
||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
||||
autodoc_mock_imports = ["digitalio"]
|
||||
|
||||
autodoc_preserve_defaults = True
|
||||
|
||||
|
|
|
|||
|
|
@ -6,3 +6,12 @@ Ensure your device works with this simple test.
|
|||
.. literalinclude:: ../examples/stspin_simpletest.py
|
||||
:caption: examples/stspin_simpletest.py
|
||||
:linenos:
|
||||
|
||||
Microstep mode test
|
||||
--------------------
|
||||
|
||||
Cycle through setting the different microstep modes
|
||||
|
||||
.. literalinclude:: ../examples/stspin_microsteps.py
|
||||
:caption: examples/stspin_microsteps.py
|
||||
:linenos:
|
||||
|
|
|
|||
113
examples/stspin_microsteps.py
Normal file
113
examples/stspin_microsteps.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
Microstepping mode test for the Adafruit STSPIN220 stepper motor driver.
|
||||
"""
|
||||
|
||||
import time
|
||||
import board
|
||||
import adafruit_stspin220
|
||||
|
||||
# Define the number of steps per revolution for your stepper motor
|
||||
# Most steppers are 200 steps per revolution (1.8 degrees per step)
|
||||
STEPS_PER_REVOLUTION = 200
|
||||
|
||||
STEP_PIN = board.D5 # Step clock pin
|
||||
DIR_PIN = board.D6 # Direction pin
|
||||
MODE1_PIN = board.D9 # Mode 1 pin (REQUIRED for mode switching)
|
||||
MODE2_PIN = board.D10 # Mode 2 pin (REQUIRED for mode switching)
|
||||
EN_FAULT_PIN = board.D11 # Enable/Fault pin (optional)
|
||||
STBY_RESET_PIN = board.D12 # Standby/Reset pin (REQUIRED for mode switching)
|
||||
|
||||
print("Initializing STSPIN220...")
|
||||
motor = adafruit_stspin220.STSPIN220(
|
||||
STEP_PIN,
|
||||
DIR_PIN,
|
||||
STEPS_PER_REVOLUTION,
|
||||
mode1_pin=MODE1_PIN,
|
||||
mode2_pin=MODE2_PIN,
|
||||
en_fault_pin=EN_FAULT_PIN,
|
||||
stby_reset_pin=STBY_RESET_PIN
|
||||
)
|
||||
|
||||
print("Adafruit STSPIN220 Microstepping Mode Test")
|
||||
print("=" * 50)
|
||||
|
||||
# Define all available modes with their names for display
|
||||
MODES = [
|
||||
(adafruit_stspin220.Modes.STEP_FULL, "Full Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_2, "1/2 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_4, "1/4 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_8, "1/8 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_16, "1/16 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_32, "1/32 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_64, "1/64 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_128, "1/128 Step"),
|
||||
(adafruit_stspin220.Modes.STEP_1_256, "1/256 Step"),
|
||||
]
|
||||
|
||||
BASE_RPM = 30 # Base speed for full step mode
|
||||
|
||||
print(f"Base speed: {BASE_RPM} RPM (for full step mode)")
|
||||
print("Speed will be adjusted for each mode to maintain similar rotation time")
|
||||
print("=" * 50)
|
||||
time.sleep(2.0)
|
||||
|
||||
while True:
|
||||
for mode, mode_name in MODES:
|
||||
print(f"\nTesting {mode_name} mode...")
|
||||
|
||||
try:
|
||||
# Set the microstepping mode
|
||||
motor.step_mode = mode
|
||||
|
||||
# Get the number of microsteps for this mode
|
||||
microsteps = motor.microsteps_per_step
|
||||
|
||||
# Adjust speed to maintain similar rotation time across all modes
|
||||
# More microsteps = need higher RPM to maintain same angular velocity
|
||||
adjusted_rpm = BASE_RPM * (microsteps / 1.0) # Normalized to full step
|
||||
motor.speed = adjusted_rpm
|
||||
|
||||
# Calculate total steps needed for one full revolution
|
||||
total_steps = STEPS_PER_REVOLUTION * microsteps
|
||||
|
||||
print(f" Microsteps per full step: {microsteps}")
|
||||
print(f" Adjusted speed: {adjusted_rpm:.1f} RPM")
|
||||
print(f" Steps for full revolution: {total_steps}")
|
||||
|
||||
# Check for any faults before moving
|
||||
if motor.fault:
|
||||
print(" WARNING: Fault detected! Clearing...")
|
||||
motor.clear_fault()
|
||||
time.sleep(0.1)
|
||||
|
||||
# Perform one full revolution forward
|
||||
print(f" Rotating forward 360°...")
|
||||
start_time = time.monotonic()
|
||||
motor.step(total_steps)
|
||||
rotation_time = time.monotonic() - start_time
|
||||
print(f" Rotation completed in {rotation_time:.2f} seconds")
|
||||
|
||||
# Brief pause to see the position
|
||||
time.sleep(0.5)
|
||||
|
||||
# Return to starting position
|
||||
print(f" Returning to start position...")
|
||||
motor.step(-total_steps)
|
||||
|
||||
print(f" {mode_name} test complete!")
|
||||
|
||||
except ValueError as e:
|
||||
print(f" ERROR: Could not set {mode_name} mode - {e}")
|
||||
print(" Make sure MODE1, MODE2, and STBY/RESET pins are connected!")
|
||||
|
||||
# Pause between modes
|
||||
time.sleep(1.0)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("All modes tested! Starting next cycle in 3 seconds...")
|
||||
print("=" * 50)
|
||||
time.sleep(3.0)
|
||||
|
|
@ -1,4 +1,38 @@
|
|||
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
Basic example for the Adafruit STSPIN220 stepper motor driver library.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import adafruit_stspin220
|
||||
import board
|
||||
|
||||
STEPS_PER_REVOLUTION = 200
|
||||
|
||||
STEP_PIN = board.D5
|
||||
DIR_PIN = board.D6
|
||||
|
||||
# Create stepper object with full pin configuration
|
||||
# Defaults to 1/16 microsteps
|
||||
motor = adafruit_stspin220.STSPIN220(STEP_PIN, DIR_PIN, STEPS_PER_REVOLUTION)
|
||||
|
||||
# Set the speed to 60 RPM
|
||||
motor.speed = 60
|
||||
|
||||
print(f"Microstepping mode set to 1/{motor.microsteps_per_step} at {motor.speed} RPM")
|
||||
|
||||
while True:
|
||||
# Calculate total microsteps for one full revolution
|
||||
total_microsteps = STEPS_PER_REVOLUTION * motor.microsteps_per_step
|
||||
|
||||
print(f"Stepping forward one revolution ({total_microsteps} microsteps)...")
|
||||
motor.step(total_microsteps)
|
||||
time.sleep(1.0)
|
||||
|
||||
print(f"Stepping backward one revolution ({total_microsteps} microsteps)...")
|
||||
motor.step(-total_microsteps)
|
||||
time.sleep(1.0)
|
||||
|
|
|
|||
Loading…
Reference in a new issue