From 3b7f4dcd8957a14d48a2379c4acaf3910d4fe1f7 Mon Sep 17 00:00:00 2001 From: Bolukan Date: Tue, 29 Oct 2019 15:15:41 +0100 Subject: [PATCH 1/7] Refactored setting prescale, add setPrescale --- Adafruit_PWMServoDriver.cpp | 44 +++++++++++++++++++----------------- Adafruit_PWMServoDriver.h | 1 + examples/pwmtest/pwmtest.ino | 2 ++ 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index 4c614fe..b9833bb 100755 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -102,29 +102,38 @@ void Adafruit_PWMServoDriver::wakeup() { } /*! - * @brief Sets EXTCLK pin to use the external clock + * @brief Sets prescaler for PWM output frequency * @param prescale - * Configures the prescale value to be used by the external clock + * Defines the frequency at which the outputs modulate + * @param extclk + * Sets EXTCLK pin to use the external clock */ -void Adafruit_PWMServoDriver::setExtClk(uint8_t prescale) { - uint8_t oldmode = read8(PCA9685_MODE1); - uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep - write8(PCA9685_MODE1, newmode); // go to sleep, turn off internal oscillator +void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale, bool extclk /* = false */) { + if (prescale < PCA9685_PRESCALE_MIN) return; + // if (prescale > PCA9685_PRESCALE_MAX) return; + + uint8_t newmode1 = read8(PCA9685_MODE1); + newmode1 = (newmode1 & ~MODE1_RESTART) | MODE1_SLEEP; // sleep + write8(PCA9685_MODE1, newmode1); // go to sleep, turn off internal oscillator // This sets both the SLEEP and EXTCLK bits of the MODE1 register to switch to // use the external clock. - write8(PCA9685_MODE1, (newmode |= MODE1_EXTCLK)); + if (extclk) { write8(PCA9685_MODE1, (newmode1 |= MODE1_EXTCLK)); } write8(PCA9685_PRESCALE, prescale); // set the prescaler delay(5); // clear the SLEEP bit to start - write8(PCA9685_MODE1, (newmode & ~MODE1_SLEEP) | MODE1_RESTART | MODE1_AI); + write8(PCA9685_MODE1, (newmode1 & ~MODE1_SLEEP) | MODE1_RESTART | MODE1_AI); +} -#ifdef ENABLE_DEBUG_OUTPUT - Serial.print("Mode now 0x"); - Serial.println(read8(PCA9685_MODE1), HEX); -#endif +/*! + * @brief Sets EXTCLK pin to use the external clock + * @param prescale + * Configures the prescale value to be used by the external clock + */ +void Adafruit_PWMServoDriver::setExtClk(uint8_t prescale) { + setPrescale(prescale, true); } /*! @@ -158,14 +167,7 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) { Serial.println(prescale); #endif - uint8_t oldmode = read8(PCA9685_MODE1); - uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep - write8(PCA9685_MODE1, newmode); // go to sleep - write8(PCA9685_PRESCALE, prescale); // set the prescaler - write8(PCA9685_MODE1, oldmode); - delay(5); - // This sets the MODE1 register to turn on auto increment. - write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI); + setPrescale(prescale); #ifdef ENABLE_DEBUG_OUTPUT Serial.print("Mode now 0x"); @@ -299,7 +301,7 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon // Read prescale and convert to frequency double prescale = Adafruit_PWMServoDriver::readPrescale(); prescale += 1; - uint32_t freq = 25000000; // Chip frequency is 25MHz + uint32_t freq = FREQUENCY_OSCILLATOR; // Chip frequency is 25MHz freq /= prescale; freq /= 4096; // 12 bits of resolution diff --git a/Adafruit_PWMServoDriver.h b/Adafruit_PWMServoDriver.h index 0fecb28..1880f74 100644 --- a/Adafruit_PWMServoDriver.h +++ b/Adafruit_PWMServoDriver.h @@ -81,6 +81,7 @@ class Adafruit_PWMServoDriver { void reset(); void sleep(); void wakeup(); + void setPrescale(uint8_t prescale, bool extclk=false); void setExtClk(uint8_t prescale); void setPWMFreq(float freq); void setOutputMode(bool totempole); diff --git a/examples/pwmtest/pwmtest.ino b/examples/pwmtest/pwmtest.ino index be9e79c..4bb9a2d 100644 --- a/examples/pwmtest/pwmtest.ino +++ b/examples/pwmtest/pwmtest.ino @@ -32,6 +32,8 @@ void setup() { pwm.begin(); pwm.setPWMFreq(1600); // This is the maximum PWM frequency + // or as alternative set the prescale manual: freq = oscillator-Hz / 4096*(prescale+1) + pwm.setPrescale(0x1e); // PCA9685 sets itself default to 0x1e, approx 200Hz // if you want to really speed stuff up, you can go into 'fast 400khz I2C' mode // some i2c devices dont like this so much so if you're sharing the bus, watch From f0f9a07a36f7a5e539ae4d4116e95c95d95f2771 Mon Sep 17 00:00:00 2001 From: Bolukan Date: Tue, 29 Oct 2019 18:11:46 +0100 Subject: [PATCH 2/7] On request --- Adafruit_PWMServoDriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index b9833bb..37d6c09 100755 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -301,7 +301,7 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon // Read prescale and convert to frequency double prescale = Adafruit_PWMServoDriver::readPrescale(); prescale += 1; - uint32_t freq = FREQUENCY_OSCILLATOR; // Chip frequency is 25MHz + uint32_t freq = 25000000; // Chip frequency is 25MHz freq /= prescale; freq /= 4096; // 12 bits of resolution From bb7c39a9e070afdff3e5ebbdaf388e51e1f8395f Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Nov 2019 21:09:47 +0100 Subject: [PATCH 3/7] Comply to current master branche --- Adafruit_PWMServoDriver.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index 37d6c09..da71b41 100755 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -167,7 +167,14 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) { Serial.println(prescale); #endif - setPrescale(prescale); + uint8_t oldmode = read8(PCA9685_MODE1); + uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep + write8(PCA9685_MODE1, newmode); // go to sleep + write8(PCA9685_PRESCALE, prescale); // set the prescaler + write8(PCA9685_MODE1, oldmode); + delay(5); + // This sets the MODE1 register to turn on auto increment. + write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI); #ifdef ENABLE_DEBUG_OUTPUT Serial.print("Mode now 0x"); From 601d76e1b16446155e7091ea2b5700ee9fb281da Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Nov 2019 21:12:17 +0100 Subject: [PATCH 4/7] use setPrescale function --- Adafruit_PWMServoDriver.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index 38b95e1..a6a33ed 100755 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -165,14 +165,7 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) { Serial.println(prescale); #endif - uint8_t oldmode = read8(PCA9685_MODE1); - uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep - write8(PCA9685_MODE1, newmode); // go to sleep - write8(PCA9685_PRESCALE, prescale); // set the prescaler - write8(PCA9685_MODE1, oldmode); - delay(5); - // This sets the MODE1 register to turn on auto increment. - write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI); + setPrescale(prescale); #ifdef ENABLE_DEBUG_OUTPUT Serial.print("Mode now 0x"); From ef929a145819fbfce6fa1a9760ee468b197e5e2a Mon Sep 17 00:00:00 2001 From: Bolukan Date: Mon, 4 Nov 2019 18:28:01 +0100 Subject: [PATCH 5/7] Update keywords.txt --- keywords.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/keywords.txt b/keywords.txt index 3e9ccc3..5dba8cf 100644 --- a/keywords.txt +++ b/keywords.txt @@ -12,6 +12,7 @@ begin KEYWORD2 reset KEYWORD2 sleep KEYWORD2 wakeup KEYWORD2 +setPrescale KEYWORD2 setExtClk KEYWORD2 setPWMFreq KEYWORD2 setOutputMode KEYWORD2 @@ -20,7 +21,10 @@ setPWM KEYWORD2 setPin KEYWORD2 readPrescale KEYWORD2 writeMicroseconds KEYWORD2 +setOscillatorFrequency KEYWORD2 +getOscillatorFrequency KEYWORD2 ####################################### # Constants (LITERAL1) ####################################### +FREQUENCY_OSCILLATOR LITERAL1 \ No newline at end of file From c5823936b1fbc962489296f4bb0586e30f751972 Mon Sep 17 00:00:00 2001 From: Bolukan Date: Mon, 4 Nov 2019 18:34:22 +0100 Subject: [PATCH 6/7] Commenting out line in example --- examples/pwmtest/pwmtest.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pwmtest/pwmtest.ino b/examples/pwmtest/pwmtest.ino index 8ebc384..09af7b4 100644 --- a/examples/pwmtest/pwmtest.ino +++ b/examples/pwmtest/pwmtest.ino @@ -37,7 +37,7 @@ void setup() { pwm.setOscillatorFrequency(27000000); // The int.osc. is closer to 27MHz pwm.setPWMFreq(1600); // This is the maximum PWM frequency // or as alternative set the prescale manual: freq = oscillator-Hz / 4096*(prescale+1) - pwm.setPrescale(0x1e); // PCA9685 sets itself default to 0x1e, approx 200Hz + // pwm.setPrescale(0x1e); // PCA9685 sets itself default to 0x1e, approx 200Hz // if you want to really speed stuff up, you can go into 'fast 400khz I2C' mode // some i2c devices dont like this so much so if you're sharing the bus, watch From e2a7586f39515f03c36a7ef7082d10133a85ba9d Mon Sep 17 00:00:00 2001 From: Bolukan Date: Mon, 4 Nov 2019 19:14:13 +0100 Subject: [PATCH 7/7] formatting --- Adafruit_PWMServoDriver.cpp | 9 ++++++--- Adafruit_PWMServoDriver.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Adafruit_PWMServoDriver.cpp b/Adafruit_PWMServoDriver.cpp index a6a33ed..0c74e51 100755 --- a/Adafruit_PWMServoDriver.cpp +++ b/Adafruit_PWMServoDriver.cpp @@ -110,8 +110,9 @@ void Adafruit_PWMServoDriver::wakeup() { * @param extclk * Sets EXTCLK pin to use the external clock */ -void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale, bool extclk /* = false */) { - if (prescale < PCA9685_PRESCALE_MIN) return; +void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale, bool extclk) { + if (prescale < PCA9685_PRESCALE_MIN) + return; // if (prescale > PCA9685_PRESCALE_MAX) return; uint8_t newmode1 = read8(PCA9685_MODE1); @@ -120,7 +121,9 @@ void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale, bool extclk /* = fal // This sets both the SLEEP and EXTCLK bits of the MODE1 register to switch to // use the external clock. - if (extclk) { write8(PCA9685_MODE1, (newmode1 |= MODE1_EXTCLK)); } + if (extclk) { + write8(PCA9685_MODE1, (newmode1 |= MODE1_EXTCLK)); + } write8(PCA9685_PRESCALE, prescale); // set the prescaler diff --git a/Adafruit_PWMServoDriver.h b/Adafruit_PWMServoDriver.h index f9680d5..92705ca 100644 --- a/Adafruit_PWMServoDriver.h +++ b/Adafruit_PWMServoDriver.h @@ -81,7 +81,7 @@ class Adafruit_PWMServoDriver { void reset(); void sleep(); void wakeup(); - void setPrescale(uint8_t prescale, bool extclk=false); + void setPrescale(uint8_t prescale, bool extclk = false); void setExtClk(uint8_t prescale); void setPWMFreq(float freq); void setOutputMode(bool totempole);