Skip to content

Commit d1f63cc

Browse files
committed
add set/get oscillator functions
1 parent 33ec0da commit d1f63cc

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

Adafruit_PWMServoDriver.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "Adafruit_PWMServoDriver.h"
3131
#include <Wire.h>
3232

33+
//#define ENABLE_DEBUG_OUTPUT
34+
3335
/*!
3436
* @brief Instantiates a new PCA9685 PWM driver chip with the I2C address on a
3537
* TwoWire interface
@@ -72,6 +74,8 @@ void Adafruit_PWMServoDriver::begin(uint8_t prescale) {
7274
// set a default frequency
7375
setPWMFreq(1000);
7476
}
77+
// set the default internal frequency
78+
setOscillatorFrequency(FREQUENCY_OSCILLATOR);
7579
}
7680

7781
/*!
@@ -139,16 +143,9 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
139143
// Range output modulation frequency is dependant on oscillator
140144
if (freq < 1) freq = 1;
141145
if (freq > 3500) freq = 3500; // Datasheet limit is 3052=50MHz/(4*4096)
142-
/*
143-
freq *= 0.9; // Correct for overshoot in the frequency setting (see issue #11)
144-
float prescaleval = FREQUENCY_OSCILLATOR;
145-
*/
146-
uint32_t prescaleval = FREQUENCY_CALIBRATED;
147-
prescaleval /= freq; // required output modulation frequency
148-
// rounding to nearest number is equal to adding 0,5 and floor to nearest number
149-
prescaleval += 2048;
150-
prescaleval /= 4096;
151-
prescaleval -= 1;
146+
147+
148+
float prescaleval = ((_oscillator_freq / (freq * 4096.0)) + 0.5) - 1;
152149
if (prescaleval < PCA9685_PRESCALE_MIN) prescaleval = PCA9685_PRESCALE_MIN;
153150
if (prescaleval > PCA9685_PRESCALE_MAX) prescaleval = PCA9685_PRESCALE_MAX;
154151
uint8_t prescale = (uint8_t) prescaleval;
@@ -306,7 +303,7 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon
306303
// Calculate the pulse for PWM based on Equation 1 from the datasheet section 7.3.5
307304
prescale += 1;
308305
pulselength *= prescale;
309-
pulselength /= FREQUENCY_CALIBRATED;
306+
pulselength /= _oscillator_freq;
310307

311308
#ifdef ENABLE_DEBUG_OUTPUT
312309
Serial.print(pulselength); Serial.println(" us per bit");
@@ -321,6 +318,15 @@ void Adafruit_PWMServoDriver::writeMicroseconds(uint8_t num, uint16_t Microsecon
321318
Adafruit_PWMServoDriver::setPWM(num, 0, pulse);
322319
}
323320

321+
uint32_t Adafruit_PWMServoDriver::getOscillatorFrequency(void) {
322+
return _oscillator_freq;
323+
}
324+
325+
void Adafruit_PWMServoDriver::setOscillatorFrequency(uint32_t freq) {
326+
_oscillator_freq = freq;
327+
}
328+
329+
/******************* Low level I2C interface */
324330
uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
325331
_i2c->beginTransmission(_i2caddr);
326332
_i2c->write(addr);

Adafruit_PWMServoDriver.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,7 @@
6161
#define MODE2_INVRT 0x10 /**< Output logic state inverted */
6262

6363
#define PCA9685_I2C_ADDRESS 0x40 /**< Default PCA9685 I2C Slave Address */
64-
65-
#define FREQUENCY_OSCILLATOR 25000000 /**< Oscillator frequency cf satasheet */
66-
#define FREQUENCY_CALIBRATED 26075000 /**< Oscillator frequency measured at 104.3% */
67-
#define FREQUENCY_LEGACY 27777778 /**< Oscillator frequency using freq /= 0,9 */
64+
#define FREQUENCY_OSCILLATOR 25000000 /**< Oscillator frequency in datasheet */
6865

6966
#define PCA9685_PRESCALE_MIN 3 /**< minimum prescale value */
7067
#define PCA9685_PRESCALE_MAX 255 /**< maximum prescale value */
@@ -90,10 +87,14 @@ class Adafruit_PWMServoDriver {
9087
uint8_t readPrescale(void);
9188
void writeMicroseconds(uint8_t num, uint16_t Microseconds);
9289

90+
void setOscillatorFrequency(uint32_t freq);
91+
uint32_t getOscillatorFrequency(void);
92+
9393
private:
9494
uint8_t _i2caddr;
9595
TwoWire* _i2c;
9696

97+
uint32_t _oscillator_freq;
9798
uint8_t read8(uint8_t addr);
9899
void write8(uint8_t addr, uint8_t d);
99100
};

0 commit comments

Comments
 (0)