0.2.8 PCA9634

This commit is contained in:
Rob Tillaart 2023-05-25 15:34:00 +02:00
parent 8aba6bb95d
commit 1e88244dfc
8 changed files with 104 additions and 69 deletions

View File

@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.8] - 2023-05-24
- renaming #defines PCA963X... to prepare merge with PCA9634.
- old defines will work until next major release
- update keywords.txt
- update readme.md
## [0.2.7] - 2023-05-01
- add **writeLedOut(reg, mask)** experimental
- add **readLedOut(reg)** experimental
@ -19,7 +26,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- update readme.md
- minor edits
## [0.2.6] - 2023-03-07
- add OutputEnable control functions.
- add example **PCA9634_OE_control.ino**

View File

@ -2,7 +2,7 @@
// FILE: PCA9634.cpp
// AUTHOR: Rob Tillaart
// DATE: 2022-01-03
// VERSION: 0.2.7
// VERSION: 0.2.8
// PURPOSE: Arduino library for PCA9634 I2C LED driver
// URL: https://github.com/RobTillaart/PCA9634
@ -310,9 +310,9 @@ bool PCA9634::enableSubCall(uint8_t nr)
if ((nr == 0) || (nr > 3)) return false;
uint8_t prev = getMode1();
uint8_t mask = prev;
if (nr == 1) mask |= PCA9634_MODE1_SUB1;
else if (nr == 2) mask |= PCA9634_MODE1_SUB2;
else mask |= PCA9634_MODE1_SUB3;
if (nr == 1) mask |= PCA963X_MODE1_SUB1;
else if (nr == 2) mask |= PCA963X_MODE1_SUB2;
else mask |= PCA963X_MODE1_SUB3;
// only update if changed.
if (mask != prev)
{
@ -328,9 +328,9 @@ bool PCA9634::disableSubCall(uint8_t nr)
if ((nr == 0) || (nr > 3)) return false;
uint8_t prev = getMode1();
uint8_t mask = prev;
if (nr == 1) mask &= ~PCA9634_MODE1_SUB1;
else if (nr == 2) mask &= ~PCA9634_MODE1_SUB2;
else mask &= ~PCA9634_MODE1_SUB3;
if (nr == 1) mask &= ~PCA963X_MODE1_SUB1;
else if (nr == 2) mask &= ~PCA963X_MODE1_SUB2;
else mask &= ~PCA963X_MODE1_SUB3;
// only update if changed.
if (mask != prev)
{
@ -345,9 +345,9 @@ bool PCA9634::isEnabledSubCall(uint8_t nr)
{
if ((nr == 0) || (nr > 3)) return false;
uint8_t mask = getMode1();
if (nr == 1) return (mask & PCA9634_MODE1_SUB1) > 0;
if (nr == 2) return (mask & PCA9634_MODE1_SUB2) > 0;
return (mask & PCA9634_MODE1_SUB3) > 0;
if (nr == 1) return (mask & PCA963X_MODE1_SUB1) > 0;
if (nr == 2) return (mask & PCA963X_MODE1_SUB2) > 0;
return (mask & PCA963X_MODE1_SUB3) > 0;
}
@ -358,7 +358,7 @@ bool PCA9634::setSubCallAddress(uint8_t nr, uint8_t address)
// _error = ?? TODO
return false;
}
writeReg(PCA9634_SUBADR(nr), address);
writeReg(PCA963X_SUBADR(nr), address);
return true;
}
@ -370,7 +370,7 @@ uint8_t PCA9634::getSubCallAddress(uint8_t nr)
// _error = ?? TODO
return 0;
}
uint8_t address = readReg(PCA9634_SUBADR(nr));
uint8_t address = readReg(PCA963X_SUBADR(nr));
return address;
}
@ -378,7 +378,7 @@ uint8_t PCA9634::getSubCallAddress(uint8_t nr)
bool PCA9634::enableAllCall()
{
uint8_t prev = getMode1();
uint8_t mask = prev | PCA9634_MODE1_ALLCALL;
uint8_t mask = prev | PCA963X_MODE1_ALLCALL;
// only update if changed.
if (mask != prev)
{
@ -392,7 +392,7 @@ bool PCA9634::enableAllCall()
bool PCA9634::disableAllCall()
{
uint8_t prev = getMode1();
uint8_t mask = prev & ~PCA9634_MODE1_ALLCALL;
uint8_t mask = prev & ~PCA963X_MODE1_ALLCALL;
// only update if changed.
if (mask != prev)
{
@ -406,20 +406,20 @@ bool PCA9634::disableAllCall()
bool PCA9634::isEnabledAllCall()
{
uint8_t mask = getMode1();
return mask & PCA9634_MODE1_ALLCALL;
return mask & PCA963X_MODE1_ALLCALL;
}
bool PCA9634::setAllCallAddress(uint8_t address)
{
writeReg(PCA9634_ALLCALLADR, address);
writeReg(PCA963X_ALLCALLADR, address);
return true;
}
uint8_t PCA9634::getAllCallAddress()
{
uint8_t address = readReg(PCA9634_ALLCALLADR);
uint8_t address = readReg(PCA963X_ALLCALLADR);
return address;
}

View File

@ -3,7 +3,7 @@
// FILE: PCA9634.h
// AUTHOR: Rob Tillaart
// DATE: 2022-01-03
// VERSION: 0.2.7
// VERSION: 0.2.8
// PURPOSE: Arduino library for PCA9634 I2C LED driver, 8 channel
// URL: https://github.com/RobTillaart/PCA9634
@ -12,7 +12,7 @@
#include "Wire.h"
#define PCA9634_LIB_VERSION (F("0.2.7"))
#define PCA9634_LIB_VERSION (F("0.2.8"))
// mode codes
@ -50,6 +50,7 @@
#define PCA9634_LEDPWM 0x02
#define PCA9634_LEDGRPPWM 0x03
// Error codes
// NEW
#define PCA963X_OK 0x00
@ -69,10 +70,18 @@
#define PCA9634_ERR_I2C 0xFA
// TODO PCA963X_ constants below here
// Configuration bits MODE1 register
// NEW
#define PCA963X_MODE1_AUTOINCR2 0x80 // ReadOnly, 0 = disable 1 = enable
#define PCA963X_MODE1_AUTOINCR1 0x40 // ReadOnly, bit1
#define PCA963X_MODE1_AUTOINCR0 0x20 // ReadOnly, bit0
#define PCA963X_MODE1_SLEEP 0x10 // 0 = normal 1 = sleep
#define PCA963X_MODE1_SUB1 0x08 // 0 = disable 1 = enable
#define PCA963X_MODE1_SUB2 0x04 // 0 = disable 1 = enable
#define PCA963X_MODE1_SUB3 0x02 // 0 = disable 1 = enable
#define PCA963X_MODE1_ALLCALL 0x01 // 0 = disable 1 = enable
#define PCA963X_MODE1_NONE 0x00
// OLD
#define PCA9634_MODE1_AUTOINCR2 0x80 // ReadOnly, 0 = disable 1 = enable
#define PCA9634_MODE1_AUTOINCR1 0x40 // ReadOnly, bit1
#define PCA9634_MODE1_AUTOINCR0 0x20 // ReadOnly, bit0
@ -85,6 +94,13 @@
// Configuration bits MODE2 register
// NEW
#define PCA963X_MODE2_BLINK 0x20 // 0 = dim 1 = blink
#define PCA963X_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
#define PCA963X_MODE2_ACK 0x08 // 0 = on STOP 1 = on ACK
#define PCA963X_MODE2_TOTEMPOLE 0x04 // 0 = open drain 1 = totem-pole
#define PCA963X_MODE2_NONE 0x00
// OLD
#define PCA9634_MODE2_BLINK 0x20 // 0 = dim 1 = blink
#define PCA9634_MODE2_INVERT 0x10 // 0 = normal 1 = inverted
#define PCA9634_MODE2_ACK 0x08 // 0 = on STOP 1 = on ACK
@ -93,11 +109,23 @@
// Registers in which the ALLCALL and sub-addresses are stored
#define PCA9634_SUBADR(x) (0x0D +(x)) // x = 1..3
// NEW
#define PCA963X_SUBADR(x) (0x0D +(x)) // x = 1..3
#define PCA963X_ALLCALLADR 0x11
// OLD
#define PCA9634_SUBADR(x) (0x0D +(x)) // x = 1..3
#define PCA9634_ALLCALLADR 0x11
// Standard ALLCALL and sub-addresses --> only work for write commands and NOT for read commands
// NEW
#define PCA963X_ALLCALL 0x70 // TDS of chip says 0xE0, however,
// in this library the LSB is added during the write command
// (0xE0 --> 0b11100000, 0x70 --> 0b1110000)
#define PCA963X_SUB1 0x71 // see line above (0xE2 --> 0x71)
#define PCA963X_SUB2 0x72 // see line above (0xE4 --> 0x72)
#define PCA963X_SUB3 0x74 // see line above (0xE8 --> 0x74)
// OLD
#define PCA9634_ALLCALL 0x70 // TDS of chip says 0xE0, however,
// in this library the LSB is added during the write command
// (0xE0 --> 0b11100000, 0x70 --> 0b1110000)
@ -117,11 +145,11 @@ public:
#if defined (ESP8266) || defined(ESP32)
bool begin(int sda, int scl,
uint8_t mode1_mask = PCA9634_MODE1_ALLCALL,
uint8_t mode2_mask = PCA9634_MODE2_NONE);
uint8_t mode1_mask = PCA963X_MODE1_ALLCALL,
uint8_t mode2_mask = PCA963X_MODE2_NONE);
#endif
bool begin(uint8_t mode1_mask = PCA9634_MODE1_ALLCALL,
uint8_t mode2_mask = PCA9634_MODE2_NONE);
bool begin(uint8_t mode1_mask = PCA963X_MODE1_ALLCALL,
uint8_t mode2_mask = PCA963X_MODE2_NONE);
bool isConnected();

View File

@ -37,10 +37,10 @@ of the PWM signal.
- **PCA9634(uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor with I2C device address,
and optional the Wire interface as parameter.
- **bool begin(uint8_t mode1_mask = PCA9634_MODE1_ALLCALL, uint8_t mode2_mask = PCA9634_MODE2_NONE)**
- **bool begin(uint8_t mode1_mask = PCA963X_MODE1_ALLCALL, uint8_t mode2_mask = PCA963X_MODE2_NONE)**
initializes the library after startup. Optionally setting the MODE1 and MODE2 configuration registers.
See PCA9634.h and datasheet for settings possible.
- **bool begin(int sda, int scl, uint8_t mode1_mask = PCA9634_MODE1_ALLCALL, uint8_t mode2_mask = PCA9634_MODE2_NONE)**
- **bool begin(int sda, int scl, uint8_t mode1_mask = PCA963X_MODE1_ALLCALL, uint8_t mode2_mask = PCA963X_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.
@ -101,25 +101,24 @@ useful to add or remove a single flag (bit masking).
#### Constants for mode registers
(added 0.1.2)
| Name | Value | Description |
|:--------------------------|:-------:|:-------------------------------------|
| PCA9634_MODE1_AUTOINCR2 | 0x80 | Read Only, 0 = disable 1 = enable |
| PCA9634_MODE1_AUTOINCR1 | 0x40 | Read Only, bit1 |
| PCA9634_MODE1_AUTOINCR0 | 0x20 | Read Only, bit0 |
| PCA9634_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
| PCA9634_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
| PCA9634_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
| PCA9634_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
| PCA9634_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
| PCA9634_MODE1_NONE | 0x00 | |
| PCA963X_MODE1_AUTOINCR2 | 0x80 | Read Only, 0 = disable 1 = enable |
| PCA963X_MODE1_AUTOINCR1 | 0x40 | Read Only, bit1 |
| PCA963X_MODE1_AUTOINCR0 | 0x20 | Read Only, bit0 |
| PCA963X_MODE1_SLEEP | 0x10 | 0 = normal 1 = sleep |
| PCA963X_MODE1_SUB1 | 0x08 | 0 = disable 1 = enable |
| PCA963X_MODE1_SUB2 | 0x04 | 0 = disable 1 = enable |
| PCA963X_MODE1_SUB3 | 0x02 | 0 = disable 1 = enable |
| PCA963X_MODE1_ALLCALL | 0x01 | 0 = disable 1 = enable |
| PCA963X_MODE1_NONE | 0x00 | |
| ---- | | |
| PCA9634_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
| PCA9634_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
| PCA9634_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
| PCA9634_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
| PCA9634_MODE2_NONE | 0x00 | |
| PCA963X_MODE2_BLINK | 0x20 | 0 = dim 1 = blink |
| PCA963X_MODE2_INVERT | 0x10 | 0 = normal 1 = inverted |
| PCA963X_MODE2_STOP | 0x08 | 0 = on STOP 1 = on ACK |
| PCA963X_MODE2_TOTEMPOLE | 0x04 | 0 = open drain 1 = totem-pole |
| PCA963X_MODE2_NONE | 0x00 | |
These constants makes it easier to set modes without using a non descriptive
@ -130,12 +129,12 @@ ledArray.writeMode(PCA963X_MODE2, 0b00110100);
// would become
uint8_t mode2_mask = PCA9634_MODE2_BLINK | PCA9634_MODE2_INVERT | PCA9634_MODE2_TOTEMPOLE;
uint8_t mode2_mask = PCA963X_MODE2_BLINK | PCA963X_MODE2_INVERT | PCA963X_MODE2_TOTEMPOLE;
ledArray.writeMode(PCA963X_MODE2, mode2_mask);
// or even
ledArray.setMode2(PCA9634_MODE2_BLINK | PCA9634_MODE2_INVERT | PCA9634_MODE2_TOTEMPOLE);
ledArray.setMode2(PCA963X_MODE2_BLINK | PCA963X_MODE2_INVERT | PCA963X_MODE2_TOTEMPOLE);
```
@ -210,13 +209,13 @@ The functions to enable all/sub-addresses are straightforward:
Since 0.2.6 (experimental) support to control the OE (Output Enable) pin of the PCA9634.
This OE pin can control all LEDs simultaneously.
It also allows to control multiple PCA9634 modules by connecting the OE pins.
It also allows to control multiple devices by connecting the OE pins.
Think of simultaneous switching ON/OFF or get dimming with a high frequency PWM.
Or use 2 modules alternatively by placing an inverter in between.
See datasheet for the details
- **bool setOutputEnablePin(uint8_t pin = 255)** sets the IO pin to connect to the OE pin of the PCA9634.
- **bool setOutputEnablePin(uint8_t pin = 255)** sets the IO pin to connect to the OE pin of the device.
A value of 255 indicates no pin set/selected.
Sets the OE pin to HIGH.
Returns true on success.
@ -298,7 +297,7 @@ PCA.writeLedOut(1, mask);
In scenarios in which multiple LED states should be updated synchronously, the datasheet specifies a specific sequence.
Therefore, it is possible to update multiple LED registers in one or more PCA963x chips synchronously and have them
change their state at a final STOP command. For this only a few configurations are required.
1. Make sure, the `PCA9634_MODE2_ACK` bit in the `MODE2` register is not set (it should be set to 0).
1. Make sure, the `PCA963X_MODE2_ACK` bit in the `MODE2` register is not set (it should be set to 0).
Therefore, the LED states will be updated at the STOP command of the I2C master and not during the ACK command of the PCA963x slave
2. Do NOT use the `write1()`, `write3()` or `writeN()` functions for changing LED states.
These commands already include a STOP command.
@ -340,19 +339,21 @@ when all previously send commands since the last STOP command will be executed.
- read/writeLedOut()
- **setOutputEnablePWM(uint16_t value)** PWM support ?
- getter?
- merge with PCA9635 and a PCA963X base class if possible
- restructure function groups
- in .cpp to match .h
- readme.md
- **setGroupPWM()**
- PWM also in %% ?
- **setGroupFreq()**
- set time in milliseconds and round to nearest value?
#### Wont
- consider implementing
- clearMode1() and clearMode2() functions.
- only upon request.
- merge with PCA9634/5 and a PCA963X base class if possible
- not easy, more alignment is desirable.
- only upon request.
- **setGroupPWM()**
- PWM also in %% ? (trivial for user)

Binary file not shown.

View File

@ -61,21 +61,21 @@ PCA963X_ERR_MODE LITERAL1
PCA963X_ERR_REG LITERAL1
PCA963X_ERR_I2C LITERAL1
PCA9634_MODE1_AUTOINCR2 LITERAL1
PCA9634_MODE1_AUTOINCR1 LITERAL1
PCA9634_MODE1_AUTOINCR0 LITERAL1
PCA9634_MODE1_SLEEP LITERAL1
PCA9634_MODE1_SUB1 LITERAL1
PCA9634_MODE1_SUB2 LITERAL1
PCA9634_MODE1_SUB3 LITERAL1
PCA9634_MODE1_ALLCALL LITERAL1
PCA9634_MODE1_NONE LITERAL1
PCA963X_MODE1_AUTOINCR2 LITERAL1
PCA963X_MODE1_AUTOINCR1 LITERAL1
PCA963X_MODE1_AUTOINCR0 LITERAL1
PCA963X_MODE1_SLEEP LITERAL1
PCA963X_MODE1_SUB1 LITERAL1
PCA963X_MODE1_SUB2 LITERAL1
PCA963X_MODE1_SUB3 LITERAL1
PCA963X_MODE1_ALLCALL LITERAL1
PCA963X_MODE1_NONE LITERAL1
PCA9634_MODE2_BLINK LITERAL1
PCA9634_MODE2_INVERT LITERAL1
PCA9634_MODE2_ACK LITERAL1
PCA9634_MODE2_TOTEMPOLE LITERAL1
PCA9634_MODE2_NONE LITERAL1
PCA963X_MODE2_BLINK LITERAL1
PCA963X_MODE2_INVERT LITERAL1
PCA963X_MODE2_ACK LITERAL1
PCA963X_MODE2_TOTEMPOLE LITERAL1
PCA963X_MODE2_NONE LITERAL1
PCA963X_LEDOFF LITERAL1
PCA963X_LEDON LITERAL1

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/PCA9634.git"
},
"version": "0.2.7",
"version": "0.2.8",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=PCA9634
version=0.2.7
version=0.2.8
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for PCA9634 I2C LED driver 8 channel