💡 Overview
The PCA9685 is an I2C-controlled 16-channel, 12-bit PWM driver module. Using only two I2C pins (SDA & SCL), you can independently control 16 free-running PWM outputs — perfect for driving multiple servo motors, LEDs, or other PWM-controlled devices. The on-board oscillator eliminates the need for external clocks, and because the chip handles all PWM generation internally, your microcontroller is free to perform other tasks without constant signal updates.
You can chain up to 62 modules on a single I2C bus for a total of 992 independently controllable PWM outputs, making this module ideal for robotics, animatronics, LED installations, and complex automation projects.
⭐ Key Features
- 16 independent PWM channels with 12-bit resolution (4096 steps)
- Built-in oscillator — no external clock required; outputs are free-running
- I2C interface — uses only 2 pins (SDA & SCL) on your microcontroller
- Adjustable PWM frequency from ~24 Hz to ~1526 Hz
- 5V-tolerant inputs — controllable from 3.3V or 5V logic microcontrollers
- Servo output voltage up to 6V via separate V+ power input
- 6 address-select solder jumpers — up to 62 unique addresses on one I2C bus
- Chainable design with pass-through headers for easy daisy-chaining
- Output Enable (OE) pin — quickly disable all outputs with a single signal
- 220Ω series resistors on all output lines for protection and easy LED driving
- Configurable push-pull or open-drain output mode
- Reverse polarity protection on the terminal block power input
- Green power-on LED indicator
- 3-pin servo connectors in groups of 4 for easy plug-and-play servo connection
📋 Specifications
| Parameter | Value |
|---|---|
| Controller IC | PCA9685 (NXP) |
| PWM Channels | 16 |
| PWM Resolution | 12-bit (4096 steps) |
| PWM Frequency Range | 24 Hz – 1526 Hz (adjustable) |
| Interface | I2C (up to 1 MHz clock speed) |
| Default I2C Address | 0x40 |
| Addressable Range | 0x40 – 0x7F (62 unique addresses) |
| Logic Voltage (VCC) | 2.3V – 5.5V |
| Servo Power (V+) | Up to 6V (via terminal block or header) |
| Output Current (per channel) | 25 mA (sink) / 10 mA (source) |
| Output Protection | 220Ω series resistors on all channels |
| Output Type | Configurable push-pull or open-drain (totem pole) |
| Servo Resolution at 60 Hz | ~4 µs per step |
| Operating Temperature | -40°C to +85°C |
| Board Dimensions | ~62 mm × 26 mm (2.4" × 1.0") |
📌 Pin Descriptions
Control / I2C Header Pins
| Pin | Function | Description |
|---|---|---|
| GND | Ground | Common ground — connect to MCU ground |
| OE | Output Enable | Active LOW. Pull LOW to enable outputs (default via pull-down). Pull HIGH to disable all PWM outputs instantly. |
| SCL | I2C Clock | Connect to MCU SCL pin |
| SDA | I2C Data | Connect to MCU SDA pin |
| VCC | Logic Power | 2.3V – 5.5V power for the PCA9685 chip logic (NOT servo power) |
| V+ | Servo Power | Power rail for servos/LEDs connected to the output pins (up to 6V) |
Servo Output Pins (×16)
| Pin | Function |
|---|---|
| PWM (Signal) | PWM output signal to servo signal wire (typically white or orange) |
| V+ | Servo power (connected to V+ rail — typically red wire) |
| GND | Ground (typically brown or black wire) |
Power Terminal Block
| Terminal | Function |
|---|---|
| V+ | External servo power input (up to 6V) — reverse polarity protected |
| GND | Ground for external servo power supply |
🔌 Wiring to Arduino
Arduino Uno / Nano / Pro Mini
| PCA9685 Pin | Arduino Pin | Notes |
|---|---|---|
| VCC | 5V | Logic power for the PCA9685 chip |
| GND | GND | Common ground |
| SDA | A4 (or SDA) | I2C data line |
| SCL | A5 (or SCL) | I2C clock line |
Arduino Mega 2560
| PCA9685 Pin | Arduino Pin | Notes |
|---|---|---|
| VCC | 5V | Logic power for the PCA9685 chip |
| GND | GND | Common ground |
| SDA | D20 (or SDA) | I2C data line |
| SCL | D21 (or SCL) | I2C clock line |
ESP32 / ESP8266
| PCA9685 Pin | ESP32 Pin | ESP8266 Pin |
|---|---|---|
| VCC | 3.3V | 3.3V |
| GND | GND | GND |
| SDA | GPIO 21 | GPIO 4 (D2) |
| SCL | GPIO 22 | GPIO 5 (D1) |
Raspberry Pi Pico
| PCA9685 Pin | Pico Pin | Notes |
|---|---|---|
| VCC | 3V3 (Pin 36) | Logic power |
| GND | GND (Pin 38) | Common ground |
| SDA | GP0 (Pin 1) | I2C0 SDA (default) |
| SCL | GP1 (Pin 2) | I2C0 SCL (default) |
🔋 Powering Your Servos
Servos can draw significant current — a single micro servo may draw 200–500 mA under load, and high-torque servos can exceed 1A each. Do not attempt to power servos from the Arduino's 5V pin — it cannot supply enough current and may damage your board.
Recommended Power Sources for V+
- 5V 2A–10A switching power supply — best for desktop/bench projects
- 4×AA battery holder — provides 6V (alkaline) or 4.8V (NiMH rechargeable)
- 4.8V or 6V RC battery pack — great for mobile robotics
- 5V USB power bank (with sufficient amperage) — portable option
💻 Arduino Code Example – Servo Control
Step 1: Install the Library
In the Arduino IDE, go to Sketch → Include Library → Manage Libraries… and search for Adafruit PWM Servo. Install the Adafruit PWM Servo Driver Library by Adafruit.
Step 2: Upload the Sweep Example
This example sweeps a servo back and forth on channel 0:
/***************************************************
PCA9685 Servo Sweep Example
Sweeps a servo on channel 0 from min to max position.
Connections:
Arduino 5V → PCA9685 VCC
Arduino GND → PCA9685 GND
Arduino SDA → PCA9685 SDA
Arduino SCL → PCA9685 SCL
External 5-6V → PCA9685 V+ terminal block
***************************************************/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// Create the driver object (default address 0x40)
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// Typical servo pulse length counts (out of 4096) at 60 Hz
// Adjust these values for your specific servo
#define SERVOMIN 150 // Minimum pulse length (~1 ms)
#define SERVOMAX 600 // Maximum pulse length (~2 ms)
// Servo channel on the PCA9685 (0-15)
#define SERVO_CHANNEL 0
void setup() {
Serial.begin(9600);
Serial.println("PCA9685 Servo Sweep Test");
pwm.begin();
pwm.setOscillatorFrequency(27000000); // Internal oscillator calibration
pwm.setPWMFreq(60); // Set frequency to 60 Hz for servos
delay(10);
}
void loop() {
// Sweep from minimum to maximum
Serial.println("Sweeping forward...");
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(SERVO_CHANNEL, 0, pulselen);
delay(5);
}
delay(500);
// Sweep from maximum to minimum
Serial.println("Sweeping backward...");
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(SERVO_CHANNEL, 0, pulselen);
delay(5);
}
delay(500);
}
Understanding setPWM()
The key function is pwm.setPWM(channel, on, off):
| Parameter | Range | Description |
|---|---|---|
channel |
0 – 15 | Which output channel to control |
on |
0 – 4095 | Tick count when the signal goes HIGH (usually 0) |
off |
0 – 4095 | Tick count when the signal goes LOW (controls pulse width) |
At 60 Hz, each cycle is ~16.67 ms divided into 4096 steps, so each step ≈ 4.07 µs. A typical servo expects a pulse between 1 ms (~246 counts) and 2 ms (~492 counts), but many servos accept a wider range. The values SERVOMIN (150) and SERVOMAX (600) in the example above provide a safe starting range — adjust them to match your specific servo's requirements.
pwm.writeMicroseconds(channel, microseconds) from the Adafruit library to set the pulse width in microseconds directly, which is often more intuitive. For example: pwm.writeMicroseconds(0, 1500) sets channel 0 to center position (1500 µs).💻 Arduino Code Example – LED Dimming
The PCA9685 is also excellent for controlling LED brightness. With 12-bit resolution, you get 4096 brightness levels per channel — far smoother than the Arduino's built-in 8-bit PWM (256 levels). The 220Ω series resistors on each output make it safe to connect LEDs directly for many common LED types.
/***************************************************
PCA9685 LED Dimming Example
Fades an LED on channel 0 up and down.
Connect an LED (with appropriate resistor if needed)
between the PWM pin and GND of channel 0.
Note: The board has built-in 220 ohm series resistors.
***************************************************/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define LED_CHANNEL 0
void setup() {
Serial.begin(9600);
Serial.println("PCA9685 LED Dimming Test");
pwm.begin();
pwm.setPWMFreq(1000); // Set to 1000 Hz for flicker-free LED dimming
delay(10);
}
void loop() {
// Fade up
for (uint16_t brightness = 0; brightness < 4096; brightness += 16) {
pwm.setPWM(LED_CHANNEL, 0, brightness);
delay(5);
}
// Fade down
for (uint16_t brightness = 4095; brightness > 0; brightness -= 16) {
pwm.setPWM(LED_CHANNEL, 0, brightness);
delay(5);
}
// Fully off
pwm.setPWM(LED_CHANNEL, 0, 0);
delay(500);
}
📡 I2C Address Configuration
The default I2C address is 0x40. The module has 6 solder jumper pads (labeled A0–A5) that allow you to set a custom address by bridging the appropriate jumpers. Each bridged jumper adds its binary value to the base address.
| Board # | Address | Jumpers to Bridge |
|---|---|---|
| 0 (default) | 0x40 | None |
| 1 | 0x41 | A0 |
| 2 | 0x42 | A1 |
| 3 | 0x43 | A0 + A1 |
| 4 | 0x44 | A2 |
| 5 | 0x45 | A0 + A2 |
| 6 | 0x46 | A1 + A2 |
| 7 | 0x47 | A0 + A1 + A2 |
| …continue the binary pattern up to all 6 jumpers for 62 unique addresses | ||
To set an address, apply a small solder bridge across the corresponding jumper pad(s) on the board.
🔧 Chaining Multiple Modules
The PCA9685 module features pass-through headers on both sides, making it easy to daisy-chain multiple boards. Simply connect the output header of one board to the input header of the next using jumper wires or a ribbon cable.
Steps to Chain Modules
- Set a unique I2C address on each board using the solder jumpers (see table above).
- Connect the boards in series: VCC→VCC, GND→GND, SDA→SDA, SCL→SCL.
- Each board needs its own V+ servo power connection (or share a common high-current supply).
- In your code, create a separate driver object for each board address.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// Board 0 at default address 0x40
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);
// Board 1 with A0 jumper bridged = address 0x41
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);
void setup() {
Serial.begin(9600);
pwm1.begin();
pwm1.setOscillatorFrequency(27000000);
pwm1.setPWMFreq(60);
pwm2.begin();
pwm2.setOscillatorFrequency(27000000);
pwm2.setPWMFreq(60);
}
void loop() {
// Control servo on Board 0, Channel 0
pwm1.setPWM(0, 0, 300);
// Control servo on Board 1, Channel 0
pwm2.setPWM(0, 0, 450);
delay(1000);
}
🚀 Quick-Start Checklist
- Connect VCC and GND from your Arduino to the PCA9685 module.
- Connect SDA and SCL to the appropriate I2C pins on your Arduino.
- Connect an external 5–6V power supply to the V+ terminal block for servo power.
- Plug your servo(s) into the 3-pin headers (channels 0–15). Match signal/V+/GND orientation.
- Verify the green power LED is lit on the module.
- Install the Adafruit PWM Servo Driver Library in the Arduino IDE.
- Upload the servo sweep example and verify your servo moves.
- Adjust
SERVOMINandSERVOMAXvalues to calibrate your servo's range of motion.
🎯 Typical Applications
- Robotics — Hexapod walkers, robotic arms, pan-tilt camera mounts
- Animatronics — Coordinated multi-servo character movements
- RC Vehicles — Multi-channel steering, throttle, and accessory control
- LED Lighting — Smooth 12-bit dimming for RGB LED arrays, architectural lighting
- Home Automation — Motorized blinds, vent controllers, door locks
- 3D Printers / CNC — Auxiliary servo control for tool changers, pen plotters
- IoT Projects — Cloud-controlled servo/LED systems via ESP32 or Raspberry Pi
- Education — Learning I2C communication and PWM signal generation
🛒 What You'll Need
- PCA9685 16-Channel PWM Servo Driver Module (this product)
- Arduino Uno/Nano/Mega, ESP32, ESP8266, Raspberry Pi Pico, or compatible MCU
- Servo motor(s) or LEDs
- External 5–6V DC power supply (rated for your total servo current draw)
- Jumper wires (male-to-female recommended)
- Breadboard (optional, for prototyping)
- USB cable for programming your microcontroller
- Arduino IDE with the Adafruit PWM Servo Driver Library installed
🛠️ Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| Servos don't move | No V+ power connected | Connect an external 5–6V supply to the V+ terminal block. The green LED confirms chip power, but servos need V+ separately. |
| Servos jitter or twitch | Insufficient power supply current | Use a higher-amperage power supply. Multiple servos under load can draw several amps. |
| I2C communication fails | Wrong SDA/SCL pins or missing ground | Verify wiring matches your board's I2C pins. Ensure all GND connections are shared between MCU, PCA9685, and power supply. |
| Only some channels work | Incorrect channel number in code | Channels are numbered 0–15. Verify the channel number matches the physical connector your servo is plugged into. |
| Module not detected on I2C scan | Address conflict or wiring issue | Run an I2C scanner sketch. Check that address jumpers match the address in your code. Verify SDA/SCL aren't swapped. |
| Servo moves to wrong position | SERVOMIN/SERVOMAX values need calibration | Adjust the min/max pulse values incrementally. Each servo model has slightly different pulse requirements. |
| Green LED not lit | VCC not connected or insufficient voltage | Ensure VCC is connected to 3.3V or 5V from your MCU. Check for loose connections. |
| LEDs flicker when dimming | PWM frequency too low | Increase the PWM frequency to 1000 Hz or higher for LED applications using setPWMFreq(1000). |
I2C Scanner Sketch
Use this sketch to verify the module is detected and confirm its I2C address:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial);
Serial.println("I2C Scanner - Scanning...");
}
void loop() {
byte error, address;
int devicesFound = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("Device found at address 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
devicesFound++;
}
}
if (devicesFound == 0)
Serial.println("No I2C devices found. Check wiring!");
else
Serial.println("Scan complete.");
delay(5000);
}
⚠️ Important Notes
- Separate power rails: VCC powers the PCA9685 chip logic only. V+ powers the servo motors. Always connect both.
- Do not power servos from Arduino: The Arduino's 5V regulator cannot supply enough current for servo motors. Always use an external power supply for V+.
- Common ground is essential: The GND of your MCU, the PCA9685 module, and the external servo power supply must all be connected together.
- Servo voltage limit: Do not exceed 6V on the V+ rail. Higher voltages can damage servos and the module.
- Heat considerations: If driving many servos at high load simultaneously, ensure adequate ventilation. The PCA9685 chip may become warm under heavy use.
- I2C pull-up resistors: The module includes on-board 10kΩ pull-up resistors on SDA and SCL. If chaining many modules, you may need to remove some pull-ups to avoid excessive bus loading.
- Output Enable (OE): The OE pin is active LOW with an on-board pull-down resistor (outputs enabled by default). Drive OE HIGH to instantly disable all outputs — useful as an emergency stop.
- Servo calibration: Every servo model has slightly different pulse width requirements. Always test and calibrate SERVOMIN/SERVOMAX values with your specific servos before deploying.
- ESD precautions: Handle the module by its edges. Avoid touching the IC or exposed pins to prevent electrostatic damage.
🏪 Where to Buy the PCA9685
The PCA9685 16-Channel 12-Bit I2C PWM Servo Motor Driver Module is available directly from Envistia Mall:
PCA9685 16-Channel 12-Bit I2C PWM Servo Motor Driver Module
📚 Additional Resources
- PCA9685 Datasheet (NXP)
- Adafruit PWM Servo Driver Library (GitHub)
- PCA9685 Servo Control Using Arduino (YouTube – Brainy-Bits)
- PCA9685 Servo Control Using Arduino (YouTube – Brainy-Bits):
Disclaimer: This user guide is provided for informational and educational purposes only by Envistia Mall. While every effort has been made to ensure accuracy, Envistia Mall makes no warranties or representations regarding the completeness, reliability, or suitability of this information for any particular purpose. Use of this product and the information contained herein is at your own risk. Envistia Mall shall not be held liable for any damages, injuries, or losses resulting from the use or misuse of this product or guide. Always follow proper safety precautions when working with electronic components.