Blogs
PCA9685 16-Channel 12-bit PWM/Servo Driver
PCA9685 16-Channel 12-bit PWM/Servo Driver
I2C Interface for Arduino and Raspberry Pi Projects
Introduction
The PCA9685 is a 16-channel, 12-bit PWM controller with an I2C interface, perfect for controlling multiple servos or LEDs. This compact module can drive up to 16 servos with just 2 pins (SDA and SCL) from your microcontroller.

Key Features
16 PWM Channels
Independent control of 16 outputs
12-bit Resolution
4096 steps of PWM control
I2C Interface
Simple 2-wire communication
External Power
Supports 2.3V-5.5V for PWM outputs
Technical Specifications
Channels | 16 independent PWM outputs |
---|---|
Resolution | 12-bit (4096 steps) |
Interface | I2C (up to 1MHz) |
Addresses | 62 possible I2C addresses |
PWM Frequency | 40Hz to 1000Hz (adjustable) |
Logic Voltage | 2.3V to 5.5V |
Output Voltage | Same as V+ (2.3V-5.5V) |
Current per Channel | 25mA max (200mA total) |
Pin Configuration

Pin | Function | Description |
---|---|---|
VCC | Power | 2.3V-5.5V logic power |
GND | Ground | Common ground |
SCL | I2C Clock | Serial clock input |
SDA | I2C Data | Serial data input/output |
V+ | Output Power | 2.3V-5.5V for PWM outputs |
OE | Output Enable | Active low output enable |
PWM0-15 | PWM Outputs | 16 PWM output channels |
Wiring with Arduino
1 2 3 4 5 6 |
// Basic I2C Connection: // VCC → Arduino 5V // GND → Arduino GND // SCL → Arduino A5 (or SCL pin) // SDA → Arduino A4 (or SDA pin) // V+ → External power (for servos) |
Wiring with Raspberry Pi
1 2 3 4 5 6 |
# Basic I2C Connection: # VCC → Pi 3.3V # GND → Pi GND # SCL → Pi GPIO 3 (SCL) # SDA → Pi GPIO 2 (SDA) # V+ → External power (for servos) |
Arduino Code Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); void setup() { Serial.begin(9600); pwm.begin(); pwm.setPWMFreq(60); // Analog servos run at ~60 Hz } void loop() { // Move servo on channel 0 from 0 to 180 degrees for (uint16_t pulselen = 150; pulselen < 600; pulselen++) { pwm.setPWM(0, 0, pulselen); delay(5); } delay(500); for (uint16_t pulselen = 600; pulselen > 150; pulselen--) { pwm.setPWM(0, 0, pulselen); delay(5); } delay(500); } |
Raspberry Pi Python Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from board import SCL, SDA import busio from adafruit_pca9685 import PCA9685 from adafruit_motor import servo i2c = busio.I2C(SCL, SDA) pca = PCA9685(i2c) pca.frequency = 50 # Servos typically run at 50Hz servo1 = servo.Servo(pca.channels[0]) while True: for angle in range(0, 180, 5): # 0 to 180 degrees servo1.angle = angle for angle in range(180, 0, -5): # 180 to 0 degrees servo1.angle = angle |
Advanced Applications
LED Dimming
1 2 |
// Set LED brightness (0-4095) pwm.setPWM(channel, 0, brightness); |
Multiple Servos
1 2 3 4 |
// Control multiple servos pwm.setPWM(0, 0, servo1Pos); pwm.setPWM(1, 0, servo2Pos); pwm.setPWM(2, 0, servo3Pos); |
Cascading Modules
1 2 3 |
// Control multiple PCA9685s Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41); pwm2.setPWMFreq(60); |
Troubleshooting
No Response
- Check I2C connections (SDA/SCL)
- Verify power supply is connected
- Confirm I2C address (default 0x40)
Servo Jitter
- Ensure adequate power supply
- Check for loose connections
- Try different PWM frequency (50-60Hz for servos)
I2C Errors
- Verify pull-up resistors on SDA/SCL
- Check for address conflicts
- Test with different I2C speed