Skip to content

Commit 9dd0d3c

Browse files
committed
Defined magic numbers in header file.
MODE2 does not contain RESTART bit (removed &0x7F operation)
1 parent fbe4894 commit 9dd0d3c

File tree

2 files changed

+61
-39
lines changed

2 files changed

+61
-39
lines changed

Adafruit_PWMServoDriver.cpp

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t addr, TwoWire *i2c) {
4646
* @brief Setups the I2C interface and hardware
4747
* @param prescale
4848
* Sets External Clock (Optional)
49-
*
5049
*/
5150
void Adafruit_PWMServoDriver::begin(uint8_t prescale) {
5251
_i2c->begin();
@@ -63,7 +62,7 @@ void Adafruit_PWMServoDriver::begin(uint8_t prescale) {
6362
* @brief Sends a reset command to the PCA9685 chip over I2C
6463
*/
6564
void Adafruit_PWMServoDriver::reset() {
66-
write8(PCA9685_MODE1, 0x80);
65+
write8(PCA9685_MODE1, MODE1_RESTART);
6766
delay(10);
6867
}
6968

@@ -72,7 +71,7 @@ void Adafruit_PWMServoDriver::reset() {
7271
*/
7372
void Adafruit_PWMServoDriver::sleep() {
7473
uint8_t awake = read8(PCA9685_MODE1);
75-
uint8_t sleep = awake | 0x10; // set sleep bit high
74+
uint8_t sleep = awake | MODE1_SLEEP; // set sleep bit high
7675
write8(PCA9685_MODE1, sleep);
7776
delay(5); // wait until cycle ends for sleep to be active
7877
}
@@ -82,31 +81,29 @@ void Adafruit_PWMServoDriver::sleep() {
8281
*/
8382
void Adafruit_PWMServoDriver::wakeup() {
8483
uint8_t sleep = read8(PCA9685_MODE1);
85-
uint8_t wakeup = sleep & ~0x10; // set sleep bit low
84+
uint8_t wakeup = sleep & ~MODE1_SLEEP; // set sleep bit low
8685
write8(PCA9685_MODE1, wakeup);
8786
}
8887

89-
/**************************************************************************/
9088
/*!
91-
@brief Sets EXTCLK pin to use the external clock
92-
@param prescale Configures the prescale value to be used by the external
93-
clock
94-
*/
95-
/**************************************************************************/
89+
* @brief Sets EXTCLK pin to use the external clock
90+
* @param prescale
91+
* Configures the prescale value to be used by the external clock
92+
*/
9693
void Adafruit_PWMServoDriver::setExtClk(uint8_t prescale) {
9794
uint8_t oldmode = read8(PCA9685_MODE1);
98-
uint8_t newmode = (oldmode & 0x7F) | 0x10; // sleep
95+
uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep
9996
write8(PCA9685_MODE1, newmode); // go to sleep, turn off internal oscillator
10097

10198
// This sets both the SLEEP and EXTCLK bits of the MODE1 register to switch to
10299
// use the external clock.
103-
write8(PCA9685_MODE1, (newmode |= 0x40));
100+
write8(PCA9685_MODE1, (newmode |= MODE1_EXTCLK));
104101

105102
write8(PCA9685_PRESCALE, prescale); // set the prescaler
106103

107104
delay(5);
108-
write8(PCA9685_MODE1,
109-
(newmode & ~(0x10)) | 0xa0); // clear the SLEEP bit to start
105+
// clear the SLEEP bit to start
106+
write8(PCA9685_MODE1, (newmode & ~MODE1_SLEEP) | MODE1_RESTART | MODE1_AI);
110107

111108
#ifdef ENABLE_DEBUG_OUTPUT
112109
Serial.print("Mode now 0x");
@@ -124,8 +121,7 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
124121
Serial.println(freq);
125122
#endif
126123

127-
freq *=
128-
0.9; // Correct for overshoot in the frequency setting (see issue #11).
124+
freq *= 0.9; // Correct for overshoot in the frequency setting (see issue #11).
129125
float prescaleval = 25000000;
130126
prescaleval /= 4096;
131127
prescaleval /= freq;
@@ -143,14 +139,13 @@ void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
143139
#endif
144140

145141
uint8_t oldmode = read8(PCA9685_MODE1);
146-
uint8_t newmode = (oldmode & 0x7F) | 0x10; // sleep
142+
uint8_t newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP; // sleep
147143
write8(PCA9685_MODE1, newmode); // go to sleep
148144
write8(PCA9685_PRESCALE, prescale); // set the prescaler
149145
write8(PCA9685_MODE1, oldmode);
150146
delay(5);
151-
write8(PCA9685_MODE1,
152-
oldmode |
153-
0xa0); // This sets the MODE1 register to turn on auto increment.
147+
// This sets the MODE1 register to turn on auto increment.
148+
write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI);
154149

155150
#ifdef ENABLE_DEBUG_OUTPUT
156151
Serial.print("Mode now 0x");
@@ -169,10 +164,10 @@ void Adafruit_PWMServoDriver::setOutputMode(bool totempole) {
169164
uint8_t oldmode = read8(PCA9685_MODE2);
170165
uint8_t newmode;
171166
if (totempole) {
172-
newmode = (oldmode&0x7F) | 0x04;
167+
newmode = oldmode | MODE2_OUTDRV;
173168
}
174169
else {
175-
newmode = (oldmode&0x7F) & ~0x04;
170+
newmode = oldmode & ~MODE2_OUTDRV;
176171
}
177172
write8(PCA9685_MODE2, newmode);
178173
#ifdef ENABLE_DEBUG_OUTPUT
@@ -189,7 +184,7 @@ void Adafruit_PWMServoDriver::setOutputMode(bool totempole) {
189184
* @return requested PWM output value
190185
*/
191186
uint8_t Adafruit_PWMServoDriver::getPWM(uint8_t num) {
192-
_i2c->requestFrom((int)_i2caddr, LED0_ON_L + 4 * num, (int)4);
187+
_i2c->requestFrom((int)_i2caddr, PCA9685_LED0_ON_L + 4 * num, (int)4);
193188
return _i2c->read();
194189
}
195190

@@ -210,7 +205,7 @@ void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
210205
#endif
211206

212207
_i2c->beginTransmission(_i2caddr);
213-
_i2c->write(LED0_ON_L + 4 * num);
208+
_i2c->write(PCA9685_LED0_ON_L + 4 * num);
214209
_i2c->write(on);
215210
_i2c->write(on >> 8);
216211
_i2c->write(off);

Adafruit_PWMServoDriver.h

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,57 @@
2525
#include <Arduino.h>
2626
#include <Wire.h>
2727

28-
#define PCA9685_SUBADR1 0x2 /**< i2c bus address 1 */
29-
#define PCA9685_SUBADR2 0x3 /**< i2c bus address 2 */
30-
#define PCA9685_SUBADR3 0x4 /**< i2c bus address 3 */
28+
// REGISTER ADDRESSES
29+
#define PCA9685_MODE1 0x00 /**< Mode Register 1 */
30+
#define PCA9685_MODE2 0x01 /**< Mode Register 2 */
31+
#define PCA9685_SUBADR1 0x02 /**< i2c bus address 1 */
32+
#define PCA9685_SUBADR2 0x03 /**< i2c bus address 2 */
33+
#define PCA9685_SUBADR3 0x04 /**< i2c bus address 3 */
34+
#define PCA9685_ALLCALLADR 0x05
35+
#define PCA9685_LED0_ON_L 0x06 /**< LED0 output and brightness control byte 0 */
36+
#define PCA9685_LED0_ON_H 0x07 /**< LED0 output and brightness control byte 1 */
37+
#define PCA9685_LED0_OFF_L 0x08 /**< LED0 output and brightness control byte 2 */
38+
#define PCA9685_LED0_OFF_H 0x09 /**< LED0 output and brightness control byte 3 */
39+
// etc all 16: LED15_OFF_H 0x45
40+
#define PCA9685_ALLLED_ON_L 0xFA /**< load all the LEDn_ON registers, byte 0 */
41+
#define PCA9685_ALLLED_ON_H 0xFB /**< load all the LEDn_ON registers, byte 1 */
42+
#define PCA9685_ALLLED_OFF_L 0xFC /**< load all the LEDn_OFF registers, byte 0 */
43+
#define PCA9685_ALLLED_OFF_H 0xFD /**< load all the LEDn_OFF registers, byte 1 */
44+
#define PCA9685_PRESCALE 0xFE /**< Prescaler for PWM output frequency */
45+
#define PCA9685_TESTMODE 0xFF
3146

32-
#define PCA9685_MODE1 0x0 /**< Mode Register 1 */
33-
#define PCA9685_MODE2 0x1 /**< Mode Register 2 */
34-
#define PCA9685_PRESCALE 0xFE /**< Prescaler for PWM output frequency */
47+
// MODE1 bits
48+
#define MODE1_ALLCAL 0x01
49+
#define MODE1_SUB3 0x02
50+
#define MODE1_SUB2 0x04
51+
#define MODE1_SUB1 0x08
52+
#define MODE1_SLEEP 0x10
53+
#define MODE1_AI 0x20
54+
#define MODE1_EXTCLK 0x40
55+
#define MODE1_RESTART 0x80
56+
// MODE2 bits
57+
#define MODE2_OUTNE_0 0x01
58+
#define MODE2_OUTNE_1 0x02
59+
#define MODE2_OUTDRV 0x04
60+
#define MODE2_OCH 0x08
61+
#define MODE2_INVRT 0x10
3562

36-
#define LED0_ON_L 0x6 /**< LED0 output and brightness control byte 0 */
37-
#define LED0_ON_H 0x7 /**< LED0 output and brightness control byte 1 */
38-
#define LED0_OFF_L 0x8 /**< LED0 output and brightness control byte 2 */
39-
#define LED0_OFF_H 0x9 /**< LED0 output and brightness control byte 3 */
63+
// Default PCA9685 I2C Slave Address if A0-A5 are not set
64+
#define PCA9685_I2C_ADDRESS 0x40
4065

41-
#define ALLLED_ON_L 0xFA /**< load all the LEDn_ON registers, byte 0 */
42-
#define ALLLED_ON_H 0xFB /**< load all the LEDn_ON registers, byte 1 */
43-
#define ALLLED_OFF_L 0xFC /**< load all the LEDn_OFF registers, byte 0 */
44-
#define ALLLED_OFF_H 0xFD /**< load all the LEDn_OFF registers, byte 1 */
66+
#define FREQUENCY_OSCILLATOR 25000000
67+
#define FREQUENCY_CALIBRATED 26075000 // measured 104.3% compared to official 25 MHz
68+
#define FREQUENCY_LEGACY 27777778 // Effect of freq /= 0,9
69+
70+
#define PCA9685_PRESCALE_MIN 3
71+
#define PCA9685_PRESCALE_MAX 255
4572

4673
/*!
4774
* @brief Class that stores state and functions for interacting with PCA9685 PWM chip
4875
*/
4976
class Adafruit_PWMServoDriver {
5077
public:
51-
Adafruit_PWMServoDriver(uint8_t addr = 0x40, TwoWire *I2C = &Wire);
78+
Adafruit_PWMServoDriver(uint8_t addr = PCA9685_I2C_ADDRESS, TwoWire *I2C = &Wire);
5279
void begin(uint8_t prescale = 0);
5380
void reset();
5481
void sleep();

0 commit comments

Comments
 (0)