The PCA9685 is an I²C-bus controlled 16-channel PWM controller with 12-bit (4096-step) duty-cycle resolution per output, a programmable output frequency of 24 Hz to 1526 Hz, a 2.3–5.5 V supply range, and 16 outputs that can each sink up to 25 mA. Its datasheet positions it as an LED controller optimized for RGBA color backlighting — RGB/RGBA LED drivers, LCD backlights, status LEDs, and keypad backlights — and its per-channel programmable phase shift is a feature it advertises specifically for avoiding current surges in large LED banks. In practice it has become one of the most popular hobbyist and industrial choices as an external PWM expander for servo and motor-driver applications, precisely because it takes PWM generation entirely off your MCU and puts 16 channels behind one I²C address. This post is about using it correctly in both roles, starting with the biggest misconception about the part.
The myth: "the PCA9685 is a servo driver" (or a motor driver)
Search "servo controller PCA9685" or "motor driver PCA9685" and you'll find the part described as exactly that. The datasheet says otherwise: NXP's own Applications section lists RGB/RGBA LED drivers, LED status information, LED displays, LCD backlights, and keypad backlights — and the general description calls it "an I²C-bus controlled 16-channel LED controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications." The truth is a useful nuance, not a contradiction:
- What it genuinely is: a 16-channel, 12-bit PWM generator with I²C control. It outputs logic-level PWM waveforms; it does not decode servo pulse positioning, and it does not switch motor current.
- Why it works for servos: a hobby servo is just a PWM consumer — it wants a repeating pulse (typically ~50 Hz refresh, ~1–2 ms width) on a logic-level pin. The PCA9685 produces exactly that at 4096-step resolution, so it drives servos directly from its LEDn pins with no external parts. That's why the "servo controller" usage works so well even though it's not the part's intended use case. Concretely, for a 50 Hz refresh you compute the prescaler from the datasheet's equation,
prescale = round(osc_clock/(4096 × update_rate)) − 1: with the internal 25 MHz oscillator,round(25e6/(4096 × 50)) − 1 = 121 = 0x79. Write 0x79 to PRE_SCALE (remember: only while SLEEP = 1), then set the pulse width via the LEDn_ON and LEDn_OFF registers — a 1–2 ms pulse within the 4096-step frame is an OFF count of roughly 0x0190–0x0320 after the ON point (e.g., LED_ON = 0, LED_OFF = 0x0190 for ~1 ms, 0x0320 for ~2 ms). - Why it works as a motor-driver interface: most H-bridge and DC motor driver ICs take a PWM input at logic level and do the power switching themselves. The PCA9685 sits in front of the driver as the PWM source. It is never the motor driver itself — its outputs are specified for 25 mA sink (10 mA source class at 5 V), nowhere near motor current.
- The real constraint that shapes both uses: all 16 outputs share one PWM frequency. Brightness/duty is per-channel, but refresh rate is global — you can't run some channels at 50 Hz for servos and others at 1 kHz for a backlight dimming scheme on the same chip.
So the honest framing: the PCA9685 is a PWM expander that happens to be an excellent servo and motor-driver-interface part, while being an LED controller by design. Keep that in mind and the rest of its spec sheet stops being surprising.
Wiring the PCA9685 into your design
Power. VDD operates from 2.3 V to 5.5 V; absolute maximum is −0.5 V to 6.0 V, so verify your rail never crosses 6 V even on transients. The part carries ~50 pF of on-chip decoupling, but the datasheet explicitly tells you to determine whether additional external decoupling is required and, if so, place it as close as physically possible to the device. It deliberately does not give a bypass capacitance value — that's your call based on how hard you switch the outputs.
I²C bus. The interface is Fast-mode Plus capable — 1 MHz, with 30 mA high drive on SDA for driving high-capacitance buses. The datasheet publishes no pull-up resistor value; it defers sizing to Section 7 of UM10204 (the I²C-bus specification), so pick pull-ups for your bus capacitance and speed. Two useful datasheet-backed facts: input filters on SDA and SCL suppress noise spikes under 50 ns (so don't double-filter), and the SDA/SCL fall-time budget (300 ns max fall time) explicitly allows small series protection resistors between the pins and the bus lines. Six hardware address pins span addresses 0x40–0x7F, letting up to 62 devices share one bus; there are no internal pull-ups on those pins, so they must be pulled HIGH or LOW externally. With all pins grounded the 7-bit address is 0x40.
OE pin. OE is active-low and needs a pull-up if your master's control signal is open-drain — without one, the pin floats and output behavior is undefined.
Outputs. At power-up the outputs default to totem-pole; open-drain is software-selected (OUTDRV in MODE2), and mixing configurations across channels is not allowed — all 16 are one mode. For direct LED drive, the datasheet's design-in section recommends the open-drain NMOS configuration to keep ISS and ground bounce in check — and it pairs that recommendation with the hard constraint that mixing of open-drain and totem-pole configurations across the 16 outputs is not possible. If you're interfacing to a motor driver or servo instead, totem-pole (the default) is what you want — the driver or servo input wants an actively driven logic signal, not an open-drain one.
Interfacing to servos and motor drivers specifically. The LEDn outputs sink up to 25 mA but source only weak logic levels (VOH with IOH = −10 mA is just 1.6 V at VDD = 2.3 V). Servo signal inputs and H-bridge PWM inputs are high-impedance logic inputs, so this doesn't matter — but it's why you can't source meaningful current from these pins, and it's the number one wiring mistake when people assume "16 channels" means "16 small loads." The LEDn pins are also only tolerant up to 5.5 V and sink up to 25 mA at 5 V; anything that needs higher voltage and/or higher current than that requires an external driver stage. Use the INVRT and OUTDRV bits in MODE2 to match your motor driver's PWM input polarity without changing firmware logic elsewhere — noting that INVRT only takes effect when OE = 0.
The numbers engineers misread
Three specs get people into trouble, and all three have the same root cause: the PCA9685's outputs are logic-level PWM pins with a modest drive budget, not power outputs.
- 25 mA per output, 400 mA total. Each LEDn output is limited to 25 mA absolute max, and the datasheet is explicit that the total package is limited to 400 mA "due to internal busing limits" (ISS max 400 mA, Ptot max 400 mW). Sixteen channels at 25 mA each is exactly 400 mA — there is zero headroom at full drive on all channels. Sum your worst-case currents across channels before committing to a design.
- Shared PWM frequency, 24–1526 Hz. Frequency is set by one prescaler:
prescale = round(osc_clock/(4096 × update_rate)) − 1, giving 24 Hz (PRE_SCALE = 0xFF) up to 1526 Hz (PRE_SCALE = 0x03). Per-channel ON/OFF compare points give you duty and phase at 1/4096 resolution, so staggering channel timing is free — but refresh rate is not per-channel. - PRE_SCALE writes only work in SLEEP. The prescaler can only be written while the SLEEP bit of MODE1 is set. Write it while awake and the change silently doesn't take — this looks exactly like a firmware bug and is really a datasheet rule.
Two more behavioral traps worth knowing: the EXTCLK bit is sticky and can only be cleared by a power cycle or software reset, and a "power cycle" means VDD actually dropping below 0.2 V — a brown-out that stays above 0.2 V does not reset the part. Also, the internal 25 MHz oscillator has no specified accuracy tolerance in the datasheet, so if you need a known PWM frequency (which servo timing arguably does), the datasheet-sanctioned path is feeding an external clock (DC–50 MHz) via EXTCLK.
Testing the PCA9685 on the bench
A workable bring-up sequence:
- Power sanity. With no load, operating supply current is on the order of 6 mA typ (10 mA max) with SCL at 1 MHz; far above that at idle flags a short or a floating input. Standby is ~2.2 µA typ (15.5 µA max) — a big excursion there means a pull-up or input is loading something.
- I²C link. Write and read back registers to confirm the bus. The part ACKs at its programmed address (0x40 with all address pins grounded). Note the built-in bus time-out: the serial interface resets if SDA or SCL is held LOW for a minimum of 25 ms — a stalled bus looks like a dead part until you account for this.
- Software reset as a known state. Issue the SWRST general call — send the General Call bus address 0000 0000b (0x00) with R/W = 0, then the SWRST data byte 06h as the second byte of the transaction; the datasheet says the result is identical to power-on reset and sets outputs LOW. Confirm all outputs go LOW and registers read back to defaults — a non-zero output before you've programmed anything means something else is driving it.
- PWM verification. Scope an output and confirm the period matches your prescaler setting. Step duty from 0 to 100% in 12-bit increments and confirm monotonic behavior. Verify outputs commit together on STOP (the default, OCH=0) when you burst-write all channels.
- Worst-case pattern. Run all 16 channels at full sink simultaneously while watching the VDD rail and ground. The datasheet flags ground bounce as a real possibility "especially if all 16 outputs are changed at full current (25 mA each)" — if you see rail collapse or spurious transitions, revisit decoupling placement and ground return before shipping. This is exactly why the per-channel phase-shift feature exists: staggering ON times across the 16 channels spreads the current surges instead of stacking them.
Troubleshooting the PCA9685
The failures that come up repeatedly, and their actual causes:
- Device doesn't respond on I²C. First, check whether SDA or SCL is being held LOW ≥ 25 ms — the internal bus time-out resets the interface and a hung bus is indistinguishable from a dead part. Second, confirm the part actually left reset: VDD must have reached VPOR (~1.7 V typ, 2.0 V max) on power-up, and if the rail browned out but never fell below 0.2 V, the part may be in an undefined state — fully re-power it. Third, check logic levels: VIH is 0.7·VDD, so a master that can't pull the bus to 0.7·VDD with your chosen pull-ups never establishes a valid HIGH.
- PWM frequency won't change. You wrote PRE_SCALE while SLEEP = 0. Set SLEEP first, write the prescaler, then clear SLEEP and allow ~500 µs for the oscillator to stabilize.
- Output stuck HIGH when it should be sinking. The outputs are strongest in sink; if you're sourcing through the load instead, the weak VOH will look like a stuck output. Check your polarity chain: INVRT only takes effect when OE = 0, and when OE = 1 the output state is controlled solely by the OUTNE[1:0] bits — a confused OE/OUTNE interaction is a classic cause of "the outputs do the opposite of what I wrote."
- Works alone, glitches with all channels active. This is the 400 mA aggregate limit plus ground bounce. Reduce per-channel drive, use the programmable per-channel ON/OFF phase shift to stagger switching, and put decoupling physically against the chip.
- Frequency is wrong but registers look right. Check your prescaler arithmetic for off-by-one errors (
− 1at the end), and if you ever enabled EXTCLK, remember it's sticky — only a full power cycle (below 0.2 V) or SWRST clears it, and until then the internal oscillator setting is irrelevant.
The two most commonly missed items in practice: the 25 ms bus time-out (masquerading as a dead device) and the PRE_SCALE-only-in-SLEEP rule (masquerading as a stuck frequency). Put both on your debug checklist before suspecting hardware.
Part page: PCA9685.