Red/Green/Blue/Amber (RGBA) color backlighting applications. Each LED output has its
own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates
at a programmable frequency from a typical of 40 Hz to 1000 Hz with a duty cycle that is
adjustable from 0 % to 100 % to allow the LED to be set to a specific brightness value.
All outputs are set to the same PWM frequency.
begin()
init()
setLEDDimmed()
sample code 如下:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#define PCA9685_MODE1 0x00 // location for Mode1 register address | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#define PCA9685_MODE2 0x01 // location for Mode2 reigster address | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#define PCA9685_LED0 0x06 // location for start of LED0 registers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#define PCA9685_I2C_BASE_ADDRESS B1000000 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class PCA9685 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//NB the i2c address here is the value of the A0, A1, A2, A3, A4 and A5 pins ONLY | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//as the class takes care of its internal base address. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//so i2cAddress should be between 0 and 63 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PCA9685(); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void begin(int i2cAddress); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bool init(); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void setLEDOn(int ledNumber); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void setLEDOff(int ledNumber); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void setLEDDimmed(int ledNumber, byte amount); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void writeLED(int ledNumber, word outputStart, word outputEnd); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void writeRegister(int regaddress, byte val); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
word readRegister(int regAddress); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Our actual i2c address: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
byte _i2cAddress; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; |
#include "PCA9685.h" | |
PCA9685::PCA9685() {} | |
void PCA9685::begin(int i2cAddress) { | |
_i2cAddress = PCA9685_I2C_BASE_ADDRESS | (i2cAddress & B00111111); | |
} | |
bool PCA9685::init() { | |
delay(1); | |
writeRegister(PCA9685_MODE1, (byte)0x01); // reset the device | |
delay(1); | |
bool isOnline; | |
if (readRegister(PCA9685_MODE1)==0x01) { | |
isOnline = true; | |
} else { | |
isOnline = false; | |
} | |
writeRegister(PCA9685_MODE1, (byte)B10100000); // set up for auto increment | |
writeRegister(PCA9685_MODE2, (byte)0x10); // set to output | |
return isOnline; | |
} | |
void PCA9685::setLEDOn(int ledNumber) { | |
writeLED(ledNumber, 0x1000, 0); | |
} | |
void PCA9685::setLEDOff(int ledNumber) { | |
writeLED(ledNumber, 0, 0x1000); | |
} | |
void PCA9685::setLEDDimmed(int ledNumber, byte amount) { // Amount from 0-100 (off-on) | |
if (amount==0) { | |
setLEDOff(ledNumber); | |
} else if (amount>=100) { | |
setLEDOn(ledNumber); | |
} else { | |
int randNumber = (int)random(4096); // Randomize the phaseshift to distribute load. Good idea? Hope so. | |
writeLED(ledNumber, randNumber, (int)(amount*41+randNumber) & 0xFFF); | |
} | |
} | |
void PCA9685::writeLED(int ledNumber, word LED_ON, word LED_OFF) { // LED_ON and LED_OFF are 12bit values (0-4095); ledNumber is 0-15 | |
if (ledNumber >=0 && ledNumber <= 15) { | |
Wire.beginTransmission(_i2cAddress); | |
Wire.write(PCA9685_LED0 + 4*ledNumber); | |
Wire.write(lowByte(LED_ON)); | |
Wire.write(highByte(LED_ON)); | |
Wire.write(lowByte(LED_OFF)); | |
Wire.write(highByte(LED_OFF)); | |
Wire.endTransmission(); | |
} | |
} | |
//PRIVATE | |
void PCA9685::writeRegister(int regAddress, byte data) { | |
Wire.beginTransmission(_i2cAddress); | |
Wire.write(regAddress); | |
Wire.write(data); | |
Wire.endTransmission(); | |
} | |
word PCA9685::readRegister(int regAddress) { | |
word returnword = 0x00; | |
Wire.beginTransmission(_i2cAddress); | |
Wire.write(regAddress); | |
Wire.endTransmission(); | |
Wire.requestFrom((int)_i2cAddress, 1); | |
// int c=0; | |
//Wait for our 2 bytes to become available | |
while (Wire.available()) { | |
//high byte | |
// if (c==0) { returnword = Wire.read() << 8; } | |
//low byte | |
// if (c==1) { | |
returnword |= Wire.read(); | |
//} | |
//c++; | |
} | |
return returnword; | |
} |
沒有留言:
張貼留言