Skip to content

Commit 3b7f4dc

Browse files
committed
Refactored setting prescale, add setPrescale
1 parent 95ee436 commit 3b7f4dc

File tree

3 files changed

+26
-21
lines changed

3 files changed

+26
-21
lines changed

Adafruit_PWMServoDriver.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -102,29 +102,38 @@ void Adafruit_PWMServoDriver::wakeup() {
102102
}
103103

104104
/*!
105-
* @brief Sets EXTCLK pin to use the external clock
105+
* @brief Sets prescaler for PWM output frequency
106106
* @param prescale
107-
* Configures the prescale value to be used by the external clock
107+
* Defines the frequency at which the outputs modulate
108+
* @param extclk
109+
* Sets EXTCLK pin to use the external clock
108110
*/
109-
void Adafruit_PWMServoDriver::setExtClk(uint8_t prescale) {
110-
uint8_t oldmode = read8(PCA9685_MODE1);
111-
uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep
112-
write8(PCA9685_MODE1, newmode); // go to sleep, turn off internal oscillator
111+
void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale, bool extclk /* = false */) {
112+
if (prescale < PCA9685_PRESCALE_MIN) return;
113+
// if (prescale > PCA9685_PRESCALE_MAX) return;
114+
115+
uint8_t newmode1 = read8(PCA9685_MODE1);
116+
newmode1 = (newmode1 & ~MODE1_RESTART) | MODE1_SLEEP; // sleep
117+
write8(PCA9685_MODE1, newmode1); // go to sleep, turn off internal oscillator
113118

114119
// This sets both the SLEEP and EXTCLK bits of the MODE1 register to switch to
115120
// use the external clock.
116-
write8(PCA9685_MODE1, (newmode |= MODE1_EXTCLK));
121+
if (extclk) { write8(PCA9685_MODE1, (newmode1 |= MODE1_EXTCLK)); }
117122

118123
write8(PCA9685_PRESCALE, prescale); // set the prescaler
119124

120125
delay(5);
121126
// clear the SLEEP bit to start
122-
write8(PCA9685_MODE1, (newmode & ~MODE1_SLEEP) | MODE1_RESTART | MODE1_AI);
127+
write8(PCA9685_MODE1, (newmode1 & ~MODE1_SLEEP) | MODE1_RESTART | MODE1_AI);
128+
}
123129

124-
#ifdef ENABLE_DEBUG_OUTPUT
125-
Serial.print("Mode now 0x");
126-
Serial.println(read8(PCA9685_MODE1), HEX);
127-
#endif
130+
/*!
131+
* @brief Sets EXTCLK pin to use the external clock
132+
* @param prescale
133+
* Configures the prescale value to be used by the external clock
134+
*/
135+
void Adafruit_PWMServoDriver::setExtClk(uint8_t prescale) {
136+
setPrescale(prescale, true);
128137
}
129138

130139
/*!
@@ -158,14 +167,7 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
158167
Serial.println(prescale);
159168
#endif
160169

161-
uint8_t oldmode = read8(PCA9685_MODE1);
162-
uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep
163-
write8(PCA9685_MODE1, newmode); // go to sleep
164-
write8(PCA9685_PRESCALE, prescale); // set the prescaler
165-
write8(PCA9685_MODE1, oldmode);
166-
delay(5);
167-
// This sets the MODE1 register to turn on auto increment.
168-
write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI);
170+
setPrescale(prescale);
169171

170172
#ifdef ENABLE_DEBUG_OUTPUT
171173
Serial.print("Mode now 0x");
@@ -299,7 +301,7 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon
299301
// Read prescale and convert to frequency
300302
double prescale = Adafruit_PWMServoDriver::readPrescale();
301303
prescale += 1;
302-
uint32_t freq = 25000000; // Chip frequency is 25MHz
304+
uint32_t freq = FREQUENCY_OSCILLATOR; // Chip frequency is 25MHz
303305
freq /= prescale;
304306
freq /= 4096; // 12 bits of resolution
305307

Adafruit_PWMServoDriver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Adafruit_PWMServoDriver {
8181
void reset();
8282
void sleep();
8383
void wakeup();
84+
void setPrescale(uint8_t prescale, bool extclk=false);
8485
void setExtClk(uint8_t prescale);
8586
void setPWMFreq(float freq);
8687
void setOutputMode(bool totempole);

examples/pwmtest/pwmtest.ino

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ void setup() {
3232

3333
pwm.begin();
3434
pwm.setPWMFreq(1600); // This is the maximum PWM frequency
35+
// or as alternative set the prescale manual: freq = oscillator-Hz / 4096*(prescale+1)
36+
pwm.setPrescale(0x1e); // PCA9685 sets itself default to 0x1e, approx 200Hz
3537

3638
// if you want to really speed stuff up, you can go into 'fast 400khz I2C' mode
3739
// some i2c devices dont like this so much so if you're sharing the bus, watch

0 commit comments

Comments
 (0)