CircuitPython helper library for the PWM/Servo FeatherWing, Shield and Pi HAT and Bonnet kits.
npx @tessl/cli install tessl/pypi-adafruit-circuitpython-servokit@1.3.0A CircuitPython helper library that provides a unified interface for controlling servo motors through Adafruit's PWM/Servo hardware kits. It abstracts the complexity of the underlying PCA9685 PWM controller, offering simple APIs for both standard positioning servos and continuous rotation servos with support for configurable I2C addressing, reference clock speeds, and PWM frequencies.
pip install adafruit-circuitpython-servokitPrimary import for the ServoKit class:
from adafruit_servokit import ServoKitRequired dependencies (automatically imported):
import board
from adafruit_pca9685 import PCA9685Optional imports for type hints:
from typing import Optional
from busio import I2C
from adafruit_motor.servo import Servo, ContinuousServoimport time
from adafruit_servokit import ServoKit
# Set channels to the number of servo channels on your kit.
# 8 for FeatherWing, 16 for Shield/HAT/Bonnet.
kit = ServoKit(channels=8)
# Control a standard servo on channel 0
kit.servo[0].angle = 180
time.sleep(1)
kit.servo[0].angle = 0
# Control a continuous rotation servo on channel 1
kit.continuous_servo[1].throttle = 1 # Forward
time.sleep(1)
kit.continuous_servo[1].throttle = -1 # Backward
time.sleep(1)
kit.continuous_servo[1].throttle = 0 # StopThe library provides a simple abstraction over the Adafruit PCA9685 PWM controller chip:
Creates a ServoKit instance representing an Adafruit PWM/Servo hardware kit with configurable I2C settings and PWM parameters.
class ServoKit:
def __init__(
self,
*,
channels: int,
i2c: Optional[I2C] = None,
address: int = 0x40,
reference_clock_speed: int = 25000000,
frequency: int = 50,
) -> None:
"""
Initialize ServoKit for controlling servo motors.
Parameters:
- channels: int - Number of servo channels (must be 8 or 16)
- i2c: Optional[I2C] - I2C bus instance (defaults to board.I2C())
- address: int - I2C address of PCA9685 controller (default: 0x40)
- reference_clock_speed: int - Internal reference clock frequency in Hz (default: 25000000)
- frequency: int - Overall PWM frequency in Hz (default: 50)
Raises:
- ValueError: If channels is not 8 or 16
"""Controls standard positioning servos with angle-based positioning from 0 to 180 degrees.
@property
def servo(self) -> "_Servo":
"""
Access to standard servo controls via channel indexing.
Returns:
_Servo instance providing indexed access to servo channels
"""
class _Servo:
def __getitem__(self, servo_channel: int) -> Servo:
"""
Get servo controller for specific channel.
Parameters:
- servo_channel: int - Channel number (0 to channels-1)
Returns:
Servo object from adafruit_motor.servo
Raises:
- ValueError: If channel number is out of range or already in use
"""
def __len__(self) -> int:
"""
Get number of available servo channels.
Returns:
int - Number of channels
"""Servo Object Interface (from adafruit_motor.servo):
class Servo:
@property
def angle(self) -> Optional[float]:
"""Current servo angle in degrees (0-180)"""
@angle.setter
def angle(self, value: Optional[float]) -> None:
"""Set servo angle in degrees (0-180)"""Controls continuous rotation servos with throttle-based speed and direction control.
@property
def continuous_servo(self) -> "_ContinuousServo":
"""
Access to continuous servo controls via channel indexing.
Returns:
_ContinuousServo instance providing indexed access to continuous servo channels
"""
class _ContinuousServo:
def __getitem__(self, servo_channel: int) -> ContinuousServo:
"""
Get continuous servo controller for specific channel.
Parameters:
- servo_channel: int - Channel number (0 to channels-1)
Returns:
ContinuousServo object from adafruit_motor.servo
Raises:
- ValueError: If channel number is out of range or already in use
"""
def __len__(self) -> int:
"""
Get number of available servo channels.
Returns:
int - Number of channels
"""ContinuousServo Object Interface (from adafruit_motor.servo):
class ContinuousServo:
@property
def throttle(self) -> Optional[float]:
"""Current throttle value (-1.0 to 1.0)"""
@throttle.setter
def throttle(self, value: Optional[float]) -> None:
"""Set throttle value (-1.0 to 1.0, where -1.0=full reverse, 1.0=full forward, 0=stop)"""from typing import Optional
from busio import I2C
from adafruit_motor.servo import Servo, ContinuousServo__version__: str # Library version string
__repo__: str # Repository URLThe library raises ValueError exceptions in the following cases:
channels=8channels=16channels=16channels=16All hardware uses the PCA9685 PWM controller and communicates via I2C.
import time
from adafruit_servokit import ServoKit
kit = ServoKit(channels=16)
# Move all servos sequentially
for i in range(len(kit.servo)):
kit.servo[i].angle = 180
time.sleep(1)
kit.servo[i].angle = 0
time.sleep(1)import time
from adafruit_servokit import ServoKit
kit = ServoKit(channels=16)
# Move all servos simultaneously
for i in range(len(kit.servo)):
kit.servo[i].angle = 180
time.sleep(1)
for i in range(len(kit.servo)):
kit.servo[i].angle = 0
time.sleep(1)import board
import busio
from adafruit_servokit import ServoKit
# Create custom I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Initialize with custom settings
kit = ServoKit(
channels=16,
i2c=i2c,
address=0x41, # Custom I2C address
frequency=60 # Custom PWM frequency
)