> Source: https://www.tinkered.ai/components/pca9685-servo-driver/raspberry-pi-pico (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/pca9685-servo-driver/raspberry-pi-pico. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# PCA9685 16-Channel Servo Driver with a Raspberry Pi Pico

The PCA9685 board drives up to 16 servos for the Raspberry Pi Pico over two I2C wires, SDA on GP4 and SCL on GP5, at address 0x40. Its VCC comes from the Pico's 3V3 so the bus stays at 3.3 V, while the servos take their own 5 V to 6 V on the board's V+ terminal.

## Wiring

| PCA9685 16-Channel Servo Driver | Raspberry Pi Pico | Note |
| --- | --- | --- |
| VCC | 3V3 |  |
| GND | GND |  |
| SDA | GP4 |  |
| SCL | GP5 |  |

## What to know on the Raspberry Pi Pico

- SDA and SCL read high above 0.7 x VCC, and the board's pull-ups go to VCC: on 3V3 both match the Pico; on VBUS the bus would sit at 5 V. (NXP PCA9685 datasheet Rev. 4, p. 38)
- The chip itself draws 6 mA typical, 10 mA max, from the 3V3 pin. Servo current never touches the Pico: it comes in on V+ from a separate supply sharing GND. (NXP PCA9685 datasheet Rev. 4, p. 38)
- All 16 outputs share one frequency; setPWMFreq(50) suits servos, so LEDs on other channels flicker at 50 Hz too. (NXP PCA9685 datasheet Rev. 4, pp. 1, 25)
- Boards chain from 0x40 with address pads; 0x70 is the All Call address and stays unused. (NXP PCA9685 datasheet Rev. 4, pp. 7, 8)

## Code

Libraries: adafruit/Adafruit PWM Servo Driver Library

```cpp
// PCA9685 16-Channel Servo Driver on Raspberry Pi Pico: wiring and a free simulation at https://www.tinkered.ai/components/pca9685-servo-driver/raspberry-pi-pico
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

const uint16_t SERVO_MIN_US = 544;
const uint16_t SERVO_MAX_US = 2400;   // 180 degrees

void servoAngle(uint8_t ch, int deg) {
  pwm.writeMicroseconds(ch, map(constrain(deg, 0, 180), 0, 180, SERVO_MIN_US, SERVO_MAX_US));
}

void setup() {
  Serial.begin(115200);
  pwm.begin();
  pwm.setOscillatorFrequency(25000000);
  pwm.setPWMFreq(50);                // servos: 50 Hz
  pwm.setPWM(15, 0, 1024);           // the LED on 15 at 25 % (1024 of 4096)
}

void loop() {
  for (int deg = 0; deg <= 180; deg += 10) {
    servoAngle(0, deg);
    servoAngle(1, 180 - deg);
    delay(100);
  }
  for (int deg = 180; deg >= 0; deg -= 10) {
    servoAngle(0, deg);
    servoAngle(1, 180 - deg);
    delay(100);
  }
}
```

Compiled for rp2040:rp2040:rpipico on 2026-10-30.

## Questions

### Can a 3.3 V Pico drive the PCA9685?

Yes. The chip runs from 2.3 V to 5.5 V (NXP datasheet, p. 1) and reads I2C high above 0.7 x VCC (p. 38); power VCC from 3V3 and the servos from V+.

### Why use a PCA9685 when the Pico has 16 PWM channels?

The Pico's PWM outputs (Pico datasheet, p. 4) work for a few servos, but the PCA9685 frees the GPIOs, keeps servo timing off the RP2040 and chains boards on two wires.

### Why do my servos not move on the Pico?

V+ needs its own 5 V to 6 V supply with a common ground; VCC only powers the chip. Then check 0x40 and that setPWMFreq(50) runs after begin().

## More

- [PCA9685 16-Channel Servo Driver reference](https://www.tinkered.ai/components/pca9685-servo-driver.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the PCA9685 16-Channel Servo Driver on the Raspberry Pi Pico in the browser, with this wiring and code, free: https://www.tinkered.ai/components/pca9685-servo-driver/raspberry-pi-pico
