Skip to main content

Raw PWM control

What this example shows​

Setting a channel's raw on/off tick counts and ramping them over time. This is the board's basic building block: every higher-level call, including the servo angle helper on the next page, ends up calling setPWM().

The example code​

Select Board
Basic_PWM.ino
#include "PCA9685-SOLDERED.h"

PCA9685 pwm;

void setup()
{
pwm.begin();
pwm.setPWMFreq(1000); // fast PWM for LEDs/general outputs, not servos
}

void loop()
{
for (uint16_t duty = 0; duty <= 4095; duty += 32)
{
pwm.setPWM(0, 0, duty);
delay(20);
}
}

Expected result:

No serial output. Channel 0's duty cycle ramps from 0 to 4064 in steps of 32, taking a little over 2.5 seconds per ramp, then repeats.

Functions used​

PCA9685(uint8_t _address = PCA9685_DEFAULT_ADDRESS)returns None

Native constructor. The board's I2C address is fixed by the JP1-JP6 solder jumpers, so pass the address that matches how your board is set, or leave it at the default.

ReturnsConstructor; no return value.

Parameters

TypeNameDescription
uint8_t_addressI2C address of the board. Defaults to PCA9685_DEFAULT_ADDRESS (0x40).
begin()returns void

Initializes the PCA9685 over I2C at the address set in the constructor: wakes the oscillator, enables the ALLCALL address, and sets the default 50 Hz PWM frequency. Call it once in setup().

ReturnsNothing.

Parameters

This function takes no parameters.

setPWMFreq(float freq)returns void

Sets the PWM frequency shared by all 16 channels. Clamped to the chip's 24-1526 Hz range.

ReturnsNothing.

Parameters

TypeNameDescription
floatfreqDesired frequency in Hz, clamped to 24-1526 Hz.
setPWM(uint8_t channel, uint16_t on, uint16_t off)returns void

Sets the raw tick counts at which a channel's output turns on and off within one PWM period (4096 ticks). Used directly for LEDs and general PWM; setServoAngle() on the next page is a convenience wrapper around this same call.

ReturnsNothing.

Parameters

TypeNameDescription
uint8_tchannelChannel number, 0 to 15.
uint16_tonTick count (0-4095) at which the output turns on.
uint16_toffTick count (0-4095) at which the output turns off.

Putting it together​

begin() sets a 50 Hz default, but this example immediately raises it to 1000 Hz with setPWMFreq(), which suits an LED or general PWM load better than the 50 Hz hobby servos expect. setPWM() then places both edges of the pulse: with on fixed at 0, off alone controls the duty cycle, so ramping off from 0 to 4064 ramps the output from fully off to nearly fully on.

To hold a channel steady instead of ramping it, call setPWM() once with the tick values you want and stop calling it again; the PCA9685 keeps generating that signal on its own until you change it.