Position Control with Motor Library
The best way to control servos is with a handy Adafruit CircuitPython Motor module which simplifies setting the duty cycle to control servos (and even allows controlling servos from different PWM hardware like the PCA9685 board).
CircuitPython Library Install
To follow this approach you'll need to install the Adafruit CircuitPython Motor library on your CircuitPython board.
First make sure you are running the latest version of Adafruit CircuitPython for your board.
Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle. Our introduction guide has a great page on how to install the library bundle for both express and non-express boards.
Remember for non-Express boards, you'll need to manually install the necessary libraries from the bundle:
- adafruit_motor
You can also download the adafruit_motor folder from its releases page on Github.
Before continuing make sure your board's lib folder has the adafruit_motor folder copied over.
Now connect to the board's serial REPL so you are at the CircuitPython >>> prompt.
Python Library Install
On Linux, you'll need to install the Adafruit_Blinka
library that provides the CircuitPython support in Python. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!
Once that's done, from your command line run the following command:
-
pip3 install adafruit-circuitpython-motor
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
Controlling a Servo
Then import the board
and pwmio
modules as before. We'll create a PWM output just like as shown in the first section--the motor library will take this PWM output and add an extra level of simple control on top of it:
import board import pwmio pwm = pwmio.PWMOut(board.D5, frequency=50)
Now let's import the servo submodule from the adafruit_motor
module and create an instance of the Servo
class from it:
from adafruit_motor import servo servo = servo.Servo(pwm, min_pulse=750, max_pulse=2250)
Notice the servo class needs to be told what PWM output the servo is connected to for your board. If you're following the wiring and this guide it will be a PWM output on board pin 5 (be sure to create this with a 50 hz frequency as shown!).
There are a few optional keyword parameters that you might specify in the initializer too. These aren't shown and are useful for using very specialized or custom servos with different ranges or pulse width values--for simple servos you don't typically need to set these values:
- actuation_range - The range in degrees of the servo movement. The default is 180 degrees.
- min_pulse - The minimum position pulse length in microseconds (default 1000 us).
- max_pulse - The maximum position pulse length in microseconds (default 2000 us).
Here we've change the minimum pulse from the default 1000 microseconds to 750, and the default maximum pulse from 2000 microseconds to 2250 to ensure we get the full sweep as some servos differ. Some experimentation may be required!
Controlling the servo is simple once you have the class created, just set the angle
property to a value from 0 to 180 degrees!
servo.angle = 0 servo.angle = 90 servo.angle = 180
Notice each time you set angle the servo springs to life and moves!
If you don't see the servo moving be sure you have it wired and powered exactly as shown. Also make sure you've created the PWM output exactly as shown above too (note the 50 hz frequency!).
There's another type of servo class in the module that you might find useful too, the ContinuousServo
class. This is for controlling continuous rotation servos that move completely around like a small motor instead of point at specific angles. For these servos you control their speed (or throttle). Create an instance just like with the Servo
class above:
continuous = adafruit_motor.servo.ContinuousServo(pwm, min_pulse=750, max_pulse=2250)
With these servos you set the throttle
property to a value from -1 to 1 (or anything in between, including fractional values). Where -1 is fully speed 'backwards' and 1 is full speed 'forwards'. A value of 0 should stop the motor (but your servo might need to be trimmed a bit and have a small value set that stops its movement instead of zero, experiment with values yourself to see).
continuous.throttle = -1 # Full backwards continuous.throttle = 0 # Stop continuous.throttle = 1 # Full forwards continuous.throttle = 0.5 # Half speed forwards
Standard Servo
Here's a complete standard servo sweep example written for the adafruit_motor
library. Remember save this as code.py on your board to have it run:
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries # # SPDX-License-Identifier: MIT """CircuitPython Essentials Servo standard servo example""" import time import board import pwmio 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)
# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries # # SPDX-License-Identifier: MIT """CircuitPython Essentials Servo continuous rotation servo example""" import time import board import pwmio from adafruit_motor import servo # create a PWMOut object on Pin A2. pwm = pwmio.PWMOut(board.A2, frequency=50) # Create a servo object, my_servo. my_servo = servo.ContinuousServo(pwm) while True: print("forward") my_servo.throttle = 1.0 time.sleep(2.0) print("stop") my_servo.throttle = 0.0 time.sleep(2.0) print("reverse") my_servo.throttle = -1.0 time.sleep(2.0) print("stop") my_servo.throttle = 0.0 time.sleep(4.0)
Check out all of the examples in the Adafruit CircuitPython Motor module too!
Page last edited January 22, 2025
Text editor powered by tinymce.