mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.4.3 PCA9635
This commit is contained in:
parent
972102e1ce
commit
6b5a5cc638
@ -6,7 +6,7 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: arduino/arduino-lint-action@v1
|
||||
with:
|
||||
library-manager: update
|
||||
|
@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
|
@ -10,7 +10,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v1
|
||||
with:
|
||||
|
@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.4.3] - 2023-01-23
|
||||
- update GitHub actions
|
||||
- update license 2023
|
||||
- add OutputEnable control functions.
|
||||
- add example **PCA9635_OE_control.ino**
|
||||
- update unit test.
|
||||
- **configure()** now returns error state
|
||||
- update readme.md
|
||||
- minor edits
|
||||
|
||||
|
||||
## [0.4.2] - 2022-11-19
|
||||
- add RP2040 in build-CI
|
||||
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2022 Rob Tillaart
|
||||
Copyright (c) 2016-2023 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -2,7 +2,7 @@
|
||||
// FILE: PCA9635.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 23-apr-2016
|
||||
// VERSION: 0.4.2
|
||||
// VERSION: 0.4.3
|
||||
// PURPOSE: Arduino library for PCA9635 I2C LED driver
|
||||
// URL: https://github.com/RobTillaart/PCA9635
|
||||
|
||||
@ -16,9 +16,12 @@
|
||||
//
|
||||
PCA9635::PCA9635(const uint8_t deviceAddress, TwoWire *wire)
|
||||
{
|
||||
_address = deviceAddress;
|
||||
_wire = wire;
|
||||
_channelCount = 16;
|
||||
_address = deviceAddress;
|
||||
_wire = wire;
|
||||
_channelCount = 16;
|
||||
_data = 0;
|
||||
_error = PCA9635_OK;
|
||||
_OutputEnablePin = 255;
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +51,22 @@ bool PCA9635::begin(uint8_t mode1_mask, uint8_t mode2_mask)
|
||||
}
|
||||
|
||||
|
||||
uint8_t PCA9635::configure(uint8_t mode1_mask, uint8_t mode2_mask)
|
||||
{
|
||||
_data = 0;
|
||||
_error = PCA9635_OK;
|
||||
|
||||
uint8_t r1 = setMode1(mode1_mask);
|
||||
uint8_t r2 = setMode2(mode2_mask);
|
||||
|
||||
if ((r1 != PCA9635_OK) || (r2 != PCA9635_OK))
|
||||
{
|
||||
return PCA9635_ERROR;
|
||||
}
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
bool PCA9635::isConnected()
|
||||
{
|
||||
_wire->beginTransmission(_address);
|
||||
@ -56,13 +75,9 @@ bool PCA9635::isConnected()
|
||||
}
|
||||
|
||||
|
||||
void PCA9635::configure(uint8_t mode1_mask, uint8_t mode2_mask)
|
||||
uint8_t PCA9635::channelCount()
|
||||
{
|
||||
_data = 0;
|
||||
_error = 0;
|
||||
|
||||
setMode1(mode1_mask);
|
||||
setMode2(mode2_mask);
|
||||
return _channelCount;
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +103,7 @@ uint8_t PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count)
|
||||
{
|
||||
if (channel + count > _channelCount)
|
||||
{
|
||||
_error = PCA9635_ERR_WRITE;
|
||||
_error = PCA9635_ERR_CHAN;
|
||||
return PCA9635_ERROR;
|
||||
}
|
||||
uint8_t base = PCA9635_PWM(channel);
|
||||
@ -104,7 +119,8 @@ uint8_t PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count)
|
||||
_error = PCA9635_ERR_I2C;
|
||||
return PCA9635_ERROR;
|
||||
}
|
||||
return PCA9635_OK;
|
||||
_error = PCA9635_OK;
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +132,7 @@ uint8_t PCA9635::writeMode(uint8_t reg, uint8_t value)
|
||||
return PCA9635_OK;
|
||||
}
|
||||
_error = PCA9635_ERR_REG;
|
||||
return PCA9635_ERROR;
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
@ -130,7 +146,7 @@ uint8_t PCA9635::readMode(uint8_t reg)
|
||||
return value;
|
||||
}
|
||||
_error = PCA9635_ERR_REG;
|
||||
return PCA9635_ERROR;
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +170,8 @@ uint8_t PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode)
|
||||
uint8_t clrmask = ~(0x03 << shift);
|
||||
uint8_t value = (readReg(reg) & clrmask) | setmask;
|
||||
writeReg(reg, value);
|
||||
return PCA9635_OK;
|
||||
_error = PCA9635_OK;
|
||||
return _error;
|
||||
}
|
||||
|
||||
|
||||
@ -168,13 +185,16 @@ uint8_t PCA9635::getLedDriverMode(uint8_t channel)
|
||||
}
|
||||
|
||||
uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2);
|
||||
uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places
|
||||
uint8_t shift = (channel & 0x03) * 2; // 0, 2, 4, 6 places
|
||||
uint8_t value = (readReg(reg) >> shift ) & 0x03;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// note error flag is reset after read!
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// ERROR
|
||||
//
|
||||
int PCA9635::lastError()
|
||||
{
|
||||
int e = _error;
|
||||
@ -183,7 +203,6 @@ int PCA9635::lastError()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// SUB CALL - ALL CALL
|
||||
@ -192,12 +211,16 @@ 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;
|
||||
uint8_t mask = prev;
|
||||
if (nr == 1) mask |= PCA9635_MODE1_SUB1;
|
||||
else if (nr == 2) mask |= PCA9635_MODE1_SUB2;
|
||||
else mask |= PCA9635_MODE1_SUB3;
|
||||
// only update if changed.
|
||||
if (reg != prev) setMode1(reg);
|
||||
if (mask != prev)
|
||||
{
|
||||
setMode1(mask);
|
||||
// TODO error handling ...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -206,12 +229,16 @@ 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;
|
||||
uint8_t mask = prev;
|
||||
if (nr == 1) mask &= ~PCA9635_MODE1_SUB1;
|
||||
else if (nr == 2) mask &= ~PCA9635_MODE1_SUB2;
|
||||
else mask &= ~PCA9635_MODE1_SUB3;
|
||||
// only update if changed.
|
||||
if (reg != prev) setMode1(reg);
|
||||
if (mask != prev)
|
||||
{
|
||||
setMode1(mask);
|
||||
// TODO error handling ...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -219,16 +246,20 @@ bool PCA9635::disableSubCall(uint8_t nr)
|
||||
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;
|
||||
uint8_t mask = getMode1();
|
||||
if (nr == 1) return (mask & PCA9635_MODE1_SUB1) > 0;
|
||||
if (nr == 2) return (mask & PCA9635_MODE1_SUB2) > 0;
|
||||
return (mask & PCA9635_MODE1_SUB3) > 0;
|
||||
}
|
||||
|
||||
|
||||
bool PCA9635::setSubCallAddress(uint8_t nr, uint8_t address)
|
||||
{
|
||||
if ((nr == 0) || (nr > 3)) return false;
|
||||
if ((nr == 0) || (nr > 3))
|
||||
{
|
||||
// _error = ?? TODO
|
||||
return false;
|
||||
}
|
||||
writeReg(PCA9635_SUBADR(nr), address);
|
||||
return true;
|
||||
}
|
||||
@ -236,7 +267,11 @@ bool PCA9635::setSubCallAddress(uint8_t nr, uint8_t address)
|
||||
|
||||
uint8_t PCA9635::getSubCallAddress(uint8_t nr)
|
||||
{
|
||||
if ((nr == 0) || (nr > 3)) return 0;
|
||||
if ((nr == 0) || (nr > 3))
|
||||
{
|
||||
// _error = ?? TODO
|
||||
return 0;
|
||||
}
|
||||
uint8_t address = readReg(PCA9635_SUBADR(nr));
|
||||
return address;
|
||||
}
|
||||
@ -245,9 +280,13 @@ uint8_t PCA9635::getSubCallAddress(uint8_t nr)
|
||||
bool PCA9635::enableAllCall()
|
||||
{
|
||||
uint8_t prev = getMode1();
|
||||
uint8_t reg = prev | PCA9635_MODE1_ALLCALL;
|
||||
uint8_t mask = prev | PCA9635_MODE1_ALLCALL;
|
||||
// only update if changed.
|
||||
if (reg != prev) setMode1(reg);
|
||||
if (mask != prev)
|
||||
{
|
||||
setMode1(mask);
|
||||
// error handling TODO
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -255,17 +294,21 @@ bool PCA9635::enableAllCall()
|
||||
bool PCA9635::disableAllCall()
|
||||
{
|
||||
uint8_t prev = getMode1();
|
||||
uint8_t reg = prev & ~PCA9635_MODE1_ALLCALL;
|
||||
uint8_t mask = prev & ~PCA9635_MODE1_ALLCALL;
|
||||
// only update if changed.
|
||||
if (reg != prev) setMode1(reg);
|
||||
if (mask != prev)
|
||||
{
|
||||
setMode1(mask);
|
||||
// error handling TODO
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PCA9635::isEnabledAllCall()
|
||||
{
|
||||
uint8_t reg = getMode1();
|
||||
return reg & PCA9635_MODE1_ALLCALL;
|
||||
uint8_t mask = getMode1();
|
||||
return mask & PCA9635_MODE1_ALLCALL;
|
||||
}
|
||||
|
||||
|
||||
@ -283,6 +326,46 @@ uint8_t PCA9635::getAllCallAddress()
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// OE - Output Enable control
|
||||
//
|
||||
// active LOW see page 5 par 6.2 datasheet
|
||||
//
|
||||
bool PCA9635::setOutputEnablePin(uint8_t pin)
|
||||
{
|
||||
_OutputEnablePin = pin;
|
||||
if (_OutputEnablePin != 255)
|
||||
{
|
||||
pinMode(_OutputEnablePin, OUTPUT);
|
||||
digitalWrite(_OutputEnablePin, HIGH);
|
||||
return true;
|
||||
}
|
||||
// must it be set to HIGH now?
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PCA9635::setOutputEnable(bool on)
|
||||
{
|
||||
if (_OutputEnablePin != 255)
|
||||
{
|
||||
digitalWrite(_OutputEnablePin, on ? LOW : HIGH);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PCA9635::getOutputEnable()
|
||||
{
|
||||
if (_OutputEnablePin != 255)
|
||||
{
|
||||
return digitalRead(_OutputEnablePin);
|
||||
}
|
||||
return HIGH;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
@ -294,6 +377,7 @@ uint8_t PCA9635::writeReg(uint8_t reg, uint8_t value)
|
||||
_wire->write(reg);
|
||||
_wire->write(value);
|
||||
_error = _wire->endTransmission();
|
||||
|
||||
if (_error == 0) _error = PCA9635_OK;
|
||||
else _error = PCA9635_ERR_I2C;
|
||||
return _error;
|
||||
@ -305,6 +389,7 @@ uint8_t PCA9635::readReg(uint8_t reg)
|
||||
_wire->beginTransmission(_address);
|
||||
_wire->write(reg);
|
||||
_error = _wire->endTransmission();
|
||||
|
||||
if (_wire->requestFrom(_address, (uint8_t)1) != 1)
|
||||
{
|
||||
_error = PCA9635_ERROR;
|
||||
@ -316,5 +401,5 @@ uint8_t PCA9635::readReg(uint8_t reg)
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// FILE: PCA9635.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 23-apr-2016
|
||||
// VERSION: 0.4.2
|
||||
// VERSION: 0.4.3
|
||||
// PURPOSE: Arduino library for PCA9635 I2C LED driver, 16 channel
|
||||
// URL: https://github.com/RobTillaart/PCA9635
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define PCA9635_LIB_VERSION (F("0.4.2"))
|
||||
#define PCA9635_LIB_VERSION (F("0.4.3"))
|
||||
|
||||
#define PCA9635_MODE1 0x00
|
||||
#define PCA9635_MODE2 0x01
|
||||
@ -25,8 +25,8 @@
|
||||
#define PCA9635_GRPFREQ 0x13
|
||||
|
||||
// check datasheet for details
|
||||
#define PCA9635_LEDOUT_BASE 0x14 // 0x14..0x17
|
||||
#define PCA9635_LEDOFF 0x00 // default @ startup
|
||||
#define PCA9635_LEDOUT_BASE 0x14 // 0x14..0x17
|
||||
#define PCA9635_LEDOFF 0x00 // default @ startup
|
||||
#define PCA9635_LEDON 0x01
|
||||
#define PCA9635_LEDPWM 0x02
|
||||
#define PCA9635_LEDGRPPWM 0x03
|
||||
@ -41,26 +41,26 @@
|
||||
#define PCA9635_ERR_I2C 0xFA
|
||||
|
||||
|
||||
// Configuration bits MODE1 register
|
||||
#define PCA9635_MODE1_AUTOINCR2 0x80 // ReadOnly, 0 = disable 1 = enable
|
||||
#define PCA9635_MODE1_AUTOINCR1 0x40 // ReadOnly, bit1
|
||||
#define PCA9635_MODE1_AUTOINCR0 0x20 // ReadOnly, bit0
|
||||
#define PCA9635_MODE1_SLEEP 0x10 // 0 = normal 1 = sleep
|
||||
#define PCA9635_MODE1_SUB1 0x08 // 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_ALLCALL 0x01 // 0 = disable 1 = enable
|
||||
// Configuration bits MODE1 register
|
||||
#define PCA9635_MODE1_AUTOINCR2 0x80 // ReadOnly, 0 = disable 1 = enable
|
||||
#define PCA9635_MODE1_AUTOINCR1 0x40 // ReadOnly, bit1
|
||||
#define PCA9635_MODE1_AUTOINCR0 0x20 // ReadOnly, bit0
|
||||
#define PCA9635_MODE1_SLEEP 0x10 // 0 = normal 1 = sleep
|
||||
#define PCA9635_MODE1_SUB1 0x08 // 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_ALLCALL 0x01 // 0 = disable 1 = enable
|
||||
#define PCA9635_MODE1_NONE 0x00
|
||||
|
||||
// Configuration bits MODE2 register
|
||||
#define PCA9635_MODE2_BLINK 0x20 // 0 = dim 1 = blink
|
||||
#define PCA9635_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
|
||||
#define PCA9635_MODE2_ACK 0x08 // 0 = on STOP 1 = on ACK
|
||||
#define PCA9635_MODE2_TOTEMPOLE 0x04 // 0 = open drain 1 = totem-pole
|
||||
// Configuration bits MODE2 register
|
||||
#define PCA9635_MODE2_BLINK 0x20 // 0 = dim 1 = blink
|
||||
#define PCA9635_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
|
||||
#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_NONE 0x00
|
||||
|
||||
// NOT IMPLEMENTED YET
|
||||
#define PCA9635_SUBADR(x) (0x17+(x)) // x = 1..3
|
||||
// NOT IMPLEMENTED YET
|
||||
#define PCA9635_SUBADR(x) (0x17+(x)) // x = 1..3
|
||||
#define PCA9635_ALLCALLADR 0x1B
|
||||
|
||||
|
||||
@ -76,23 +76,19 @@ public:
|
||||
#endif
|
||||
bool begin(uint8_t mode1_mask = PCA9635_MODE1_ALLCALL,
|
||||
uint8_t mode2_mask = PCA9635_MODE2_NONE);
|
||||
void configure(uint8_t mode1_mask, uint8_t mode2_mask);
|
||||
bool isConnected();
|
||||
|
||||
uint8_t channelCount() { return _channelCount; };
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// CONFIGURATION
|
||||
//
|
||||
uint8_t configure(uint8_t mode1_mask, uint8_t mode2_mask);
|
||||
uint8_t channelCount();
|
||||
|
||||
uint8_t setLedDriverMode(uint8_t channel, uint8_t mode);
|
||||
uint8_t getLedDriverMode(uint8_t channel);
|
||||
|
||||
// single PWM setting
|
||||
uint8_t write1(uint8_t channel, uint8_t value);
|
||||
|
||||
// RGB setting, write three consecutive PWM registers
|
||||
uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
||||
|
||||
// generic worker, write N consecutive PWM registers
|
||||
uint8_t writeN(uint8_t channel, uint8_t* arr, uint8_t count);
|
||||
|
||||
// reg = 1, 2 check datasheet for values
|
||||
uint8_t writeMode(uint8_t reg, uint8_t value);
|
||||
uint8_t readMode(uint8_t reg);
|
||||
@ -102,7 +98,6 @@ public:
|
||||
uint8_t getMode1() { return readMode(PCA9635_MODE1); };
|
||||
uint8_t getMode2() { return readMode(PCA9635_MODE2); };
|
||||
|
||||
|
||||
// TODO PWM also in %% ?
|
||||
void setGroupPWM(uint8_t value) { writeReg(PCA9635_GRPPWM, value); };
|
||||
uint8_t getGroupPWM() { return readReg(PCA9635_GRPPWM); };
|
||||
@ -111,11 +106,32 @@ public:
|
||||
void setGroupFREQ(uint8_t value) { writeReg(PCA9635_GRPFREQ, value); };
|
||||
uint8_t getGroupFREQ() { return readReg(PCA9635_GRPFREQ); };
|
||||
|
||||
int lastError();
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// SUB CALL - ALL CALL (since 0.2.0)
|
||||
// WRITE
|
||||
//
|
||||
// single PWM setting
|
||||
uint8_t write1(uint8_t channel, uint8_t value);
|
||||
|
||||
// RGB setting, write three consecutive PWM registers
|
||||
uint8_t write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
||||
|
||||
// generic worker, write N consecutive PWM registers
|
||||
uint8_t writeN(uint8_t channel, uint8_t* arr, uint8_t count);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// ERROR
|
||||
//
|
||||
// note error flag is reset after read!
|
||||
int lastError();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// SUB CALL - ALL CALL (since 0.2.0)
|
||||
//
|
||||
// nr = { 1, 2, 3 }
|
||||
bool enableSubCall(uint8_t nr);
|
||||
@ -131,20 +147,29 @@ public:
|
||||
uint8_t getAllCallAddress();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// OE - Output Enable control
|
||||
//
|
||||
bool setOutputEnablePin(uint8_t pin);
|
||||
bool setOutputEnable(bool on);
|
||||
uint8_t getOutputEnable();
|
||||
|
||||
|
||||
private:
|
||||
// DIRECT CONTROL
|
||||
uint8_t writeReg(uint8_t reg, uint8_t value); // returns error status.
|
||||
// DIRECT CONTROL
|
||||
uint8_t writeReg(uint8_t reg, uint8_t value); // returns error status.
|
||||
uint8_t readReg(uint8_t reg);
|
||||
|
||||
uint8_t _address;
|
||||
uint8_t _register;
|
||||
uint8_t _data;
|
||||
int _error;
|
||||
uint8_t _channelCount = 16;
|
||||
uint8_t _OutputEnablePin;
|
||||
|
||||
TwoWire* _wire;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -15,17 +15,20 @@ Arduino library for PCA9635 I2C 8 bit PWM LED driver, 16 channel.
|
||||
|
||||
This library is to control the I2C PCA9635 PWM extender.
|
||||
The 16 channels are independently configurable in steps of 1/256.
|
||||
this allows for better than 1% fine tuning of the duty-cycle
|
||||
This allows for better than 1% fine tuning of the duty-cycle
|
||||
of the PWM signal.
|
||||
|
||||
library is related to the 8 channel PCA9634 class.
|
||||
library is related to the 8 channel https://github.com/RobTillaart/PCA9634 class.
|
||||
(these might merge in the future)
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
```cpp
|
||||
#include "PCA9635.h"
|
||||
```
|
||||
|
||||
### Constructor
|
||||
#### Constructor
|
||||
|
||||
- **PCA9635(uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor with I2C device address,
|
||||
and optional the Wire interface as parameter.
|
||||
@ -41,25 +44,25 @@ See PCA9635.h and datasheet for settings possible.
|
||||
- **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 getLedDriverMode(uint8_t channel)** returns the current mode of the channel.
|
||||
|
||||
| LED mode | Value | Description |
|
||||
|:-------------------|:-----:|:----------------------------------|
|
||||
| PCA9635_LEDOFF | 0x00 | led is 100% off, default @startup |
|
||||
| PCA9635_LEDON | 0x01 | led is 100% on. |
|
||||
| PCA9635_LEDPWM | 0x02 | set LED in PWM mode, 0..255 |
|
||||
| PCA9635_LEDGRPPWM | 0x03 | add LED to the GRPPWM* |
|
||||
| LED mode | Value | Description |
|
||||
|:--------------------|:-------:|:------------------------------------|
|
||||
| PCA9635_LEDOFF | 0x00 | led is 100% off, default @startup |
|
||||
| PCA9635_LEDON | 0x01 | led is 100% on. |
|
||||
| PCA9635_LEDPWM | 0x02 | set LED in PWM mode, 0..255 |
|
||||
| PCA9635_LEDGRPPWM | 0x03 | add LED to the GRPPWM* |
|
||||
|
||||
\* all LEDs in the group GRPPWM can be set to the same PWM value in one set.
|
||||
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.
|
||||
@ -74,7 +77,7 @@ May return **PCA9635_ERR_WRITE** if array has too many elements
|
||||
(including channel as offset).
|
||||
|
||||
|
||||
### Mode registers
|
||||
#### Mode registers
|
||||
|
||||
Used to configure the PCA963x general behaviour.
|
||||
|
||||
@ -92,21 +95,21 @@ useful to add or remove a single flag (bit masking).
|
||||
|
||||
(added 0.3.4)
|
||||
|
||||
| Name | Value | Description |
|
||||
|:------------------------|:-----:|:-----------------------------------|
|
||||
| PCA9635_MODE1_AUTOINCR2 | 0x80 | Read Only, 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_AUTOINCR1 | 0x40 | Read Only, bit1 |
|
||||
| PCA9635_MODE1_AUTOINCR0 | 0x20 | Read Only, bit0 |
|
||||
| PCA9635_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
|
||||
| PCA9635_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
|
||||
| | | |
|
||||
| PCA9635_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
|
||||
| PCA9635_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
|
||||
| PCA9635_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
|
||||
| PCA9635_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
|
||||
| Name | Value | Description |
|
||||
|:--------------------------|:-------:|:-------------------------------------|
|
||||
| PCA9635_MODE1_AUTOINCR2 | 0x80 | Read Only, 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_AUTOINCR1 | 0x40 | Read Only, bit1 |
|
||||
| PCA9635_MODE1_AUTOINCR0 | 0x20 | Read Only, bit0 |
|
||||
| PCA9635_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
|
||||
| PCA9635_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
|
||||
| PCA9635_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
|
||||
| ---- | | |
|
||||
| PCA9635_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
|
||||
| PCA9635_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
|
||||
| PCA9635_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
|
||||
| PCA9635_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
|
||||
|
||||
These constants makes it easier to set modes without using a non descriptive
|
||||
bit mask. The constants can be merged by OR-ing them together, see snippet:
|
||||
@ -125,7 +128,7 @@ ledArray.setMode2(PCA9635_MODE2_BLINK | PCA9635_MODE2_INVERT | PCA9635_MODE2_TOT
|
||||
```
|
||||
|
||||
|
||||
### Group PWM and frequency
|
||||
#### Group PWM and frequency
|
||||
|
||||
Check datasheet for the details.
|
||||
|
||||
@ -137,22 +140,22 @@ 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.
|
||||
|
||||
| Error code | Value | Description |
|
||||
|:------------------|:-----:|:---------------------|
|
||||
| PCA9635_OK | 0x00 | Everything went well
|
||||
| PCA9635_ERROR | 0xFF | Generic error
|
||||
| PCA9635_ERR_WRITE | 0xFE | Tries to write more elements than PWM channels
|
||||
| PCA9635_ERR_CHAN | 0xFD | Channel out of range
|
||||
| PCA9635_ERR_MODE | 0xFC | Invalid mode
|
||||
| PCA9635_ERR_REG | 0xFB | Invalid register
|
||||
| PCA9635_ERR_I2C | 0xFA | I2C communication error
|
||||
| Error code | Value | Description |
|
||||
|:--------------------|:-------:|:----------------------|
|
||||
| PCA9635_OK | 0x00 | Everything went well
|
||||
| PCA9635_ERROR | 0xFF | Generic error
|
||||
| PCA9635_ERR_WRITE | 0xFE | Tries to write more elements than PWM channels
|
||||
| PCA9635_ERR_CHAN | 0xFD | Channel out of range
|
||||
| PCA9635_ERR_MODE | 0xFC | Invalid mode
|
||||
| PCA9635_ERR_REG | 0xFB | Invalid register
|
||||
| PCA9635_ERR_I2C | 0xFA | I2C communication error
|
||||
|
||||
|
||||
### SUB CALL and ALL CALL
|
||||
## SUB CALL and ALL CALL
|
||||
|
||||
Please read the datasheet to understand the working of **SUB CALL** and **ALL CALL**.
|
||||
|
||||
@ -192,24 +195,56 @@ The functions to enable all/sub-addresses are straightforward:
|
||||
- **uint8_t getAllCallAddress()**
|
||||
|
||||
|
||||
## Operation
|
||||
#### OutputEnable
|
||||
|
||||
See examples
|
||||
Since 0.4.3 (experimental) support to control the OE (Output Enable) pin of the PCA9635.
|
||||
This OE pin can control all LEDs simultaneously. It also allows to
|
||||
control multiple PCA9635.
|
||||
Think of simultaneous switching ON/OFF of get dimming with a high frequency PWM.
|
||||
|
||||
See datasheet for the details
|
||||
|
||||
- **bool setOutputEnablePin(uint8_t pin = 255)** sets the IO pin to connect to the OE pin of the PCA9635.
|
||||
A value of 255 indicates no pin set/selected.
|
||||
Sets the OE pin to LOW.
|
||||
Returns true on success.
|
||||
- **bool setOutputEnable(uint8_t value)** Sets the OE pin HIGH or LOW.
|
||||
All non zero values are HIGH.
|
||||
Returns true on success.
|
||||
- **uint8_t getOutputEnable()** get the current value of the OE pin.
|
||||
If pin is not set/selected it will return LOW.
|
||||
|
||||
Note: the OE is LOW active. The user has to set the power on value
|
||||
by means of a PULL UP / DOWN resistor.
|
||||
|
||||
|
||||
## Future
|
||||
|
||||
#### must
|
||||
#### Must
|
||||
|
||||
- improve documentation
|
||||
|
||||
#### should
|
||||
#### Should
|
||||
|
||||
- move code from .h to .cpp
|
||||
- unit tests
|
||||
- SUB CALL if possible?
|
||||
- ALL CALL if possible?
|
||||
- add examples
|
||||
- improve error handling (0.5.0)
|
||||
- return values etc.
|
||||
- documentation.
|
||||
|
||||
|
||||
#### Could
|
||||
|
||||
#### could
|
||||
- sync with PCA9634 developments
|
||||
- merge with PCA9634 and a PCA963X base class if possible
|
||||
- restructure function groups
|
||||
- in .cpp to match .h
|
||||
- readme.md
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
//
|
||||
// FILE: PCA9635_OE_control.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: test PCA9635 library
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
#include "PCA9635.h"
|
||||
|
||||
|
||||
PCA9635 ledArray(0x20);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.print("PCA9635 LIB version: ");
|
||||
Serial.println(PCA9635_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
ledArray.begin();
|
||||
|
||||
// just one channel
|
||||
ledArray.write1(1, 100);
|
||||
|
||||
ledArray.setOutputEnablePin(12);
|
||||
ledArray.setOutputEnable(true);
|
||||
delay(1000);
|
||||
ledArray.setOutputEnable(false);
|
||||
delay(1000);
|
||||
ledArray.setOutputEnable(true);
|
||||
|
||||
// TODO elaborate
|
||||
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -38,9 +38,15 @@ enableAllCall KEYWORD2
|
||||
disableAllCall KEYWORD2
|
||||
isEnabledAllCall KEYWORD2
|
||||
|
||||
setOutputEnablePin KEYWORD2
|
||||
setOutputEnable KEYWORD2
|
||||
getOutputEnable KEYWORD2
|
||||
|
||||
#
|
||||
# Constants ( LITERAL1)
|
||||
#
|
||||
PCA9635_LIB_VERSION LITERAL1
|
||||
|
||||
PCA9635_OK LITERAL1
|
||||
PCA9635_ERROR LITERAL1
|
||||
PCA9635_ERR_WRITE LITERAL1
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/PCA9635.git"
|
||||
},
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.3",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PCA9635
|
||||
version=0.4.2
|
||||
version=0.4.3
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for PCA9635 I2C LED driver 16 channel
|
||||
|
@ -89,6 +89,33 @@ unittest(test_LedDriverMode)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_OutputEnable)
|
||||
{
|
||||
PCA9635 ledArray(0x20);
|
||||
|
||||
assertTrue(ledArray.begin());
|
||||
|
||||
assertEqual(HIGH, ledArray.getOutputEnable());
|
||||
|
||||
assertTrue(ledArray.setOutputEnablePin(12));
|
||||
assertEqual(HIGH, ledArray.getOutputEnable());
|
||||
|
||||
assertTrue(ledArray.setOutputEnable(true));
|
||||
assertEqual(LOW, ledArray.getOutputEnable());
|
||||
|
||||
assertTrue(ledArray.setOutputEnable(false));
|
||||
assertEqual(HIGH, ledArray.getOutputEnable());
|
||||
|
||||
assertTrue(ledArray.setOutputEnable(true));
|
||||
assertEqual(LOW, ledArray.getOutputEnable());
|
||||
|
||||
assertFalse(ledArray.setOutputEnablePin(255));
|
||||
assertEqual(HIGH, ledArray.getOutputEnable());
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user