This project demonstrates how to control multiple servo motors simultaneously using the PCA9685 16-channel PWM/Servo Driver module with Arduino. The PCA9685 module solves the limitation of Arduino's 6 PWM pins by providing 16 independent PWM outputs through I2C communication.
Original Tutorial: PCA9685 Multiple Servo Control Using Arduino
- Control up to 16 servo motors with a single PCA9685 module
- I2C communication using only 2 Arduino pins (SDA & SCL)
- Cascadable up to 62 modules (992 total outputs)
- Built-in clock eliminates continuous signal transmission
- 3.3V and 5V compatible
- Precise 12-bit PWM resolution
| Component | Quantity | Description |
|---|---|---|
| Arduino Uno R3 | 1 | Main microcontroller |
| SG90 Servo Motor | 8 | Standard servo motors |
| PCA9685 16-Channel Module | 1 | PWM/Servo driver |
| External 5V Adapter | 1 | Power supply for servos |
| Jumper Wires | As needed | Connections |
- VCC: Power supply (3.3V to 5V) for module circuitry
- GND: Ground connection
- SDA: I2C data line (connect to Arduino A4)
- SCL: I2C clock line (connect to Arduino A5)
- OE: Output Enable (optional, pull low to disable outputs)
- V+: External power for servos (connect to 5V adapter)
Arduino PCA9685
VCC -> 5V
GND -> GND
A4 -> SDA
A5 -> SCL
- Connect Arduino VCC and GND to PCA9685 VCC and GND
- Connect Arduino A4 to PCA9685 SDA
- Connect Arduino A5 to PCA9685 SCL
- Connect external 5V adapter positive to PCA9685 V+
- Connect external adapter ground to common ground
- Connect servos to channels 0-7 on PCA9685
- Open Arduino IDE
- Go to Tools > Manage Libraries
- Search for "Adafruit PWM Servo Driver"
- Install the library
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
#define SERVOMIN 125 // Minimum pulse length (0 degrees)
#define SERVOMAX 625 // Maximum pulse length (180 degrees)
void setup() {
Serial.begin(9600);
Serial.println("16 channel Servo test!");
board1.begin();
board1.setPWMFreq(60); // Servos operate at ~60 Hz
}
void loop() {
// Set all servos to 0 degrees
for(int i=0; i<8; i++) {
board1.setPWM(i, 0, angleToPulse(0));
}
delay(1000);
// Sweep all servos from 0 to 180 degrees
for(int angle = 0; angle < 181; angle += 10) {
for(int i=0; i<8; i++) {
board1.setPWM(i, 0, angleToPulse(angle));
}
delay(100);
}
}
int angleToPulse(int ang) {
int pulse = map(ang, 0, 180, SERVOMIN, SERVOMAX);
Serial.print("Angle: "); Serial.print(ang);
Serial.print(" pulse: "); Serial.println(pulse);
return pulse;
}- setPWM(channel, on, off): Sets PWM values for specific channel
- setPWMFreq(frequency): Sets PWM frequency (60Hz for servos)
- angleToPulse(angle): Converts angle to pulse width
You can cascade multiple PCA9685 modules by:
- Setting unique I2C addresses using address jumpers (A0-A5)
- Creating separate objects for each module
- Default address is 0x40, next would be 0x41, etc.
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);- Board 0: Address = 0x40 (no jumpers)
- Board 1: Address = 0x41 (bridge A0)
- Board 2: Address = 0x42 (bridge A1)
- Board 3: Address = 0x43 (bridge A0 & A1)
- PWM Resolution: 12-bit (4096 steps)
- I2C Address: 0x40 (default, configurable)
- Max Current per Pin: 25mA
- Operating Voltage: 3.3V to 5V
- PWM Frequency: Configurable (60Hz for servos)
- Output Resistance: 220Ω series resistor per pin
- Servos not moving: Check external power supply connection
- Erratic movement: Ensure proper ground connections
- Communication errors: Verify I2C connections (SDA/SCL)
- Power issues: Use adequate external power supply (not Arduino 5V)
- Arduino cannot power multiple servos directly
- PCA9685 provides control signals, not power
- All channels share the same PWM frequency
- Maximum 25mA per output pin
- Robotics: Multi-joint robot arms and legs
- Automation: Multiple actuator control systems
- Animatronics: Character movement systems
- RC Projects: Multi-servo aircraft/vehicle control
- IoT Devices: Smart home automation systems
The complete Arduino sketch is provided above. Modify the servo count in the for loops if using different numbers of servos.
- Web Control: Add ESP32/ESP8266 for web-based servo control
- Sensor Integration: Add sensors for autonomous servo positioning
- Multiple Modules: Cascade additional PCA9685 modules for more servos
- Precise Control: Implement position feedback for closed-loop control
- Original Circuit Digest Tutorial
- Adafruit PCA9685 Library Documentation
- Servo Motor Basics
- Arduino Projects
This project is based on the open-source tutorial from Circuit Digest. Please refer to their terms and conditions for usage rights.
Created by: Circuit Digest Team
Tutorial Source: https://circuitdigest.com/microcontroller-projects/pca9685-multiple-servo-control-using-arduino

