Blog · Tutorial

PCA9685 servo tutorial: 16 servos, two wires

Tutorial

Sixteen servos, two signal wires, and a host that does nothing once it's set up. Wiring the PCA9685 takes five minutes — but three details decide whether it works, and none of them are printed on the board.

Step 1

PCA9685 wiring: two supplies, one ground

The PCA9685 needs two separate power paths, and conflating them is the most common way this goes wrong. Logic power runs the chip; V+ runs the servos and never touches the host.

How big a supply? A micro servo idles at tens of milliamps and pulls an amp or more stalled — and a servo holding position against a load is partly stalled continuously. Sixteen of them is a real power budget, not a pin on a dev board.

Get this wrong and the symptom won't look like power. The rail sags whenever something moves, the host browns out, i2c transactions die mid-byte, and you get intermittent "device not found" errors that read exactly like a pull-up problem. People chase that for hours. If your bus only drops out when a servo moves, it's the supply.

Step 2

The PCA9685 i2c address is 0x40 — and also 0x70

Before any code, run an i2c scan. You should see 0x40, the default, moved by the six solder jumpers if you need it elsewhere.

You will also see 0x70, and that one surprises people. NXP's datasheet is explicit: the LED All Call address register resets to 0xE0 — 0x70 in 7-bit terms — and the ALLCALL bit in MODE1 is enabled at power-up. Every PCA9685 answers 0x70 from boot, so you can command a rack of them with a single write.

The problem is who else lives there. 0x70 is TCA9546A and TCA9548A multiplexer territory — the exact part you reach for when you have too many devices, which is exactly when you're also running a servo driver. Both answer, both get confused, and a scan just shows "0x70" without telling you two chips replied. Fix it by clearing MODE1 bit 0 (code below) or strapping the mux to 0x71–0x77. Our collision roundup covers the rest of that neighbourhood.

Step 3

PCA9685 frequency: set 50 Hz before anything else

The output frequency is global: one prescaler, all sixteen channels. It spans roughly 24 Hz to 1526 Hz because the chip was built for LED dimming, and it resets to 200 Hz.

Servos want ~50 Hz — a pulse every 20 ms. Leave it at 200 Hz and they buzz audibly, hunt around the setpoint, run hot, draw far more current than they should, and can strip their own gears trying to track a signal that means nothing to them. The failure looks mechanical, so people blame the servos.

The prescaler value comes straight from the datasheet:

prescale = round(osc_clock / (4096 × update_rate)) − 1

  50 Hz:  round(25 MHz / (4096 × 50))  − 1 = 121  (0x79)
 200 Hz:  round(25 MHz / (4096 × 200)) − 1 =  30  (0x1E)  ← the reset default

One catch that wastes an evening: writes to PRE_SCALE are ignored unless the SLEEP bit in MODE1 is set. The prescaler feeds the internal oscillator, so it can't move while the oscillator runs. That's why every set-frequency routine sleeps the chip, writes the value, wakes it, waits for the oscillator to settle, then pulses RESTART. Miss the sleep and the write silently does nothing — the command appears to run and the frequency doesn't change.

Step 4 · Arduino

PCA9685 Arduino code: move a servo

Install Adafruit's PWM Servo Driver library from the Library Manager, then:

#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

void setup() {
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);  // trim — see note below
  pwm.setPWMFreq(50);                    // servos: 50 Hz, NOT the 200 Hz default
  delay(10);
}

void loop() {
  // Pulse width in microseconds — the servo's own language.
  // 1000 = one end, 1500 = centre, 2000 = the other end.
  pwm.writeMicroseconds(0, 1000); delay(600);
  pwm.writeMicroseconds(0, 1500); delay(600);
  pwm.writeMicroseconds(0, 2000); delay(600);
}

Prefer writeMicroseconds over raw setPWM counts — it says what you mean. If you do use counts, the maths at 50 Hz is 20 ms ÷ 4096 ≈ 4.88 µs per step, so 1.0 ms ≈ 205 counts and 2.0 ms ≈ 410.

About setOscillatorFrequency(27000000): the internal oscillator is nominally 25 MHz but varies part to part, so your real output drifts from what you asked for. That call lets you correct it — measure the actual output with a logic analyzer and tune the number until 50 Hz is 50 Hz. For hobby servos the default is usually close enough; for anything timing-critical, measure rather than assume.

Start with one servo, unloaded, before wiring sixteen. If it sweeps smoothly end to end, your frequency is right and the rest is just repetition.

Step 4 · MicroPython

PCA9685 MicroPython: the same thing on raw registers

No library needed — the chip is simple enough to drive directly, and doing it once shows you exactly what the Arduino library hides. Register map from the datasheet: MODE1 at 0x00, PRE_SCALE at 0xFE, and four bytes per channel from LED0_ON_L = 0x06.

