Skip to content

Add setMultiplePWM() function #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion Adafruit_PWMServoDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#include "Adafruit_PWMServoDriver.h"

//#define ENABLE_DEBUG_OUTPUT
// #define ENABLE_DEBUG_OUTPUT

/*!
* @brief Instantiates a new PCA9685 PWM driver chip with the I2C address on a
Expand Down Expand Up @@ -361,6 +361,43 @@ void Adafruit_PWMServoDriver::setOscillatorFrequency(uint32_t freq) {
_oscillator_freq = freq;
}

/*!
* @brief Sets the PWM output for multiple channels
* @param values Array of PWM values (0-4095) for each channel
* @param length Length of the array, from 1 to 16
* @return 0 if successful, otherwise 1
*/
uint8_t Adafruit_PWMServoDriver::setMultiplePWM(uint16_t *values,
uint8_t length) {
if (length > 16)
length = 16;
uint8_t totalBytes = 1 + 4 * length;

uint8_t buffer[totalBytes];
buffer[0] = PCA9685_LED0_ON_L;
uint8_t *b = buffer + 1;

for (uint8_t i = 0; i < length; i++, b += 4) {
uint16_t val = values[i] > 4095 ? 4095 : values[i];
b[0] = 0;
if (val == 0) {
b[1] = 0;
b[2] = 0;
b[3] = MODE1_SLEEP;
} else if (val == 4095) {
b[1] = MODE1_SLEEP;
b[2] = 0;
b[3] = 0;
} else {
b[1] = 0;
b[2] = val & 0xFF;
b[3] = val >> 8;
}
}

return i2c_dev->write(buffer, totalBytes) ? 0 : 1;
}

/******************* Low level I2C interface */
uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
uint8_t buffer[1] = {addr};
Expand Down
1 change: 1 addition & 0 deletions Adafruit_PWMServoDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Adafruit_PWMServoDriver {
void setOutputMode(bool totempole);
uint16_t getPWM(uint8_t num, bool off = false);
uint8_t setPWM(uint8_t num, uint16_t on, uint16_t off);
uint8_t setMultiplePWM(uint16_t *values, uint8_t length);
void setPin(uint8_t num, uint16_t val, bool invert = false);
uint8_t readPrescale(void);
void writeMicroseconds(uint8_t num, uint16_t Microseconds);
Expand Down
8 changes: 5 additions & 3 deletions examples/pwmtest/pwmtest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ void setup() {

void loop() {
// Drive each PWM in a 'wave'
for (uint16_t i=0; i<4096; i += 8) {
for (uint8_t pwmnum=0; pwmnum < 16; pwmnum++) {
pwm.setPWM(pwmnum, 0, (i + (4096/16)*pwmnum) % 4096 );
uint16_t pwmValues[16];
for (uint16_t i = 0; i < 4096; i += 8) {
for (uint8_t pwmnum = 0; pwmnum < 16; pwmnum++) {
pwmValues[pwmnum] = (i + (4096 / 16) * pwmnum) % 4096;
}
pwm.setMultiplePWM(pwmValues, 16);
#ifdef ESP8266
yield(); // take a breather, required for ESP8266
#endif
Expand Down
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ setPWMFreq KEYWORD2
setOutputMode KEYWORD2
getPWM KEYWORD2
setPWM KEYWORD2
setMultiplePWM KEYWORD2
setPin KEYWORD2
readPrescale KEYWORD2
writeMicroseconds KEYWORD2
Expand Down