0.2.1 TLC5917

This commit is contained in:
Rob Tillaart 2024-09-24 14:41:56 +02:00
parent 054d79afa9
commit 090aa0cf8a
16 changed files with 224 additions and 37 deletions

View File

@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.1] - 2024-09-24
- Fix #11, add schema to readme and examples
- update keywords.txt
- implement return type **int write(..)**
- fix channel test in **write()**
- update readme.md
## [0.2.0] - 2024-07-12
- fix deviceCount in **write()**.
- fix allocation buffer for channels in constructor.

View File

@ -11,7 +11,7 @@
# TLC5917
TLC5917 is an Arduino library for TLC5917 8-Channel Constant-Current LED Sink Drivers.
Arduino library for TLC5917 8-Channel Constant-Current LED Sink Drivers.
## Description
@ -24,10 +24,10 @@ This library also support more than one device in a daisy chain (see below).
The library allows to set the channels (outputs) on/off individually or as a group in one call.
Furthermore it allows to set a current gain for all devices connected.
The **TLC5916** is a derived class that is functional identical to the TLC5917.
The **TLC5916** is a derived class that is functional identical to the **TLC5917**.
When implementation proceeds this might change, the difference is in support for fetching
the status and error modi. This functionality is not supported by the library yet,
so there is no difference between the **TLC5916** and **TLC5917** for now.
the status and error modi. As this functionality is not supported by the library yet,
there is no difference between the **TLC5916** and **TLC5917** for now.
The library needs more testing with hardware.
Please share your experiences.
@ -35,11 +35,30 @@ Please share your experiences.
(Changes of the interface are definitely possible).
### Schema
Always check the datasheet!
```
TLC5917
+----u----+
GND | 1 16 | VDD
SDI | 2 15 | R-EXT
CLK | 3 14 | SDO
LE | 4 13 | OE
OUT0 | 5 12 | OUT7
OUT1 | 6 11 | OUT6
OUT2 | 7 10 | OUT5
OUT3 | 8 09 | OUT4
+---------+
```
### Breaking changes
The 0.2.0 version fixed an internal storage bug which allocated way to much memory
in version 0.1.x. So these versions can be considered obsolete.
The performance of the library **write()** call improved a lot.
in version 0.1.x. So the pre 0.2.0 versions can be considered obsolete.
The performance of the **write()** call improved a lot.
### Daisy chaining
@ -48,7 +67,7 @@ This library supports daisy chaining of multiple **TLC5917** modules.
A constructor takes the number of devices as parameter and
an internal buffer is allocated (8 channels per device).
This internal buffer is clocked into the devices with the **write()** call.
So **setChannel()** calls can be changed until last moment.
So **setChannel()** calls can change this buffer until last moment before **write()**
### Related
@ -70,7 +89,7 @@ So **setChannel()** calls can be changed until last moment.
### Constructor
- **TLC5917(uint8_t clock, uint8_t data, uint8_t latch, uint8_t outputEnable)** constructor.
Single device constructor.
Single device constructor, latch = LE pin, outputEnable = OE pin (see above).
Defines the pins used for uploading / writing the data to the device.
The outputEnable pin is explained in more detail below.
- **TLC5917(int deviceCount, uint8_t clock, uint8_t data, uint8_t latch, uint8_t outputEnable)** constructor.
@ -81,8 +100,8 @@ The outputEnable pin is explained in more detail below.
### Base
- **bool begin()** set the pinMode of the pins used and their initial values.
The TLC5917 is disabled by default, as the device has random values in its register.
- **bool begin()** sets the pinMode of the pins used and their initial values.
The TLC5917 module is disabled by default, as the device has random values in its registers.
Therefore one must call **enable()** explicitly.
- **int channelCount()** return the amount of channels == 8 x number of devices.
@ -92,16 +111,29 @@ Therefore one must call **enable()** explicitly.
- **bool setChannel(uint8_t channel, bool on)** set a channel on or off in the
internal buffer. The value is not written immediately to the device(s).
One has to call **write()** for that.
Returns false if **channel** is out of range.
- **bool setChannel(uint8_t \* array)** copy a preset of channel settings in one call.
The user has to take care that the size of array holds the right amount of bytes.
Typical amount is deviceCount (or more).
Will always return true for now.
- **bool setAll(bool on)** set all channels on or off.
- **bool getChannel(uint8_t channel)** get current state of a channel from the cached buffer.
- **void write()** writes the whole buffer (deviceCount x 8 values) to the device(s).
- **void write(int channels)** writes a part of the internal buffer (only **channels** values) to the device.
Will always return true for now.
- **bool getChannel(uint8_t channel)** returns current state of a channel from the
cached buffer. This might differ from the actual device state if channels have been
changed without a **write()**.
Returns false if **channel** is out of range.
### Write
- **int write()** writes the whole internal buffer (deviceCount x 8 values) to the device(s).
Returns the number of channels written (0 .. channelCount).
- **int write(int channels)** writes a part of the internal buffer (only **channels** values)
to the device.
Typical used to speed up if less than max number e.g. only 17 channels are used
and needs to be updated.
and needs to be updated.
**experimental, might have side effects**
Returns the number of channels written (0 .. channelCount).
**write()** must be called after setting all values one wants to change.
@ -110,7 +142,7 @@ channels as fast as possible.
See also **TLC5917_performance.ino** for an indication of time needed.
### OutputEnable line
### OutputEnable
The **outputEnable** pin (OE or blank) is used to set all channels on or off.
This allows to "preload" the registers with values and enable them all at once
@ -121,19 +153,20 @@ Default a TLC device is disabled, by **begin()**, so one should enable it "manua
- **void enable()** all channels reflect last values written.
- **void disable()** all channels are off / 0.
- **bool isEnabled()** returns status of outputEnable line.
- **bool isEnabled()** returns status of outputEnable **OE** line.
The library only supports one **enable() line**.
If you want a separate **enable()** per device you might need to connect the devices
"in parallel" instead of "in series" (daisy chained).
The outputEnable parameter in the constructor should be set to -1 (out of range value).
#### PWM
It might be possible to use a PWM pin on the **outputEnable** line to dim the LEDS.
It might be possible to use a PWM signal on the **outputEnable** pin to dim the LEDS.
This is neither tested nor supported by the library.
Note that writing to the TLC5917 needs a HIGH **outputEnable** so the PWM value needs
to be set again.
to be set again after each **write()**.
### Configure gain
@ -144,7 +177,7 @@ See datasheet page 23 for details.
- **void setSpecialMode()** switch to special mode to configure the gain.
Note that calling **setSpecialMode()** and **setNormalMode()** disables the output.
So one should enable it again if one wants to.
So one should **enable()** the output again if one wants to.
The special mode needs to be set for the following functions:
@ -161,8 +194,8 @@ Over the range 0.250 - 2.989 the max error is 0.0124
Over the range 2.989 - 3.000 the max error goes up to 0.023
So except for end of the range the error is (IMHO) small.
Returns false if out of range (n < 0.250 or n > 3.0).
- **float getVoltageGain()** see below (from cache).
- **float getCurrentGain()** see below (from cache).
- **float getVoltageGain()** see below (returns value from cache).
- **float getCurrentGain()** see below (returns value from cache).
| bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
@ -170,6 +203,7 @@ Returns false if out of range (n < 0.250 or n > 3.0).
| abbrev | CM | HC | CC0 | CC1 | CC2 | CC3 | CC4 | CC5 |
| default | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
CM == Current Multiplier
- limits the output current range.
- Low (CM = 0): 3 mA to 40 mA.
@ -199,6 +233,7 @@ and issue #9 for the LGT8F328 data
Timing in microseconds, 800 channels = 100 devices.
| Version | Function | UNO 1.8.19 | LGT8F328 | other |
|:-------:|:-----------------|:----------:|:--------:|:--------:|
| 0.2.0 | SETCHANNEL TRUE | 2572 | 1152 |
@ -207,9 +242,14 @@ Timing in microseconds, 800 channels = 100 devices.
| 0.2.0 | SETALL FALSE | 232 | - |
| 0.2.0 | WRITE optimized | 1772 | - |
| 0.2.0 | WRITE normal | 9420 | - |
| 0.2.1 | WRITE optimized | 1832 | - |
| 0.2.1 | WRITE normal | 9484 | - |
_The "WRITE optimized" is AVR only._
The 0.2.1 is slightly slower (~3%), probably due to added return values.
So setting and writing 8 channels (e.g. a single 7 segment display) takes
28.40 + 17.72 = 46.12 < 50 microseconds.
So in theory an UNO could update it roughly 20K times per second.
@ -221,10 +261,11 @@ First investigations show that **write()** could be a hardware SPI transaction.
However the **setNormalMode()**, **setSpecialMode()** and especially the
**writeConfiguration()** function are no standard 8 bit SPI transactions.
This of course includes the **gain** functions that use these.
To solve this one still has to provide the CLOCK, LATCH and OUTPUT ENABLE pins.
Especially the CLOCK pin is part of the SPI pins, and it would depend on the
board and optional number of HW SPI ports of the board.
To prevent this complexity the library does not have a hardware SPI constructor.
To prevent this complexity the library does not have a hardware SPI constructor.
It looks like it is possible to create a simplified class (stripped version)
without the gain control that might work well with HW SPI for many application.
@ -245,6 +286,11 @@ The added value is however limited as the (optimized) SW is pretty fast already.
- what is clock in practice (e.g. an ESP32 240 MHz)
- now the CurrentGain is set to the same value for all devices.
- needs array, one value (uint8_t) per device, investigate.
- investigate device count and channels unsigned int?
- use channel count in constructor, might be more correct as device count
as one could use e.g. 21 channels explicitly. Would prevent overflows
better. Impact on code?
- need to write section about latch enable LE line?
#### Could
@ -252,6 +298,10 @@ The added value is however limited as the (optimized) SW is pretty fast already.
- reading error codes from SDO
- do brightness test with analogWrite(OE, value);
- it would be mandatory to have OE be a PWM pin.
- return values for enable/disable?
- track "dirty cache", e.g. changed channels are not written yet.
- e.g. **bool writePending()**
- user can track this quite easily.
#### Wont (unless needed)
@ -260,7 +310,7 @@ The added value is however limited as the (optimized) SW is pretty fast already.
- **void getChannel(uint8_t \* array)** fill an array with current data.
- error handling in special mode
- over-temperature, open-load, short to GND, short to VLED (TLC5917 only).
- implement hardware SPI, see above.
- implement hardware SPI simplified class, see section above.
## Support

