def stepper1(self): """:py:class:`~adafruit_motor.stepper.StepperMotor` controls for one connected to stepper 1 (also labeled motor 1 and motor 2). .. image :: /_static/motor_featherwing/stepper1.jpg :alt: Stepper 1 location This example moves the stepper motor 100 steps forwards. .. code-block:: python from adafruit_featherwing import motor_featherwing wing = motor_featherwing.MotorFeatherWing() for i in range(100): wing.stepper1.onestep()""" if not self._stepper1: if self._motor1 or self._motor2: raise RuntimeError( "Cannot use stepper1 at the same time as motor1 or motor2." ) self._pca.channels[8].duty_cycle = 0xffff self._pca.channels[13].duty_cycle = 0xffff self._stepper1 = stepper.StepperMotor(self._pca.channels[10], self._pca.channels[9], self._pca.channels[11], self._pca.channels[12]) return self._stepper1
def test_double_to_single(): """Tests double to single movement""" coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3]) # We always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xFFFF if j == 0 else 0) motor.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE) assert coil[0].duty_cycle == 0xFFFF assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xFFFF motor.onestep(direction=stepper.BACKWARD, style=stepper.SINGLE) assert coil[0].duty_cycle == 0 assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xFFFF motor.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE) assert coil[0].duty_cycle == 0xFFFF assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xFFFF motor.onestep(direction=stepper.FORWARD, style=stepper.SINGLE) assert coil[0].duty_cycle == 0xFFFF assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0
def test_interleave_steps(): coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3]) # We always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xffff if j == 0 else 0) for i in range(15): # Test 15 half steps so we wrap around motor.onestep(style=stepper.INTERLEAVE) for j in range(4): expected_value = 0 # Even half steps should be DOUBLE coil active steps. if i % 2 == 0: if j == i // 2 % 4 or j == (i // 2 + 1) % 4: expected_value = 0xffff # Odd half steps should be SINGLE coil active steps elif j == (i // 2 + 1) % 4: expected_value = 0xffff assert coil[j].duty_cycle == expected_value motor.onestep(direction=stepper.BACKWARD, style=stepper.INTERLEAVE) assert coil[0].duty_cycle == 0 assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xffff
def test_microstep_steps(): coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3], microsteps=2) # We always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xffff if j == 0 else 0) motor.onestep(style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0xb504 assert coil[1].duty_cycle == 0xb504 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0 motor.onestep(style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0x0 assert coil[1].duty_cycle == 0xffff assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0 motor.onestep(style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0 assert coil[1].duty_cycle == 0xb504 assert coil[2].duty_cycle == 0xb504 assert coil[3].duty_cycle == 0 motor.onestep(direction=stepper.BACKWARD, style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0x0 assert coil[1].duty_cycle == 0xffff assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0
def stepper2(self): """:py:class:`~adafruit_motor.stepper.StepperMotor` controls for one connected to stepper 2 (also labeled motor 3 and motor 4). .. image :: ../docs/_static/motor_featherwing/stepper2.jpg :alt: Stepper 2 location This example moves the stepper motor 100 steps forwards. .. code-block:: python from adafruit_featherwing import motor_featherwing wing = motor_featherwing.MotorFeatherWing() for i in range(100): wing.stepper2.onestep() """ if not self._stepper2: from adafruit_motor import stepper if self._motor3 or self._motor4: raise RuntimeError("Cannot use stepper2 at the same time as motor3 or motor4.") self._pca.channels[7].duty_cycle = 0xffff self._pca.channels[2].duty_cycle = 0xffff self._stepper2 = stepper.StepperMotor(self._pca.channels[4], self._pca.channels[3], self._pca.channels[5], self._pca.channels[6]) return self._stepper2
def test_microstep_to_single(): coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3]) # We always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xffff if j == 0 else 0) motor.onestep(direction=stepper.BACKWARD, style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0xfec3 assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0x1918 motor.onestep(direction=stepper.BACKWARD, style=stepper.SINGLE) assert coil[0].duty_cycle == 0 assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xffff motor.onestep(direction=stepper.FORWARD, style=stepper.MICROSTEP) assert coil[0].duty_cycle == 0x1918 assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0xfec3 motor.onestep(direction=stepper.FORWARD, style=stepper.SINGLE) assert coil[0].duty_cycle == 0xffff assert coil[1].duty_cycle == 0 assert coil[2].duty_cycle == 0 assert coil[3].duty_cycle == 0
def stepper2(self): """:py:class:``~adafruit_motor.stepper.StepperMotor`` controls for one connected to stepper 2 (also labeled motor 3 and motor 4). The following image shows the location of the stepper2 terminals on the DC/Stepper FeatherWing. stepper2 is made up of the M3 and M4 terminals. The labels on the FeatherWing are found on the bottom of the board. The terminals are labeled on the top of the Shield and Pi Hat. .. image :: ../docs/_static/motor_featherwing/stepper2.jpg :alt: Stepper 2 location This example moves the stepper motor 100 steps forwards. .. code-block:: python from adafruit_motorkit import MotorKit kit = MotorKit() for i in range(100): kit.stepper2.onestep() """ if not self._stepper2: from adafruit_motor import stepper if self._motor3 or self._motor4: raise RuntimeError("Cannot use stepper2 at the same time as motor3 or motor4.") self._pca.channels[7].duty_cycle = 0xffff self._pca.channels[2].duty_cycle = 0xffff self._stepper2 = stepper.StepperMotor(self._pca.channels[4], self._pca.channels[3], self._pca.channels[5], self._pca.channels[6], microsteps=self._steppers_microsteps) return self._stepper2
def stepper2(self): if not self._stepper2: from adafruit_motor import stepper if self._motor3 or self._motor4: raise RuntimeError("Cannot use stepper2 at the same time as motor3 or motor4.") self._pca.channels[7].duty_cycle = 0xffff self._pca.channels[2].duty_cycle = 0xffff self._stepper2 = stepper.StepperMotor(self._pca.channels[4], self._pca.channels[3], self._pca.channels[5], self._pca.channels[6]) return self._stepper2
def stepper1(self): if not self._stepper1: from adafruit_motor import stepper if self._motor1 or self._motor2: raise RuntimeError("Cannot use stepper1 at the same time as motor1 or motor2.") self._pca.channels[8].duty_cycle = 0xffff self._pca.channels[13].duty_cycle = 0xffff self._stepper1 = stepper.StepperMotor(self._pca.channels[10], self._pca.channels[9], self._pca.channels[11], self._pca.channels[12]) return self._stepper1
def test_single_coil(): coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3]) # Always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xffff if j == 0 else 0) for i in range(1, 7): # Test 6 steps so we wrap around motor.onestep() for j in range(4): assert coil[j].duty_cycle == (0xffff if i % 4 == j else 0)
def test_double_coil(): coil = (Coil(), Coil(), Coil(), Coil()) # We undo the coil order so our tests make more sense. motor = stepper.StepperMotor(coil[2], coil[0], coil[1], coil[3]) # Despite double stepping we always start with a single step. for j in range(4): assert coil[j].duty_cycle == (0xffff if j == 0 else 0) for i in range(6): # Test 6 steps so we wrap around motor.onestep(style=stepper.DOUBLE) for j in range(4): assert coil[j].duty_cycle == (0xffff if i % 4 == j or (i + 1) % 4 == j else 0)
def stepper1(self): """:py:class:``~adafruit_motor.stepper.StepperMotor`` controls for one connected to stepper 1 (also labeled motor 1 and motor 2). The following image shows the location of the stepper1 terminals on the DC/Stepper FeatherWing. stepper1 is made up of the M1 and M2 terminals. The labels on the FeatherWing are found on the bottom of the board. The terminals are labeled on the top of the Shield and Pi Hat. .. image :: ../docs/_static/motor_featherwing/stepper1.jpg :alt: Stepper 1 location This example moves the stepper motor 100 steps forwards. .. code-block:: python from adafruit_motorkit import MotorKit kit = MotorKit() for i in range(100): kit.stepper1.onestep() """ if not self._stepper1: from adafruit_motor import ( # pylint: disable=import-outside-toplevel stepper, ) if self._motor1 or self._motor2: raise RuntimeError( "Cannot use stepper1 at the same time as motor1 or motor2." ) self._pca.channels[8].duty_cycle = 0xFFFF self._pca.channels[13].duty_cycle = 0xFFFF self._stepper1 = stepper.StepperMotor( self._pca.channels[10], self._pca.channels[9], self._pca.channels[11], self._pca.channels[12], microsteps=self._steppers_microsteps, ) return self._stepper1
class MotorController: A = digitalio.DigitalInOut(board.D6) B = digitalio.DigitalInOut(board.D19) C = digitalio.DigitalInOut(board.D26) D = digitalio.DigitalInOut(board.D13) A.switch_to_output() B.switch_to_output() C.switch_to_output() D.switch_to_output() motor = Stepper.StepperMotor(A, B, C, D, microsteps=None) sleep_time = 0.003 direction = Stepper.FORWARD running = False def status(self): return { 'pause': self.sleep_time, 'direction': self.direction, 'running': self.running } def run(self, sleep): if not self.running: self.running = True while self.running: self.motor.onestep(direction=self.direction, style=Stepper.SINGLE) sleep(self.sleep_time) def stop(self): self.running = False def change_step_pause(self, delta: Optional[float] = None, abs: Optional[float] = None): if delta is not None: self.sleep_time = max(0.0018, self.sleep_time + delta) elif abs is not None: self.sleep_time = max(0.0018, abs) def reverse(self): self.direction = Stepper.BACKWARD if self.direction == Stepper.FORWARD else Stepper.FORWARD
# 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(): for _ in range(STEPS): stepper_motor.onestep(direction=stepper.FORWARD) time.sleep(DELAY) stepper_motor.release() def stepper_back(): for _ in range(STEPS): stepper_motor.onestep(direction=stepper.BACKWARD) time.sleep(DELAY)
digitalio.DigitalInOut(board.D16), # A2 digitalio.DigitalInOut(board.D20), # B1 digitalio.DigitalInOut(board.D21), # B2 # motor 3 digitalio.DigitalInOut(board.D27), # A1 digitalio.DigitalInOut(board.D17), # A2 digitalio.DigitalInOut(board.D22), # B1 digitalio.DigitalInOut(board.D23), # B2 ) for coil in coils: coil.direction = digitalio.Direction.OUTPUT motor1 = stepper.StepperMotor(coils[0], coils[1], coils[2], coils[3], microsteps=None) motor2 = stepper.StepperMotor(coils[4], coils[5], coils[6], coils[7], microsteps=None) motor3 = stepper.StepperMotor(coils[8], coils[9], coils[10], coils[11], microsteps=None) degPerStep = 1.8 # number of degrees per step of the motor
import designlib as des import time from board import SCL, SDA import busio from adafruit_pca9685 import PCA9685 from adafruit_motor import stepper i2c = busio.I2C(SCL, SDA) pca = PCA9685(i2c, address=0x60) pca.frequency = 1600 powerChannel = [0] stepChannel_1 = [1] stepChannel_2 = [2] pca.channels[powerChannel] = 0xFFFF stepperMotor = stepper.StepperMotor(pca.channel[stepChannel_1], pca.channel[stepChannel_2]) def X_Stepper(msg): step = des.Conv_Steps_XY(msg) if step > 0: stepMain = step.floor() stepMicro = ((((stepMain - step) * 100) / 2)).floor() for i in range(step): stepperMotor.onestep() time.sleep(0.01) stepperMotor.onestep(microsteps=stepMicro) if step < 0: step = step * -1 stepMain = step.floor() stepMicro = ((((stepMain - step) * 100) / 2)).floor()
# Run a Stepper Motor. Tested on ItsyBitsy M4 Express + DRV8833. # https://www.adafruit.com/product/3800 # https://www.adafruit.com/product/3297 import time import board import pulseio from adafruit_motor import stepper AIn1 = pulseio.PWMOut(board.D9, frequency=1600) AIn2 = pulseio.PWMOut(board.D10, frequency=1600) BIn1 = pulseio.PWMOut(board.D11, frequency=1600) BIn2 = pulseio.PWMOut(board.D12, frequency=1600) stepper_motor = stepper.StepperMotor(AIn1, AIn2, BIn1, BIn2) for i in range(1000): stepper_motor.onestep() time.sleep(0.01) for i in range(1000): stepper_motor.onestep(direction=stepper.BACKWARD) time.sleep(0.01)
buttona.pull = Pull.DOWN buttonb = DigitalInOut(board.BUTTON_B) buttonb.direction = Direction.INPUT buttonb.pull = Pull.DOWN BOTTOM_SENSOR = 2 TOP_SENSOR = 3 seesaw.pin_mode(BOTTOM_SENSOR, seesaw.INPUT_PULLUP) seesaw.pin_mode(TOP_SENSOR, seesaw.INPUT_PULLUP) # Create one stepper motor using the 4 'drive' PWM pins 13, 43, 12 and 42 pwms = [PWMOut(seesaw, 13), PWMOut(seesaw, 43), PWMOut(seesaw, 12), PWMOut(seesaw, 42)] for p in pwms: p.frequency = 2000 stepper_motor = stepper.StepperMotor(pwms[0], pwms[1], pwms[2], pwms[3]) pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=1) pixels.fill((0,0,0)) def rainbow(): pixels.fill((20,0,0)) time.sleep(0.05) pixels.fill((20,20,0)) time.sleep(0.05) pixels.fill((0,20,0)) time.sleep(0.05) pixels.fill((0,20,20)) time.sleep(0.05) pixels.fill((0,0,20))
from adafruit_pca9685 import PCA9685 from adafruit_motor import stepper i2c = busio.I2C(SCL, SDA) # Create a simple PCA9685 class instance for the Motor FeatherWing's default address. pca = PCA9685(i2c, address=0x60) pca.frequency = 1600 # Motor 1 is channels 9 and 10 with 8 held high. # Motor 2 is channels 11 and 12 with 13 held high. # Motor 3 is channels 3 and 4 with 2 held high. # Motor 4 is channels 5 and 6 with 7 held high. pca.channels[7].duty_cycle = 0xFFFF pca.channels[2].duty_cycle = 0xFFFF stepper_motor = stepper.StepperMotor( pca.channels[4], pca.channels[3], pca.channels[5], pca.channels[6] ) for i in range(100): stepper_motor.onestep() time.sleep(0.01) for i in range(100): stepper_motor.onestep(direction=stepper.BACKWARD) time.sleep(0.01) pca.deinit()