Let's look at the most basic example from the Servo guide:
import time import board import pulseio from adafruit_motor import servo # create a PWMOut object on Pin A2. pwm = pwmio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50) # Create a servo object, my_servo. my_servo = servo.Servo(pwm) while True: for angle in range(0, 180, 5): # 0 - 180 degrees, 5 degrees at a time. my_servo.angle = angle time.sleep(0.05) for angle in range(180, 0, -5): # 180 - 0 degrees, 5 degrees at a time. my_servo.angle = angle time.sleep(0.05)
This works fine for us if we only have one servo, and we don't have anything else that we want to happen at the same time. But once we add in another thing, we'd have the same trouble as before — time.sleep()
delaying our other actions unintentionally.
In the next version we adopt the "is it time yet" approach in order to avoid the use of time.sleep()
:
# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries # # SPDX-License-Identifier: MIT """ This example script shows how to sweep servo(s) without using time.sleep(). """ import time import board import pwmio from adafruit_motor import servo SERVO_LIST = [ { "MAX_ANGLE": 180, "MIN_ANGLE": 0, "PREV_TIME": -1, "PIN": board.A1, "DELAY_BETWEEN": 0.05, "SERVO": None, "MOVE_BY": 5 } ] for cur_servo in SERVO_LIST: pwm = pwmio.PWMOut(cur_servo["PIN"], duty_cycle=2 ** 15, frequency=50) # Create a servo object. cur_servo["SERVO"] = servo.Servo(pwm) while True: # Store the current time to refer to later. now = time.monotonic() for servo in SERVO_LIST: if now >= servo["PREV_TIME"] + servo["DELAY_BETWEEN"]: try: servo["SERVO"].angle += servo["MOVE_BY"] except ValueError as e: if servo["MOVE_BY"] > 0: servo["SERVO"].angle = servo["MAX_ANGLE"] else: servo["SERVO"].angle = servo["MIN_ANGLE"] if servo["SERVO"].angle >= servo["MAX_ANGLE"] or \ servo["SERVO"].angle <= servo["MIN_ANGLE"]: servo["MOVE_BY"] = -servo["MOVE_BY"] servo["PREV_TIME"] = now
This version also moves the configuration for the servo sweeping into a list of dictionaries so that additional servos with different sweeping effects can be added easily.
To add an additional servo, you would make a copy of the dictionary that is in SERVO_LIST
and change any of the fields that we want to the new desired parameters:
{ "MAX_ANGLE": 90, "MIN_ANGLE": 45, "PREV_TIME": -1, "PIN": board.A2, "DELAY_BETWEEN": 0.03, "SERVO": None, "MOVE_BY": 5 }
SERVO
and PREV_TIME
should be left as their default values. The rest of the code will fill them in when needed. MAX_ANGLE
and MIN_ANGLE
are the degrees at which the servo will turn around to move the opposite direction.
PIN
is the IO pin that the servo is connected to.
DELAY_BETWEEN
is how long it will wait between each servo step. This is in seconds, and you likely want to keep it pretty small in most situations.
MOVE_BY
is how many steps the servo will take each time it moves.
Here is an example of a list with two servos in it. You could continue adding more if you wanted.
SERVO_LIST = [ { "MAX_ANGLE": 180, "MIN_ANGLE": 0, "PREV_TIME": -1, "PIN": board.A1, "DELAY_BETWEEN": 0.05, "SERVO": None, "MOVE_BY": 5 }, { "MAX_ANGLE": 90, "MIN_ANGLE": 45, "PREV_TIME": -1, "PIN": board.A2, "DELAY_BETWEEN": 0.03, "SERVO": None, "MOVE_BY": 5 } ]
Page last edited January 22, 2025
Text editor powered by tinymce.