from machine import I2C, Pin
import time

PCA = 0x40
MODE1, PRESCALE, LED0_ON_L = 0x00, 0xFE, 0x06

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400_000)   # Pico defaults

def set_freq(hz):
    # datasheet: prescale = round(25MHz / (4096 * hz)) - 1
    prescale = round(25_000_000 / (4096 * hz)) - 1
    old = i2c.readfrom_mem(PCA, MODE1, 1)[0]
    i2c.writeto_mem(PCA, MODE1, bytes([(old & 0x7F) | 0x10]))  # SLEEP — required!
    i2c.writeto_mem(PCA, PRESCALE, bytes([prescale]))
    i2c.writeto_mem(PCA, MODE1, bytes([old]))                  # wake
    time.sleep_ms(1)                                           # oscillator settles
    i2c.writeto_mem(PCA, MODE1, bytes([old | 0xA0]))           # RESTART + auto-increment

def write_us(ch, us, hz=50):
    counts = round(us * 4096 * hz / 1_000_000)      # 1500us @ 50Hz -> 307
    i2c.writeto_mem(PCA, LED0_ON_L + 4 * ch,
                    bytes([0, 0, counts & 0xFF, counts >> 8]))

def all_call(on):
    # MODE1 bit 0 = ALLCALL. Clear it and the chip stops answering 0x70 —
    # this is how you stop it fighting a multiplexer.
    old = i2c.readfrom_mem(PCA, MODE1, 1)[0]
    i2c.writeto_mem(PCA, MODE1, bytes([(old | 0x01) if on else (old & ~0x01)]))

set_freq(50)
all_call(False)          # only needed if a mux shares the bus
for us in (1000, 1500, 2000):
    write_us(0, us)
    time.sleep(0.6)

That all_call(False) line is the 0x70 fix from Step 2. Run it, rescan, and 0x70 disappears — your multiplexer has the address to itself.

Going further

Stacking PCA9685 boards

Sixteen channels not enough? The address jumpers put several PCA9685s on the same two wires — bridge A0 on the second board and it moves to 0x41. Sixteen more channels, same SDA/SCL, no extra host pins.

Two limits. Current, obviously: thirty-two moving servos is a serious supply. And the bus — every board you chain adds its pull-up resistors in parallel plus more cable capacitance, and eventually the edges get too lazy to make it. If a long chain turns flaky, that's where to look. Nothing responding at all? The 7-step checklist beats guessing.

Get one

Questions

PCA9685 FAQ

What is the PCA9685's i2c address?

0x40 out of the box. Six solder jumpers (A0–A5) move it, and because all six are yours the part reaches well past the 0x40–0x4F range people expect — NXP's datasheet says up to 62 devices can share one bus. Mind the top of that range: 0x70 is the all-call address it already answers, and 0x78–0x7F is reserved by the i2c spec.

Why does my PCA9685 respond to 0x70 as well as its own address?

Because the LED All Call address is on from power-up. The ALLCALLADR register resets to 0xE0 — that's 0x70 as a 7-bit address — and the ALLCALL bit in MODE1 defaults to enabled, so every PCA9685 answers 0x70 the moment it boots. It's there so you can command a rack of drivers at once, but it collides head-on with a TCA9548A multiplexer. Clear bit 0 of MODE1 to switch it off, or move the mux to 0x71–0x77.

What PWM frequency do servos need?

About 50 Hz — a pulse every 20 ms. The PCA9685 resets to 200 Hz because it's designed for LEDs as much as servos, so you must set the frequency yourself before attaching anything. Leave it at 200 Hz and servos buzz, hunt, draw far more current than they should and can strip their gears.

Why does setting the frequency need a sleep step?

The datasheet blocks writes to PRE_SCALE unless the SLEEP bit in MODE1 is set — the prescaler feeds the internal oscillator, so it can't change while the oscillator runs. That's why every set-frequency routine sleeps the chip, writes PRE_SCALE, wakes it, waits, then pulses RESTART. Skip the sleep and your write is silently ignored, which looks like the frequency command doing nothing at all.

Can I power servos from the PCA9685 board?

Only through its dedicated V+ terminal, from a supply that can actually deliver. A micro servo pulls an amp when stalled, and a servo holding position against a load is partly stalled all the time. Powering servos through the host's 5 V pin is the most common way to make an i2c bus drop out — the rail sags, the host browns out, and it looks exactly like a wiring fault.

Can I run LEDs and servos on the same PCA9685?

Not well. The frequency is global — one prescaler for all sixteen channels — so you'd be running LEDs at 50 Hz (visible flicker) or servos at a few hundred Hz (which damages them). Use two boards; they're cheap, and the address jumpers exist for exactly this.