View File

@ -1,7 +1,7 @@
//
// FILE: TLC5917.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.0
// VERSION: 0.2.1
// DATE: 2024-03-17
// PURPOSE: Arduino library for TLC5917 8-Channel Constant-Current LED Sink Drivers.
// URL: https://github.com/RobTillaart/TLC5917
@ -102,21 +102,22 @@ bool TLC5917::getChannel(uint8_t channel)
//
// MAX speed single device 30 MHz
// multi device 15 MHz CHECK TODO
void TLC5917::write()
int TLC5917::write()
{
write(_channelCount);
return write(_channelCount);
}
void TLC5917::write(int channels)
int TLC5917::write(int channels)
{
if (channels < 0) return;
if (channels <= 0) return 0;
int devices = (channels > _channelCount) ? _channelCount / 8 : channels / 8;
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
// register level optimized AVR
// check FastShiftOut for more optimizations if needed.
uint8_t port = digitalPinToPort(_data);
volatile uint8_t *_dataOutRegister = portOutputRegister(port);
uint8_t outmask1 = digitalPinToBitMask(_data);
@ -167,6 +168,7 @@ void TLC5917::write(int channels)
// pulse latch to hold the signals
digitalWrite(_le, HIGH);
digitalWrite(_le, LOW);
return channels;
}
@ -260,6 +262,7 @@ uint8_t TLC5917::getMode()
// 9.4.3 Writing Configuration Code in Special Mode
// no AVR optimized version as fucntion is not often used (assumption).
void TLC5917::writeConfiguration(uint8_t configuration)
{
uint8_t _clk = _clock;

View File

@ -2,13 +2,13 @@
//
// FILE: TLC5917.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.0
// VERSION: 0.2.1
// DATE: 2024-03-17
// PURPOSE: Arduino library for TLC5917 8-Channel Constant-Current LED Sink Drivers.
// URL: https://github.com/RobTillaart/TLC5917
#define TLC5917_LIB_VERSION (F("0.2.0"))
#define TLC5917_LIB_VERSION (F("0.2.1"))
#include "Arduino.h"
@ -42,7 +42,7 @@ public:
// LE = Latch Enable
// OE = Output Enable
TLC5917(uint8_t clock, uint8_t data, uint8_t LE, uint8_t OE);
// multi device constructor
// multi device constructor
// - for daisy chaining
TLC5917(int deviceCount, uint8_t clock, uint8_t data, uint8_t LE, uint8_t OE);
virtual ~TLC5917();
@ -58,13 +58,13 @@ public:
bool getChannel(uint8_t channel);
// write the internal buffer to the TLC5917 device(s).
void write(int channels);
void write();
int write(int channels);
int write();
// control the outputEnable (OE) line.
void enable();
void disable();
bool isEnabled(); // returns status
bool isEnabled(); // returns status OE line
// GAIN configuration mode
// TODO test if this works for single device.

View File

@ -5,6 +5,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -5,6 +5,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -6,6 +6,20 @@
//
// needs investigation.
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -5,6 +5,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -6,6 +6,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -5,6 +5,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -16,7 +16,7 @@ Done...
(default write() on UNO for reference)
TLC5917_LIB_VERSION: 0.1.3
TLC5917_LIB_VERSION: 0.2.0
Channels: 800
SETCHANNEL TRUE: 2572

View File

@ -0,0 +1,31 @@
Arduino UNO
IDE: 1.8.19
(AVR optimized write() on UNO)
TLC5917_performance\TLC5917_performance.ino
TLC5917_LIB_VERSION: 0.2.1
Channels: 800
SETCHANNEL TRUE: 2572
SETCHANNEL FALSE: 2848
SETALL TRUE: 236
SETALL FALSE: 236
WRITE: 1832
Done...
(default write() on UNO for reference)
TLC5917_LIB_VERSION: 0.2.1
Channels: 800
SETCHANNEL TRUE: 2572
SETCHANNEL FALSE: 2844
SETALL TRUE: 228
SETALL FALSE: 232
WRITE: 9484
Done...

View File

@ -5,6 +5,19 @@
// URL: https://github.com/RobTillaart/TLC5917
// TLC5917
// +----u----+
// GND | 1 16 | VDD
// SDI | 2 15 | R-EXT
// CLK | 3 14 | SDO
// LE | 4 13 | OE
// OUT0 | 5 12 | OUT7
// OUT1 | 6 11 | OUT6
// OUT2 | 7 10 | OUT5
// OUT3 | 8 09 | OUT4
// +---------+
#include "TLC5917.h"

View File

@ -22,8 +22,11 @@ isEnabled KEYWORD2
setSpecialMode KEYWORD2
setNormalMode KEYWORD2
getMode KEYWORD2
writeConfiguration KEYWORD2
getConfiguration KEYWORD2
setGain KEYWORD2
setCurrentGain KEYWORD2
getVoltageGain KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/TLC5917.git"
},
"version": "0.2.0",
"version": "0.2.1",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=TLC5917
version=0.2.0
version=0.2.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for TLC5917 8-Channel Constant-Current LED Sink Drivers.