If your robotic arm has more than two or three servos, a PCA9685 is the single best upgrade you can make. It takes servo control off your microcontroller’s shoulders and makes the whole arm steadier and easier to wire. Here’s exactly how to use one.
What the PCA9685 does
The PCA9685 is a 16-channel, 12-bit PWM driver on a small breakout board. You talk to it over I2C — just two signal wires — and it generates clean, independent PWM on all 16 outputs at once. Two things make it ideal for a robot arm:
- It frees your microcontroller. Driving six servos directly eats timers and pins and can cause jitter; the PCA9685 handles all of that over I2C.
- It has a separate power input. A screw terminal feeds servo current straight from your supply, so the current spikes of moving servos never reach (and reset) your board.
Wiring it up
The pattern is the same on every platform: logic on the signal side, a separate supply on the power side, grounds tied together.
Arduino Uno
5V→ PCA9685VCC(logic power for the chip)GND→ PCA9685GNDA4 (SDA)→SDA,A5 (SCL)→SCL(on a Mega use pin 20/21)- Separate 5–6V supply → PCA9685
V+andGNDscrew terminal - Servos → channels
0–15
ESP32 — GPIO21 (SDA), GPIO22 (SCL), 3V3→VCC, shared GND. (Full build:
ESP32 robotic arm.)
Raspberry Pi — SDA1 (GPIO2), SCL1 (GPIO3), 3V3→VCC, shared GND, and
enable I2C in raspi-config. (Full build:
Raspberry Pi robotic arm.)
The one mistake that breaks everything: forgetting to join the supply ground to the board ground. Without that shared ground the PWM signal has no reference and servos twitch or don’t move. Always tie grounds together.
I2C address and chaining
Out of the box a PCA9685 answers at I2C address 0x40. If you add a second board,
bridge the address solder jumpers to give it a new address (0x41, 0x42, …) and
both share the same two I2C wires. You can chain up to 62 boards — far more than
any hobby arm needs, but handy for a dual arm.
The code (Adafruit library)
On Arduino/ESP32, the Adafruit PWM Servo Driver library makes it a few lines:
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
void setup() {
pwm.begin();
pwm.setPWMFreq(50); // 50 Hz is standard for servos
}
// Map an angle (0–180°) to the servo's pulse range, then drive a channel.
void setAngle(uint8_t ch, int angle) {
int pulse = map(angle, 0, 180, 150, 600); // tune 150/600 per servo
pwm.setPWM(ch, 0, pulse);
}
The two numbers to tune are the min/max pulse (here 150/600) — every servo
model is slightly different, so sweep one servo and find the values where it hits
0° and 180° without straining. On a Raspberry Pi the equivalent is the
adafruit-circuitpython-pca9685/servokit library in Python.
Power, sized properly
Add up the stall current of every servo and size your supply above that — six MG996R-class servos can momentarily pull several amps together. Use a dedicated 5–6V supply or a buck converter, and see powering a robotic arm for the full picture.
Troubleshooting
- Servos jitter / don’t move → missing shared ground, or PWM frequency not set to ~50 Hz.
- Board resets when servos move → servo power is going through the microcontroller; move it to the V+ terminal.
- Only some channels work → re-flow the header/terminal solder joints (the reason a 2-pack is handy for spares).
- Nothing on I2C → wrong address or SDA/SCL swapped; run an I2C scanner sketch.
Grab a PCA9685 driver and servos and pair them with the Arduino code guide to get your arm moving. For any symptom not covered above, the full troubleshooting guide goes deeper.
Frequently asked questions
What is a PCA9685 used for?
The PCA9685 is a 16-channel, 12-bit PWM driver. In robotics it offloads servo control from your microcontroller: you send simple I2C commands and it generates steady PWM for up to 16 servos, with a separate power input so the servos don't brown out your board.
How do I connect a PCA9685 to an Arduino?
Four logic wires plus servo power. Arduino 5V→VCC, GND→GND, A4(SDA)→SDA, A5(SCL)→SCL (on an Uno). Then a separate 5–6V supply into the PCA9685's V+/GND screw terminal, and your servos into channels 0–15. Use the Adafruit PWM Servo Driver library in code.
Can a PCA9685 power servos directly?
No — the chip only handles the PWM signal. Servo current comes from the V+ screw terminal, which you feed from a separate 5–6V supply (or a buck converter). Never run servo power through the Arduino's 5V pin.
How many PCA9685 boards can I chain?
Up to 62 boards on one I2C bus by setting different addresses with the onboard solder jumpers — that's 992 channels. For a robot arm you'll rarely need more than one (16 channels), but chaining is there if you build something big.