or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-adafruit-circuitpython-servokit

CircuitPython helper library for the PWM/Servo FeatherWing, Shield and Pi HAT and Bonnet kits.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/adafruit-circuitpython-servokit@1.3.x

To install, run

npx @tessl/cli install tessl/pypi-adafruit-circuitpython-servokit@1.3.0

index.mddocs/

Adafruit CircuitPython ServoKit

A 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.

Package Information

  • Package Name: adafruit-circuitpython-servokit
  • Language: Python (CircuitPython)
  • Installation: pip install adafruit-circuitpython-servokit
  • Dependencies: Adafruit-Blinka, adafruit-circuitpython-pca9685, adafruit-circuitpython-motor, adafruit-circuitpython-busdevice, adafruit-circuitpython-register

Core Imports

Primary import for the ServoKit class:

from adafruit_servokit import ServoKit

Required dependencies (automatically imported):

import board
from adafruit_pca9685 import PCA9685

Optional imports for type hints:

from typing import Optional
from busio import I2C
from adafruit_motor.servo import Servo, ContinuousServo

Basic Usage

import 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    # Stop

Architecture

The library provides a simple abstraction over the Adafruit PCA9685 PWM controller chip:

  • ServoKit: Main class representing the hardware kit, manages I2C communication and channel allocation through the underlying PCA9685 driver
  • _Servo: Channel accessor for standard positioning servos (0-180 degrees)
  • _ContinuousServo: Channel accessor for continuous rotation servos (-1.0 to 1.0 throttle)
  • Hardware Support: Compatible with 8-channel FeatherWing and 16-channel Shield/HAT/Bonnet kits
  • Dependencies: Built on adafruit-circuitpython-pca9685 and adafruit-circuitpython-motor libraries

Capabilities

Hardware Kit Initialization

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
        """

Standard Servo Control

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)"""

Continuous Servo Control

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)"""

Types

from typing import Optional
from busio import I2C
from adafruit_motor.servo import Servo, ContinuousServo

Module Constants

__version__: str  # Library version string
__repo__: str     # Repository URL

Error Handling

The library raises ValueError exceptions in the following cases:

  • Invalid channel count: ServoKit constructor called with channels not equal to 8 or 16
  • Channel out of range: Attempting to access servo channel outside valid range (0 to channels-1)
  • Channel conflict: Attempting to use a channel that's already assigned to a different servo type

Hardware Compatibility

  • 8-Channel PWM or Servo FeatherWing: Use channels=8
  • 16-Channel PWM/Servo Shield: Use channels=16
  • 16-Channel PWM/Servo HAT for Raspberry Pi: Use channels=16
  • 16-Channel PWM/Servo Bonnet for Raspberry Pi: Use channels=16

All hardware uses the PCA9685 PWM controller and communicates via I2C.

Usage Examples

Multiple Servos Sequential Control

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)

Multiple Servos Synchronized Control

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)

Custom I2C Configuration

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
)