mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.4.0 PCA9635
This commit is contained in:
parent
d1c7de266c
commit
acd00a6296
@ -2,11 +2,21 @@
|
|||||||
// FILE: PCA9635.cpp
|
// FILE: PCA9635.cpp
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// DATE: 23-apr-2016
|
// DATE: 23-apr-2016
|
||||||
// VERSION: 0.3.4
|
// VERSION: 0.4.0
|
||||||
// PURPOSE: Arduino library for PCA9635 I2C LED driver
|
// PURPOSE: Arduino library for PCA9635 I2C LED driver
|
||||||
// URL: https://github.com/RobTillaart/PCA9635
|
// URL: https://github.com/RobTillaart/PCA9635
|
||||||
//
|
//
|
||||||
// HISTORY:
|
// HISTORY:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 0.4.0 2022-05-29 breaking changes
|
||||||
|
// rename reset() to configure()
|
||||||
|
// add mode1 and mode2 parameter to configure.
|
||||||
|
// add SUB CALL and ALL CALL functions.
|
||||||
|
// update documentation.
|
||||||
|
// renamed PCA9634_MODE2_STOP to PCA9634_MODE2_ACK
|
||||||
|
// add mode parameters to begin()
|
||||||
|
//
|
||||||
// 0.3.4 2022-04-13 add constants and functions for mode registers.
|
// 0.3.4 2022-04-13 add constants and functions for mode registers.
|
||||||
// 0.3.3 2022-01-03 add channelCount()
|
// 0.3.3 2022-01-03 add channelCount()
|
||||||
// 0.3.2 2021-12-23 update library.json, readme, license, minor edits
|
// 0.3.2 2021-12-23 update library.json, readme, license, minor edits
|
||||||
@ -21,6 +31,7 @@
|
|||||||
// 0.1.0 2016-04-23 initial BETA version
|
// 0.1.0 2016-04-23 initial BETA version
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "PCA9635.h"
|
#include "PCA9635.h"
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +48,7 @@ PCA9635::PCA9635(const uint8_t deviceAddress, TwoWire *wire)
|
|||||||
|
|
||||||
|
|
||||||
#if defined (ESP8266) || defined(ESP32)
|
#if defined (ESP8266) || defined(ESP32)
|
||||||
bool PCA9635::begin(uint8_t sda, uint8_t scl)
|
bool PCA9635::begin(uint8_t sda, uint8_t scl, uint8_t mode1_mask, uint8_t mode2_mask)
|
||||||
{
|
{
|
||||||
_wire = &Wire;
|
_wire = &Wire;
|
||||||
if ((sda < 255) && (scl < 255))
|
if ((sda < 255) && (scl < 255))
|
||||||
@ -47,17 +58,17 @@ bool PCA9635::begin(uint8_t sda, uint8_t scl)
|
|||||||
_wire->begin();
|
_wire->begin();
|
||||||
}
|
}
|
||||||
if (! isConnected()) return false;
|
if (! isConnected()) return false;
|
||||||
reset();
|
configure(mode1_mask, mode2_mask);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool PCA9635::begin()
|
bool PCA9635::begin(uint8_t mode1_mask, uint8_t mode2_mask)
|
||||||
{
|
{
|
||||||
_wire->begin();
|
_wire->begin();
|
||||||
if (! isConnected()) return false;
|
if (! isConnected()) return false;
|
||||||
reset();
|
configure(mode1_mask, mode2_mask);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,13 +81,13 @@ bool PCA9635::isConnected()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCA9635::reset()
|
void PCA9635::configure(uint8_t mode1_mask, uint8_t mode2_mask)
|
||||||
{
|
{
|
||||||
_data = 0;
|
_data = 0;
|
||||||
_error = 0;
|
_error = 0;
|
||||||
|
|
||||||
uint8_t mode1_mask = PCA9635_MODE1_AUTOINCR2 | PCA9635_MODE1_ALLCALL;
|
setMode1(mode1_mask);
|
||||||
writeReg(PCA9635_MODE1, mode1_mask); // AUTOINCR | NOSLEEP | ALLADRR 0x81
|
setMode2(mode2_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,6 +208,107 @@ int PCA9635::lastError()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SUB CALL - ALL CALL
|
||||||
|
//
|
||||||
|
bool PCA9635::enableSubCall(uint8_t nr)
|
||||||
|
{
|
||||||
|
if ((nr == 0) || (nr > 3)) return false;
|
||||||
|
uint8_t prev = getMode1();
|
||||||
|
uint8_t reg = prev;
|
||||||
|
if (nr == 1) reg |= PCA9635_MODE1_SUB1;
|
||||||
|
else if (nr == 2) reg |= PCA9635_MODE1_SUB2;
|
||||||
|
else reg |= PCA9635_MODE1_SUB3;
|
||||||
|
// only update if changed.
|
||||||
|
if (reg != prev) setMode1(reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::disableSubCall(uint8_t nr)
|
||||||
|
{
|
||||||
|
if ((nr == 0) || (nr > 3)) return false;
|
||||||
|
uint8_t prev = getMode1();
|
||||||
|
uint8_t reg = prev;
|
||||||
|
if (nr == 1) reg &= ~PCA9635_MODE1_SUB1;
|
||||||
|
else if (nr == 2) reg &= ~PCA9635_MODE1_SUB2;
|
||||||
|
else reg &= ~PCA9635_MODE1_SUB3;
|
||||||
|
// only update if changed.
|
||||||
|
if (reg != prev) setMode1(reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::isEnabledSubCall(uint8_t nr)
|
||||||
|
{
|
||||||
|
if ((nr == 0) || (nr > 3)) return false;
|
||||||
|
uint8_t reg = getMode1();
|
||||||
|
if (nr == 1) return (reg & PCA9635_MODE1_SUB1) > 0;
|
||||||
|
if (nr == 2) return (reg & PCA9635_MODE1_SUB2) > 0;
|
||||||
|
return (reg & PCA9635_MODE1_SUB3) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::setSubCallAddress(uint8_t nr, uint8_t address)
|
||||||
|
{
|
||||||
|
if ((nr == 0) || (nr > 3)) return false;
|
||||||
|
writeReg(PCA9635_SUBADR(nr), address);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t PCA9635::getSubCallAddress(uint8_t nr)
|
||||||
|
{
|
||||||
|
if ((nr == 0) || (nr > 3)) return 0;
|
||||||
|
uint8_t address = readReg(PCA9635_SUBADR(nr));
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::enableAllCall()
|
||||||
|
{
|
||||||
|
uint8_t prev = getMode1();
|
||||||
|
uint8_t reg = prev | PCA9635_MODE1_ALLCALL;
|
||||||
|
// only update if changed.
|
||||||
|
if (reg != prev) setMode1(reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::disableAllCall()
|
||||||
|
{
|
||||||
|
uint8_t prev = getMode1();
|
||||||
|
uint8_t reg = prev & ~PCA9635_MODE1_ALLCALL;
|
||||||
|
// only update if changed.
|
||||||
|
if (reg != prev) setMode1(reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::isEnabledAllCall()
|
||||||
|
{
|
||||||
|
uint8_t reg = getMode1();
|
||||||
|
return reg & PCA9635_MODE1_ALLCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCA9635::setAllCallAddress(uint8_t address)
|
||||||
|
{
|
||||||
|
writeReg(PCA9635_ALLCALLADR, address);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t PCA9635::getAllCallAddress()
|
||||||
|
{
|
||||||
|
uint8_t address = readReg(PCA9635_ALLCALLADR);
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// PRIVATE
|
// PRIVATE
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// FILE: PCA9635.h
|
// FILE: PCA9635.h
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// DATE: 23-apr-2016
|
// DATE: 23-apr-2016
|
||||||
// VERSION: 0.3.4
|
// VERSION: 0.4.0
|
||||||
// PURPOSE: Arduino library for PCA9635 I2C LED driver, 16 channel
|
// PURPOSE: Arduino library for PCA9635 I2C LED driver, 16 channel
|
||||||
// URL: https://github.com/RobTillaart/PCA9635
|
// URL: https://github.com/RobTillaart/PCA9635
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
|
|
||||||
|
|
||||||
#define PCA9635_LIB_VERSION (F("0.3.4"))
|
#define PCA9635_LIB_VERSION (F("0.4.0"))
|
||||||
|
|
||||||
#define PCA9635_MODE1 0x00
|
#define PCA9635_MODE1 0x00
|
||||||
#define PCA9635_MODE2 0x01
|
#define PCA9635_MODE2 0x01
|
||||||
@ -42,21 +42,22 @@
|
|||||||
|
|
||||||
|
|
||||||
// Configuration bits MODE1 register
|
// Configuration bits MODE1 register
|
||||||
#define PCA9635_MODE1_AUTOINCR2 0x80 // RO, 0 = disable 1 = enable
|
#define PCA9635_MODE1_AUTOINCR2 0x80 // ReadOnly, 0 = disable 1 = enable
|
||||||
#define PCA9635_MODE1_AUTOINCR1 0x40 // RO, bit1
|
#define PCA9635_MODE1_AUTOINCR1 0x40 // ReadOnly, bit1
|
||||||
#define PCA9635_MODE1_AUTOINCR0 0x20 // RO bit0
|
#define PCA9635_MODE1_AUTOINCR0 0x20 // ReadOnly, bit0
|
||||||
#define PCA9635_MODE1_SLEEP 0x10 // 0 = normal 1 = sleep
|
#define PCA9635_MODE1_SLEEP 0x10 // 0 = normal 1 = sleep
|
||||||
#define PCA9635_MODE1_SUB1 0x08 // 0 = disable 1 = enable
|
#define PCA9635_MODE1_SUB1 0x08 // 0 = disable 1 = enable
|
||||||
#define PCA9635_MODE1_SUB2 0x04 // 0 = disable 1 = enable
|
#define PCA9635_MODE1_SUB2 0x04 // 0 = disable 1 = enable
|
||||||
#define PCA9635_MODE1_SUB3 0x02 // 0 = disable 1 = enable
|
#define PCA9635_MODE1_SUB3 0x02 // 0 = disable 1 = enable
|
||||||
#define PCA9635_MODE1_ALLCALL 0x01 // 0 = disable 1 = enable
|
#define PCA9635_MODE1_ALLCALL 0x01 // 0 = disable 1 = enable
|
||||||
|
#define PCA9635_MODE1_NONE 0x00
|
||||||
|
|
||||||
// Configuration bits MODE2 register
|
// Configuration bits MODE2 register
|
||||||
#define PCA9635_MODE2_BLINK 0x20 // 0 = dim 1 = blink
|
#define PCA9635_MODE2_BLINK 0x20 // 0 = dim 1 = blink
|
||||||
#define PCA9635_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
|
#define PCA9635_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
|
||||||
#define PCA9635_MODE2_STOP 0x08 // 0 = on STOP 1 = on ACK
|
#define PCA9635_MODE2_ACK 0x08 // 0 = on STOP 1 = on ACK
|
||||||
#define PCA9635_MODE2_TOTEMPOLE 0x04 // 0 = open drain 1 = totem-pole
|
#define PCA9635_MODE2_TOTEMPOLE 0x04 // 0 = open drain 1 = totem-pole
|
||||||
|
#define PCA9635_MODE2_NONE 0x00
|
||||||
|
|
||||||
// NOT IMPLEMENTED YET
|
// NOT IMPLEMENTED YET
|
||||||
#define PCA9635_SUBADR(x) (0x17+(x)) // x = 1..3
|
#define PCA9635_SUBADR(x) (0x17+(x)) // x = 1..3
|
||||||
@ -69,10 +70,13 @@ public:
|
|||||||
explicit PCA9635(const uint8_t deviceAddress, TwoWire *wire = &Wire);
|
explicit PCA9635(const uint8_t deviceAddress, TwoWire *wire = &Wire);
|
||||||
|
|
||||||
#if defined (ESP8266) || defined(ESP32)
|
#if defined (ESP8266) || defined(ESP32)
|
||||||
bool begin(uint8_t sda, uint8_t scl);
|
bool begin(uint8_t sda, uint8_t scl,
|
||||||
|
uint8_t mode1_mask = PCA9635_MODE1_ALLCALL,
|
||||||
|
uint8_t mode2_mask = PCA9635_MODE2_NONE);
|
||||||
#endif
|
#endif
|
||||||
bool begin();
|
bool begin(uint8_t mode1_mask = PCA9635_MODE1_ALLCALL,
|
||||||
void reset();
|
uint8_t mode2_mask = PCA9635_MODE2_NONE);
|
||||||
|
void configure(uint8_t mode1_mask, uint8_t mode2_mask);
|
||||||
bool isConnected();
|
bool isConnected();
|
||||||
|
|
||||||
uint8_t channelCount() { return _channelCount; };
|
uint8_t channelCount() { return _channelCount; };
|
||||||
@ -82,10 +86,10 @@ public:
|
|||||||
|
|
||||||
// single PWM setting
|
// single PWM setting
|
||||||
uint8_t write1(uint8_t channel, uint8_t value);
|
uint8_t write1(uint8_t channel, uint8_t value);
|
||||||
|
|
||||||
// RGB setting, write three consecutive PWM registers
|
// RGB setting, write three consecutive PWM registers
|
||||||
uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
||||||
|
|
||||||
// generic worker, write N consecutive PWM registers
|
// generic worker, write N consecutive PWM registers
|
||||||
uint8_t writeN(uint8_t channel, uint8_t* arr, uint8_t count);
|
uint8_t writeN(uint8_t channel, uint8_t* arr, uint8_t count);
|
||||||
|
|
||||||
@ -100,15 +104,33 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
// TODO PWM also in %% ?
|
// TODO PWM also in %% ?
|
||||||
void setGroupPWM(uint8_t value) { writeReg(PCA9635_GRPPWM, value); }
|
void setGroupPWM(uint8_t value) { writeReg(PCA9635_GRPPWM, value); };
|
||||||
uint8_t getGroupPWM() { return readReg(PCA9635_GRPPWM); }
|
uint8_t getGroupPWM() { return readReg(PCA9635_GRPPWM); };
|
||||||
|
|
||||||
// TODO set time in milliseconds and round to nearest value?
|
// TODO set time in milliseconds and round to nearest value?
|
||||||
void setGroupFREQ(uint8_t value) { writeReg(PCA9635_GRPFREQ, value); }
|
void setGroupFREQ(uint8_t value) { writeReg(PCA9635_GRPFREQ, value); };
|
||||||
uint8_t getGroupFREQ() { return readReg(PCA9635_GRPFREQ); }
|
uint8_t getGroupFREQ() { return readReg(PCA9635_GRPFREQ); };
|
||||||
|
|
||||||
int lastError();
|
int lastError();
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SUB CALL - ALL CALL (since 0.2.0)
|
||||||
|
//
|
||||||
|
// nr = { 1, 2, 3 }
|
||||||
|
bool enableSubCall(uint8_t nr);
|
||||||
|
bool disableSubCall(uint8_t nr);
|
||||||
|
bool isEnabledSubCall(uint8_t nr);
|
||||||
|
bool setSubCallAddress(uint8_t nr, uint8_t address);
|
||||||
|
uint8_t getSubCallAddress(uint8_t nr);
|
||||||
|
|
||||||
|
bool enableAllCall();
|
||||||
|
bool disableAllCall();
|
||||||
|
bool isEnabledAllCall();
|
||||||
|
bool setAllCallAddress(uint8_t address);
|
||||||
|
uint8_t getAllCallAddress();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// DIRECT CONTROL
|
// DIRECT CONTROL
|
||||||
uint8_t writeReg(uint8_t reg, uint8_t value); // returns error status.
|
uint8_t writeReg(uint8_t reg, uint8_t value); // returns error status.
|
||||||
|
@ -29,16 +29,22 @@ library is related to the 8 channel PCA9634 class.
|
|||||||
|
|
||||||
- **PCA9635(uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor with I2C device address,
|
- **PCA9635(uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor with I2C device address,
|
||||||
and optional the Wire interface as parameter.
|
and optional the Wire interface as parameter.
|
||||||
- **bool begin()** initializes the library after startup. Mandatory.
|
- **bool begin(uint8_t mode1_mask = PCA9634_MODE1_ALLCALL, uint8_t mode2_mask = PCA9634_MODE2_NONE)**
|
||||||
- **bool begin(uint8_t sda, uint8_t scl)** idem, ESP32 ESP8266 only. Library does not support
|
initializes the library after startup. Optionally setting the MODE1 and MODE2 configuration registers.
|
||||||
multiple Wire instances (yet).
|
See PCA9635.h and datasheet for settings possible.
|
||||||
- **void reset()** resets the library to start up conditions.
|
- **bool begin(uint8_t sda, uint8_t scl, uint8_t mode1_mask = PCA9635_MODE1_ALLCALL, uint8_t mode2_mask = PCA9635_MODE2_NONE)**
|
||||||
|
idem, ESP32 ESP8266 only.
|
||||||
|
- **void configure(uint8_t mode1_mask, uint8_t mode2_mask)**
|
||||||
|
To configure the library after startup one can set the MODE1 and MODE2 configuration registers.
|
||||||
|
See PCA9635.h and datasheet for settings possible.
|
||||||
- **bool isConnected()** checks if address is available on I2C bus.
|
- **bool isConnected()** checks if address is available on I2C bus.
|
||||||
- **uint8_t channelCount()** returns the number of channels = 16.
|
- **uint8_t channelCount()** returns the number of channels = 16.
|
||||||
|
|
||||||
|
|
||||||
### LedDriverMode
|
### LedDriverMode
|
||||||
|
|
||||||
|
Configure LED behaviour.
|
||||||
|
|
||||||
- **uint8_t setLedDriverMode(uint8_t channel, uint8_t mode)** mode is 0..3 See datasheet for full details.
|
- **uint8_t setLedDriverMode(uint8_t channel, uint8_t mode)** mode is 0..3 See datasheet for full details.
|
||||||
- **uint8_t getLedDriverMode(uint8_t channel)** returns the current mode of the channel.
|
- **uint8_t getLedDriverMode(uint8_t channel)** returns the current mode of the channel.
|
||||||
|
|
||||||
@ -55,48 +61,55 @@ This is ideal to trigger e.g. multiple LEDs (servo's) at same time.
|
|||||||
|
|
||||||
### Read and write
|
### Read and write
|
||||||
|
|
||||||
|
Read and write individual values to LED channels.
|
||||||
|
Requires LEDs' DriverMode of the specific channels to be in PWM mode.
|
||||||
|
|
||||||
- **uint8_t write1(uint8_t channel, uint8_t value)** writes a single 8 bit PWM value.
|
- **uint8_t write1(uint8_t channel, uint8_t value)** writes a single 8 bit PWM value.
|
||||||
- **uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)** writes three consecutive PWM registers.
|
- **uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)**
|
||||||
|
writes three consecutive PWM registers.
|
||||||
typical use is to write R, G, B values for a full colour LED.
|
typical use is to write R, G, B values for a full colour LED.
|
||||||
- **uint8_t writeN(uint8_t channel, uint8_t \* array, uint8_t count)** write count consecutive PWM registers.
|
- **uint8_t writeN(uint8_t channel, uint8_t \* array, uint8_t count)**
|
||||||
|
write count consecutive PWM registers.
|
||||||
May return **PCA9635_ERR_WRITE** if array has too many elements
|
May return **PCA9635_ERR_WRITE** if array has too many elements
|
||||||
(including channel as offset).
|
(including channel as offset).
|
||||||
|
|
||||||
|
|
||||||
### Mode registers
|
### Mode registers
|
||||||
|
|
||||||
|
Used to configure the PCA963x general behaviour.
|
||||||
|
|
||||||
- **uint8_t writeMode(uint8_t reg, uint8_t value)** configuration of one of the two configuration registers.
|
- **uint8_t writeMode(uint8_t reg, uint8_t value)** configuration of one of the two configuration registers.
|
||||||
check datasheet for details.
|
Check datasheet for details.
|
||||||
- **uint8_t readMode(uint8_t reg)** reads back the configured mode,
|
- **uint8_t readMode(uint8_t reg)** reads back the configured mode,
|
||||||
useful to add or remove a single flag (bit masking).
|
useful to add or remove a single flag (bit masking).
|
||||||
- **uint8_t setMode1(uint8_t value)** convenience wrapper.
|
- **uint8_t setMode1(uint8_t value)** convenience wrapper.
|
||||||
- **uint8_t setMode2(uint8_t value)** convenience wrapper.
|
- **uint8_t setMode2(uint8_t value)** convenience wrapper.
|
||||||
- **uint8_t getMode1()** convenience wrapper.
|
- **uint8_t getMode1()** convenience wrapper.
|
||||||
- **uint8_t getMode2()** convenience wrapper.
|
- **uint8_t getMode2()** convenience wrapper.
|
||||||
|
|
||||||
|
|
||||||
#### Constants for mode registers
|
#### Constants for mode registers
|
||||||
|
|
||||||
(added 0.3.4)
|
(added 0.3.4)
|
||||||
|
|
||||||
| Name | Value | Description |
|
| Name | Value | Description |
|
||||||
|:------------------------|:-----:|:--------------------------------|
|
|:------------------------|:-----:|:-----------------------------------|
|
||||||
| PCA9635_MODE1_AUTOINCR2 | 0x80 | RO, 0 = disable 1 = enable |
|
| PCA9635_MODE1_AUTOINCR2 | 0x80 | Read Only, 0 = disable 1 = enable |
|
||||||
| PCA9635_MODE1_AUTOINCR1 | 0x40 | RO, bit1 |
|
| PCA9635_MODE1_AUTOINCR1 | 0x40 | Read Only, bit1 |
|
||||||
| PCA9635_MODE1_AUTOINCR0 | 0x20 | RO bit0 |
|
| PCA9635_MODE1_AUTOINCR0 | 0x20 | Read Only, bit0 |
|
||||||
| PCA9635_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
|
| PCA9635_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
|
||||||
| PCA9635_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
|
| PCA9635_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
|
||||||
| PCA9635_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
|
| PCA9635_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
|
||||||
| PCA9635_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
|
| PCA9635_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
|
||||||
| PCA9635_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
|
| PCA9635_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
|
||||||
| | | |
|
| | | |
|
||||||
| PCA9635_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
|
| PCA9635_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
|
||||||
| PCA9635_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
|
| PCA9635_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
|
||||||
| PCA9635_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
|
| PCA9635_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
|
||||||
| PCA9635_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
|
| PCA9635_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
|
||||||
|
|
||||||
These constants makes it easier to set modes without using a non descriptive
|
These constants makes it easier to set modes without using a non descriptive
|
||||||
bitmask. The constants can be merged by OR-ing them together, see snippet:
|
bit mask. The constants can be merged by OR-ing them together, see snippet:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
ledArray.writeMode(PCA9635_MODE2, 0b00110100);
|
ledArray.writeMode(PCA9635_MODE2, 0b00110100);
|
||||||
@ -114,18 +127,22 @@ ledArray.setMode2(PCA9635_MODE2_BLINK | PCA9635_MODE2_INVERT | PCA9635_MODE2_TOT
|
|||||||
|
|
||||||
### Group PWM and frequency
|
### Group PWM and frequency
|
||||||
|
|
||||||
|
Check datasheet for the details.
|
||||||
|
|
||||||
- **void setGroupPWM(uint8_t value)** sets all channels that are part of the PWM group to value.
|
- **void setGroupPWM(uint8_t value)** sets all channels that are part of the PWM group to value.
|
||||||
- **uint8_t getGroupPWM()** get the current PWM setting of the group.
|
- **uint8_t getGroupPWM()** get the current PWM setting of the group.
|
||||||
- **void setGroupFREQ(value)** see datasheet for details.
|
- **void setGroupFREQ(uint8_t value)** is used for blinking the group of configured LED.
|
||||||
- **uint8_t getGroupFREQ()** returns the freq of the PWM group.
|
Value goes from 0 to 255 with each step representing an increase of approx. 41 ms.
|
||||||
|
So 0x00 results in 41 ms blinking period (on AND off) and 0xFF in approx. 10.5 s.
|
||||||
|
- **uint8_t getGroupFREQ()** returns the set frequency of the PWM group.
|
||||||
|
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
- **int lastError()** returns **PCA9635_OK** if all is OK, and other error codes otherwise.
|
- **int lastError()** returns **PCA9635_OK** if all is OK, and other error codes otherwise.
|
||||||
|
|
||||||
| Error code | Value | Description |
|
| Error code | Value | Description |
|
||||||
|:------------------|:-----:|:--------------------|
|
|:------------------|:-----:|:---------------------|
|
||||||
| PCA9635_OK | 0x00 | Everything went well
|
| PCA9635_OK | 0x00 | Everything went well
|
||||||
| PCA9635_ERROR | 0xFF | Generic error
|
| PCA9635_ERROR | 0xFF | Generic error
|
||||||
| PCA9635_ERR_WRITE | 0xFE | Tries to write more elements than PWM channels
|
| PCA9635_ERR_WRITE | 0xFE | Tries to write more elements than PWM channels
|
||||||
@ -135,6 +152,44 @@ ledArray.setMode2(PCA9635_MODE2_BLINK | PCA9635_MODE2_INVERT | PCA9635_MODE2_TOT
|
|||||||
| PCA9635_ERR_I2C | 0xFA | I2C communication error
|
| PCA9635_ERR_I2C | 0xFA | I2C communication error
|
||||||
|
|
||||||
|
|
||||||
|
### SUB CALL and ALL CALL
|
||||||
|
|
||||||
|
Please read the datasheet to understand the working of **SUB CALL** and **ALL CALL**.
|
||||||
|
|
||||||
|
Since version 0.4.0 there is (experimental) support for the **SUB CALL** and **ALL CALL** functions.
|
||||||
|
It needs more testing and if there are issues, please report.
|
||||||
|
|
||||||
|
AllCall is automatically activated for each device on startup.
|
||||||
|
|
||||||
|
#### Description
|
||||||
|
|
||||||
|
**SUB CALL** allows one to make groups of PCA9634 devices and control them on group level.
|
||||||
|
The number of groups one can make depends on free I2C addresses on one I2C bus.
|
||||||
|
Using multiple I2C buses or multiplexers will even increase the possible number.
|
||||||
|
Every PCA9634 device can be member of up to three of these groups.
|
||||||
|
To become member one needs to set the **setSubCallAddress(nr, address)** and enable
|
||||||
|
it with **enableSubCall(nr)**.
|
||||||
|
|
||||||
|
In the same way one can become member of an **ALL CALL** group.
|
||||||
|
Typically there is only one such group but one can configure more of them by applying different addresses.
|
||||||
|
|
||||||
|
#### Interface
|
||||||
|
|
||||||
|
The functions to enable all/sub-addresses are straightforward:
|
||||||
|
|
||||||
|
- **bool enableSubCall(uint8_t nr)** nr = 1,2,3
|
||||||
|
- **bool disableSubCall(uint8_t nr)** nr = 1,2,3
|
||||||
|
- **bool isEnabledSubCall(uint8_t nr)** nr = 1,2,3
|
||||||
|
- **bool setSubCallAddress(uint8_t nr, uint8_t address)**
|
||||||
|
- **uint8_t getSubCallAddress(uint8_t nr)**
|
||||||
|
|
||||||
|
- **bool enableAllCall()**
|
||||||
|
- **bool disableAllCall()**
|
||||||
|
- **bool isEnabledAllCall()**
|
||||||
|
- **bool setAllCallAddress(uint8_t address)**
|
||||||
|
- **uint8_t getAllCallAddress()**
|
||||||
|
|
||||||
|
|
||||||
## Operation
|
## Operation
|
||||||
|
|
||||||
See examples
|
See examples
|
||||||
@ -144,6 +199,9 @@ See examples
|
|||||||
|
|
||||||
- improve documentation
|
- improve documentation
|
||||||
- unit tests
|
- unit tests
|
||||||
|
- SUB CALL if possible?
|
||||||
|
- ALL CALL if possible?
|
||||||
- add examples
|
- add examples
|
||||||
|
- sync with PCA9634 developments
|
||||||
- merge with PCA9634 and a PCA963X base class if possible
|
- merge with PCA9634 and a PCA963X base class if possible
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void testSetLedDriverModeLEDON()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - Switch all on");
|
Serial.println("Test - Switch all on");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.setLedDriverMode(channel, PCA9635_LEDON);
|
ledArray.setLedDriverMode(channel, PCA9635_LEDON);
|
||||||
if (ledArray.getLedDriverMode(channel) != PCA9635_LEDON)
|
if (ledArray.getLedDriverMode(channel) != PCA9635_LEDON)
|
||||||
@ -61,7 +61,7 @@ void testPWMMode()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - set pwm mode");
|
Serial.println("Test - set pwm mode");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.setLedDriverMode(channel, PCA9635_LEDON);
|
ledArray.setLedDriverMode(channel, PCA9635_LEDON);
|
||||||
delay(200);
|
delay(200);
|
||||||
@ -82,7 +82,7 @@ void testWrite1()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - write1 - I");
|
Serial.println("Test - write1 - I");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
for (int pwm = 0; pwm < 256; pwm++)
|
for (int pwm = 0; pwm < 256; pwm++)
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@ void testWrite1()
|
|||||||
Serial.println("Test - write 1 - II");
|
Serial.println("Test - write 1 - II");
|
||||||
for (int pwm = 0; pwm < 256; pwm++)
|
for (int pwm = 0; pwm < 256; pwm++)
|
||||||
{
|
{
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.write1(channel, pwm);
|
ledArray.write1(channel, pwm);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ void testWrite3()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - write3 - random RGB");
|
Serial.println("Test - write3 - random RGB");
|
||||||
for (int channel = 0; channel < 13; channel++) // 13 = 16 -3 !!!
|
for (int channel = 0; channel < (ledArray.channelCount() - 3); channel++) // 13 = 16 -3 !!!
|
||||||
{
|
{
|
||||||
uint8_t R = random(256);
|
uint8_t R = random(256);
|
||||||
uint8_t G = random(256);
|
uint8_t G = random(256);
|
||||||
@ -124,7 +124,7 @@ void testWriteN()
|
|||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - writeN ");
|
Serial.println("Test - writeN ");
|
||||||
uint8_t arr[16] = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255};
|
uint8_t arr[16] = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255};
|
||||||
ledArray.writeN(0, arr, 16);
|
ledArray.writeN(0, arr, 16); // 16 == ledArray.channelCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ void testSetGroupPWM_FREQ()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - GroupPWM");
|
Serial.println("Test - GroupPWM");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.setLedDriverMode(channel, PCA9635_LEDGRPPWM);
|
ledArray.setLedDriverMode(channel, PCA9635_LEDGRPPWM);
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ void testSetGroupPWM_FREQ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset to LEDPWM
|
// reset to LEDPWM
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.setLedDriverMode(channel, PCA9635_LEDPWM);
|
ledArray.setLedDriverMode(channel, PCA9635_LEDPWM);
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ void testSetLedDriverModeLEDOFF()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - Switch all off");
|
Serial.println("Test - Switch all off");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.setLedDriverMode(channel, PCA9635_LEDOFF);
|
ledArray.setLedDriverMode(channel, PCA9635_LEDOFF);
|
||||||
if (ledArray.getLedDriverMode(channel) != PCA9635_LEDOFF)
|
if (ledArray.getLedDriverMode(channel) != PCA9635_LEDOFF)
|
||||||
|
@ -27,7 +27,7 @@ void setup()
|
|||||||
Serial.print(millis());
|
Serial.print(millis());
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.println("Test - write1 - I");
|
Serial.println("Test - write1 - I");
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
for (int pwm = 0; pwm < 256; pwm++)
|
for (int pwm = 0; pwm < 256; pwm++)
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ void setup()
|
|||||||
Serial.println("Test - write 1 - II");
|
Serial.println("Test - write 1 - II");
|
||||||
for (int pwm = 0; pwm < 256; pwm++)
|
for (int pwm = 0; pwm < 256; pwm++)
|
||||||
{
|
{
|
||||||
for (int channel = 0; channel < 16; channel++)
|
for (int channel = 0; channel < ledArray.channelCount(); channel++)
|
||||||
{
|
{
|
||||||
ledArray.write1(channel, pwm);
|
ledArray.write1(channel, pwm);
|
||||||
ledArray2.write1(channel, pwm);
|
ledArray2.write1(channel, pwm);
|
||||||
|
@ -7,7 +7,7 @@ PCA9635 KEYWORD1
|
|||||||
|
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
begin KEYWORD2
|
begin KEYWORD2
|
||||||
reset KEYWORD2
|
configure KEYWORD2
|
||||||
|
|
||||||
isConnected KEYWORD2
|
isConnected KEYWORD2
|
||||||
setLedDriverMode KEYWORD2
|
setLedDriverMode KEYWORD2
|
||||||
@ -31,6 +31,13 @@ getGroupFREQ KEYWORD2
|
|||||||
|
|
||||||
lastError KEYWORD2
|
lastError KEYWORD2
|
||||||
|
|
||||||
|
enableSubCall KEYWORD2
|
||||||
|
disableSubCall KEYWORD2
|
||||||
|
isEnabledSubCall KEYWORD2
|
||||||
|
enableAllCall KEYWORD2
|
||||||
|
disableAllCall KEYWORD2
|
||||||
|
isEnabledAllCall KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
# Constants ( LITERAL1)
|
# Constants ( LITERAL1)
|
||||||
PCA9635_LIB_VERSION LITERAL1
|
PCA9635_LIB_VERSION LITERAL1
|
||||||
@ -50,8 +57,11 @@ PCA9635_MODE1_SUB1 LITERAL1
|
|||||||
PCA9635_MODE1_SUB2 LITERAL1
|
PCA9635_MODE1_SUB2 LITERAL1
|
||||||
PCA9635_MODE1_SUB3 LITERAL1
|
PCA9635_MODE1_SUB3 LITERAL1
|
||||||
PCA9635_MODE1_ALLCALL LITERAL1
|
PCA9635_MODE1_ALLCALL LITERAL1
|
||||||
|
PCA9635_MODE1_NONE LITERAL1
|
||||||
|
|
||||||
PCA9635_MODE2_BLINK LITERAL1
|
PCA9635_MODE2_BLINK LITERAL1
|
||||||
PCA9635_MODE2_INVERT LITERAL1
|
PCA9635_MODE2_INVERT LITERAL1
|
||||||
PCA9635_MODE2_STOP LITERAL1
|
PCA9635_MODE2_ACK LITERAL1
|
||||||
PCA9635_MODE2_TOTEMPOLE LITERAL1
|
PCA9635_MODE2_TOTEMPOLE LITERAL1
|
||||||
|
PCA9635_MODE2_NONE LITERAL1
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "PCA9635",
|
"name": "PCA9635",
|
||||||
"keywords": "I2C,PCA9635,PWM",
|
"keywords": "I2C,PCA9635,PWM",
|
||||||
"description": "Arduino library for PCA9635 I2C LED driver",
|
"description": "Arduino library for PCA9635 I2C LED driver, 16 channel",
|
||||||
"authors":
|
"authors":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/PCA9635.git"
|
"url": "https://github.com/RobTillaart/PCA9635.git"
|
||||||
},
|
},
|
||||||
"version": "0.3.4",
|
"version": "0.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
name=PCA9635
|
name=PCA9635
|
||||||
version=0.3.4
|
version=0.4.0
|
||||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
sentence=Arduino library for PCA9635 I2C LED driver
|
sentence=Arduino library for PCA9635 I2C LED driver 16 channel
|
||||||
paragraph=PWM, 8 bit
|
paragraph=PWM, 8 bit
|
||||||
category=Signal Input/Output
|
category=Signal Input/Output
|
||||||
url=https://github.com/RobTillaart/PCA9635
|
url=https://github.com/RobTillaart/PCA9635
|
||||||
|
@ -73,11 +73,10 @@ unittest(test_constants)
|
|||||||
|
|
||||||
unittest(test_constructor)
|
unittest(test_constructor)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "VERSION: %s\n", PCA9635_LIB_VERSION);
|
|
||||||
|
|
||||||
PCA9635 ledArray(0x20);
|
PCA9635 ledArray(0x20);
|
||||||
assertTrue(ledArray.begin());
|
assertTrue(ledArray.begin());
|
||||||
assertTrue(ledArray.isConnected());
|
assertTrue(ledArray.isConnected());
|
||||||
|
assertEqual(16, ledArray.channelCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user