HF-PCA9685 Driver
Hardware-agnostic C++ driver for the NXP PCA9685 16-channel 12-bit PWM controller
š Table of Contents
- Overview
- Features
- Quick Start
- Installation
- API Reference
- Examples
- Documentation
- Contributing
- License
š¦ Overview
š šš Live Complete Documentation - Interactive guides, examples, and step-by-step tutorials
The PCA9685 is a 16-channel, 12-bit PWM controller from NXP Semiconductors that communicates via I²C. It provides independent PWM control for up to 16 outputs with 12-bit resolution (4096 steps), making it ideal for driving LEDs, servos, and other PWM-controlled devices. The chip features an internal 25 MHz oscillator, configurable PWM frequency from 24 Hz to 1526 Hz, and supports daisy-chaining multiple devices for up to 992 PWM outputs.
This driver provides a hardware-agnostic C++ interface that abstracts all register-level operations,
requiring only an implementation of the I2cInterface for your platform. The driver uses the CRTP
(Curiously Recurring Template Pattern) for zero-overhead hardware abstraction, making it suitable
for resource-constrained embedded systems.
⨠Features
- ā 16 Independent PWM Channels: Each with 12-bit resolution (0-4095)
- ā Configurable Frequency: 24 Hz to 1526 Hz (typical range)
- ā Hardware Agnostic: CRTP-based I2C interface for platform independence
- ā Modern C++: C++11 compatible with template-based design
- ā Zero Overhead: CRTP design for compile-time polymorphism
- ā
Error Reporting: Bitmask error flags (
uint16_t) viaGetErrorFlags()/ClearErrorFlags() - ā
Duty Cycle Control: High-level
SetDuty()method for easy 0.0-1.0 control - ā
Bulk Operations:
SetAllPwm()for simultaneous channel updates - ā
Power Management:
Sleep()/Wake()via MODE1 SLEEP bit - ā
Output Modes:
SetOutputInvert(),SetOutputDriverMode()(totem-pole/open-drain) - ā
Full ON/OFF:
SetChannelFullOn()/SetChannelFullOff()without PWM - ā
Retry Logic: Configurable I2C retry count via
SetRetries()
š Quick Start
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "pca9685.hpp"
// 1. Implement the I2C interface (see platform_integration.md)
class MyI2c : public pca9685::I2cInterface<MyI2c> {
public:
bool Write(uint8_t addr, uint8_t reg, const uint8_t *data, size_t len) noexcept;
bool Read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len) noexcept;
bool EnsureInitialized() noexcept;
};
// 2. Create driver instance
MyI2c i2c;
pca9685::PCA9685<MyI2c> pwm(&i2c, 0x40); // 0x40 is default I2C address
// 3. Initialize and use
pwm.Reset();
pwm.SetPwmFreq(50.0f); // 50 Hz for servos
pwm.SetDuty(0, 0.075f); // Channel 0, 7.5% duty (1.5ms pulse for servo)
For detailed setup, see Installation and Quick Start Guide.
š§ Installation
- Clone or copy the driver files into your project
- Implement the I2C interface for your platform (see Platform Integration)
- Include the header in your code:
1
#include "pca9685.hpp"
- Compile with a C++11 or newer compiler
For detailed installation instructions, see docs/installation.md.
š API Reference
| Method | Description |
|---|---|
Reset() |
Reset device to power-on default state |
SetPwmFreq(float freq_hz) |
Set PWM frequency (24-1526 Hz) |
SetPwm(uint8_t channel, uint16_t on, uint16_t off) |
Set PWM timing for a channel |
SetDuty(uint8_t channel, float duty) |
Set duty cycle (0.0-1.0) for a channel |
SetAllPwm(uint16_t on, uint16_t off) |
Set all channels simultaneously |
SetChannelFullOn(uint8_t channel) |
Set channel fully on (no PWM) |
SetChannelFullOff(uint8_t channel) |
Set channel fully off (no PWM) |
Sleep() / Wake() |
Power management via MODE1 SLEEP bit |
SetOutputInvert(bool invert) |
Set MODE2 INVRT bit |
SetOutputDriverMode(bool totem_pole) |
Set MODE2 OUTDRV bit (true=totem-pole, false=open-drain) |
SetRetries(int retries) |
Configure I2C retry count |
GetLastError() |
Get the last error code (convenience accessor) |
GetErrorFlags() |
Get all error flags as uint16_t bitmask |
ClearErrorFlags(uint16_t mask) |
Clear specific error flags |
GetPrescale(uint8_t &prescale) |
Get current prescale value |
For complete API documentation with source code links, see docs/api_reference.md.
š Examples
- ESP32: examples/esp32 ā two apps: pca9685_comprehensive_test (full driver test suite) and pca9685_servo_demo (16-channel hobby servo animations). See examples/esp32/README.md for build/flash and examples/esp32/docs/ for per-app documentation.
- Driver examples (code snippets, any platform): docs/examples.md.
š Documentation
For complete documentation, see the docs directory.
š¤ Contributing
Pull requests and suggestions are welcome! Please follow the existing code style and include tests for new features.
š License
This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.