@@ -102,29 +102,38 @@ void Adafruit_PWMServoDriver::wakeup() {
102
102
}
103
103
104
104
/* !
105
- * @brief Sets EXTCLK pin to use the external clock
105
+ * @brief Sets prescaler for PWM output frequency
106
106
* @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
108
110
*/
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
113
118
114
119
// This sets both the SLEEP and EXTCLK bits of the MODE1 register to switch to
115
120
// use the external clock.
116
- write8 (PCA9685_MODE1, (newmode |= MODE1_EXTCLK));
121
+ if (extclk) { write8 (PCA9685_MODE1, (newmode1 |= MODE1_EXTCLK)); }
117
122
118
123
write8 (PCA9685_PRESCALE, prescale); // set the prescaler
119
124
120
125
delay (5 );
121
126
// 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
+ }
123
129
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 );
128
137
}
129
138
130
139
/* !
@@ -158,14 +167,7 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
158
167
Serial.println (prescale);
159
168
#endif
160
169
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);
169
171
170
172
#ifdef ENABLE_DEBUG_OUTPUT
171
173
Serial.print (" Mode now 0x" );
@@ -299,7 +301,7 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon
299
301
// Read prescale and convert to frequency
300
302
double prescale = Adafruit_PWMServoDriver::readPrescale ();
301
303
prescale += 1 ;
302
- uint32_t freq = 25000000 ; // Chip frequency is 25MHz
304
+ uint32_t freq = FREQUENCY_OSCILLATOR ; // Chip frequency is 25MHz
303
305
freq /= prescale;
304
306
freq /= 4096 ; // 12 bits of resolution
305
307
0 commit comments