HF-PCA9685 0.1.0-dev
Loading...
Searching...
No Matches
HF-PCA9685 Driver

Hardware-agnostic C++ driver for the NXP PCA9685 16-channel 12-bit PWM controller

C++ License CI Docs

šŸ“š Table of Contents

  1. Overview
  2. Features
  3. Quick Start
  4. Installation
  5. API Reference
  6. Examples
  7. Documentation
  8. Contributing
  9. 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) via GetErrorFlags() / 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

#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

  1. Clone or copy the driver files into your project
  2. Implement the I2C interface for your platform (see Platform Integration)
  3. Include the header in your code:
    #include "pca9685.hpp"
  4. 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](LICENSE) file for details.