diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index 71d6e5f..6aaece4 100644 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -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 @@ -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}; diff --git a/Adafruit_PWMServoDriver.h b/Adafruit_PWMServoDriver.h index be93f59..14bb10c 100644 --- a/Adafruit_PWMServoDriver.h +++ b/Adafruit_PWMServoDriver.h @@ -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); diff --git a/examples/pwmtest/pwmtest.ino b/examples/pwmtest/pwmtest.ino index 958e554..4241aca 100644 --- a/examples/pwmtest/pwmtest.ino +++ b/examples/pwmtest/pwmtest.ino @@ -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 diff --git a/keywords.txt b/keywords.txt index 2831dae..9588108 100644 --- a/keywords.txt +++ b/keywords.txt @@ -17,6 +17,7 @@ setPWMFreq KEYWORD2 setOutputMode KEYWORD2 getPWM KEYWORD2 setPWM KEYWORD2 +setMultiplePWM KEYWORD2 setPin KEYWORD2 readPrescale KEYWORD2 writeMicroseconds KEYWORD2