adafruit_pca9685
Works with
Any board with I2C. The PCA9685 chip is found on the Motor Shield V2, Servo FeatherWing, and standalone breakout boards.
What it does
adafruit_pca9685 is the low-level driver for the PCA9685 16-channel 12-bit PWM controller chip. It lets you set the frequency and duty cycle of up to 16 PWM channels independently over a single I2C connection. Most users will interact with this chip through higher-level libraries like adafruit_servokit or adafruit_motorkit — but you need direct access when driving LEDs, ESCs (electronic speed controllers), custom actuators, or anything that requires raw PWM values rather than servo angles or motor throttle abstractions.
Multiple PCA9685 boards can be stacked on the same I2C bus by configuring address jumpers (0x40 through 0x7F), giving up to 992 PWM channels from a single microcontroller.
Installing the library
Copy all of the following to CIRCUITPY/lib/:
adafruit_pca9685.mpyadafruit_bus_device/(folder)
Quick start
import board
import busio
from adafruit_pca9685 import PCA9685
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c) # default address 0x40
pca.frequency = 50 # 50 Hz for servos; up to 1600 Hz for LEDs
# Set channel 0 to 50% duty cycle
# duty_cycle is 16-bit: 0 = off, 0xFFFF = fully on
pca.channels[0].duty_cycle = 0x7FFF # ~50%
# Set a servo pulse manually (50 Hz = 20 ms period)
# 1.5 ms pulse = 90 degrees center position
# 1.5 ms / 20 ms * 65535 ≈ 4915
pca.channels[1].duty_cycle = 4915
# Turn a channel fully on or off
pca.channels[2].duty_cycle = 0xFFFF # fully on
pca.channels[3].duty_cycle = 0 # off
# Second board on the same I2C bus
pca2 = PCA9685(i2c, address=0x41)
pca2.frequency = 1000 # 1 kHz for LEDs
Key things you can do
| What you want | How to do it |
|---|---|
| Set PWM frequency | pca.frequency = 50 (1–1600 Hz) |
| Set channel duty cycle | pca.channels[n].duty_cycle = value (0–65535) |
| Turn a channel fully on | pca.channels[n].duty_cycle = 0xFFFF |
| Turn a channel off | pca.channels[n].duty_cycle = 0 |
| Use a non-default I2C address | PCA9685(i2c, address=0x41) |
| Stack multiple boards | Create separate PCA9685 instances with different addresses |
| Reset all channels | pca.reset() |
| Drive LEDs at high frequency | Set frequency = 1000 or higher to eliminate visible flicker |
| Control an ESC | Set frequency = 50, then set pulse widths matching your ESC's calibration range |
Reading the official docs
Full API reference: https://docs.circuitpython.org/projects/pca9685/en/latest/
Projects using this library
- PCA9685 16-Channel PWM Driver — using the standalone breakout board for servo and LED control from Python and CircuitPython