From ee0ef227dcf6830ae5c4a53ed7bb95f5b29d3aee Mon Sep 17 00:00:00 2001 From: andrethomas Date: Sun, 30 Sep 2018 23:07:46 +0200 Subject: [PATCH] Add ability to set default PWM Freq using #define #define USE_PCA9685_FREQ --- sonoff/user_config.h | 1 + sonoff/xdrv_15_pca9685.ino | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index eceadc68d..72aa97d53 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -302,6 +302,7 @@ // #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code) // #define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code) // #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup) +// #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz // #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) // #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) // #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) diff --git a/sonoff/xdrv_15_pca9685.ino b/sonoff/xdrv_15_pca9685.ino index e53b8d17f..c17ec3bee 100644 --- a/sonoff/xdrv_15_pca9685.ino +++ b/sonoff/xdrv_15_pca9685.ino @@ -27,7 +27,7 @@ #define PCA9685_REG_PRE_SCALE 0xFE uint8_t pca9685_detected = 0; -uint16_t pca9685_freq = 50; +uint16_t pca9685_freq = USE_PCA9685_FREQ; void PCA9685_Detect(void) { @@ -51,7 +51,7 @@ void PCA9685_Detect(void) void PCA9685_Reset(void) { I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, 0x80); - PCA9685_SetPWMfreq(50); + PCA9685_SetPWMfreq(USE_PCA9685_FREQ); for (uint8_t pin=0;pin<16;pin++) { PCA9685_SetPWM(pin,0,false); } @@ -63,9 +63,13 @@ void PCA9685_SetPWMfreq(double freq) { 7.3.5 from datasheet prescale value = round(25000000/(4096*freq))-1; */ - pca9685_freq=freq; - uint8_t pre_scale_osc = round(25000000/(4096*freq))-1; - if (1526 == freq) pre_scale_osc=0xFF; // force setting for 24hz because rounding causes 1526 to be 254 + if (freq > 23 && freq < 1527) { + pca9685_freq=freq; + } else { + pca9685_freq=50; + } + uint8_t pre_scale_osc = round(25000000/(4096*pca9685_freq))-1; + if (1526 == pca9685_freq) pre_scale_osc=0xFF; // force setting for 24hz because rounding causes 1526 to be 254 uint8_t current_mode1 = I2cRead8(USE_PCA9685_ADDR, PCA9685_REG_MODE1); // read current value of MODE1 register uint8_t sleep_mode1 = (current_mode1&0x7F) | 0x10; // Determine register value to put PCA to sleep I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, sleep_mode1); // Let's sleep a little