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

This guide helps you diagnose and resolve common issues when using the PCA9685 driver.

Common Error Messages

Error: Initialization Fails (Reset() returns false)

Symptoms:

  • Reset() returns false
  • GetLastError() returns I2cWrite (or GetErrorFlags() has I2cWrite bit set)

Causes:

  • I2C bus not initialized
  • Wrong I2C address
  • Hardware connections incorrect
  • Pull-up resistors missing

Solutions:

  1. Verify I2C bus initialization:
    // Ensure I2C is initialized before creating driver.
    // ESP32: use driver/i2c_master.h (e.g. i2c_new_master_bus) as in
    // examples/esp32/main/esp32_pca9685_bus.hpp — or your platform's I2C init.
  2. Check I2C address:
    • Default is 0x40 (all A0-A5 pins to GND)
    • Use I2C scanner to verify device address
    • Update address in constructor if different
  3. Verify hardware connections:
    • Check SDA/SCL connections
    • Verify 4.7kΩ pull-up resistors on SDA and SCL
    • Ensure power (3.3V or 5V) is connected
  4. Test I2C interface:
    • Verify your I2C interface implementation works with other devices
    • Check I2C bus speed (try 100 kHz if 400 kHz fails)

Error: Channel Out of Range

Symptoms:

  • SetPwm() or SetDuty() returns false
  • GetLastError() returns OutOfRange (or GetErrorFlags() has OutOfRange bit set)

Causes:

  • Channel number >= 16
  • PWM values > 4095

Solutions:

// Validate channel number
if (channel < 16) {
pwm.SetDuty(channel, 0.5f);
}
// Validate PWM values
if (on_time <= 4095 && off_time <= 4095) {
pwm.SetPwm(channel, on_time, off_time);
}

Hardware Issues

Device Not Detected

Symptoms:

  • Initialization fails
  • No response from device
  • I2C scanner doesn't find device

Checklist:

  • [ ] Verify power supply voltage (2.3V-5.5V)
  • [ ] Check all connections are secure
  • [ ] Verify pull-up resistors (4.7kΩ) on SCL and SDA
  • [ ] Check I2C address configuration (A0-A5 pins)
  • [ ] Use I2C scanner to detect device address
  • [ ] Verify ground connection
  • [ ] Check for short circuits

Debugging:

  • Use oscilloscope/logic analyzer to verify I2C bus activity
  • Check for proper I2C start/stop conditions
  • Verify ACK/NACK responses

No Output on Channels

Symptoms:

  • Driver initializes successfully
  • No PWM output on channels
  • Servos/LEDs don't respond

Checklist:

  • [ ] Did you call SetPwmFreq() before setting channels?
  • [ ] Are channel values within valid range (0-4095)?
  • [ ] Is OE pin pulled LOW (or floating)? (OE HIGH disables outputs)
  • [ ] Are outputs connected correctly?
  • [ ] Check with oscilloscope/multimeter for PWM signal

Solutions:

// Correct sequence
pwm.Reset(); // 1. Initialize
pwm.SetPwmFreq(50.0f); // 2. Set frequency (REQUIRED!)
pwm.SetDuty(0, 0.5f); // 3. Now set channels

Runtime Errors

Initialization Fails

Checklist:

  • [ ] I2C bus is properly initialized
  • [ ] Hardware connections are correct
  • [ ] I2C address matches hardware configuration
  • [ ] Pull-up resistors are present

Unexpected Behavior

Checklist:

  • [ ] Frequency is set before setting channels
  • [ ] Channel numbers are 0-15
  • [ ] Duty cycle values are 0.0-1.0
  • [ ] PWM values are 0-4095
  • [ ] Error handling code checks return values

FAQ

Q: Why do I need to call SetPwmFreq() before setting channels?

A: The PCA9685 requires the prescale register to be set before PWM outputs work correctly. The driver enforces this by checking initialization state. Always call Reset() then SetPwmFreq() before setting channels.

Q: Can I change frequency after setting channels?

A: Yes, but it will affect all channels. Changing frequency updates the prescale register, which changes the PWM period for all 16 channels simultaneously.

Q: What's the difference between SetPwm() and SetDuty()?

A:

  • SetPwm() gives you precise control over on/off timing (0-4095 ticks each)
  • SetDuty() is a convenience method that sets duty cycle as a float (0.0-1.0), automatically calculating the off_time

Q: Can I use multiple PCA9685 devices?

A: Yes! Configure different I2C addresses via A0-A5 pins, then create separate driver instances:

pca9685::PCA9685<MyI2c> pwm1(&i2c, 0x40); // First device
pca9685::PCA9685<MyI2c> pwm2(&i2c, 0x41); // Second device

Q: Why are my servos not moving?

A: Common causes:

  1. Frequency not set (must call SetPwmFreq(50.0f) first)
  2. Duty cycle out of servo range (try 0.05-0.10)
  3. Servo power supply insufficient
  4. OE pin pulled HIGH (disables outputs)

Q: How do I control the OE (Output Enable) pin?

A: The driver doesn't control OE. You must control it via your platform's GPIO:

// Example: ESP32
gpio_set_direction(OE_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(OE_PIN, 0); // Enable outputs

Navigation ⬅️ Examples | Back to Index