148 lines
5.1 KiB
Markdown
Raw Normal View History

2023-06-18 10:51:50 +02:00
[![Arduino CI](https://github.com/RobTillaart/TLC5947/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/TLC5947/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/TLC5947/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/TLC5947/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/TLC5947/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/TLC5947/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/TLC5947.svg?maxAge=3600)](https://github.com/RobTillaart/TLC5947/releases)
# TLC5947
2023-06-22 17:44:23 +02:00
TLC5947 is an Arduino library for the TLC5947, 24 channel 12 bit, PWM module.
2023-06-18 10:51:50 +02:00
## Description
2023-06-22 17:44:23 +02:00
This experimental library allows easy control over a TLC5947 module.
To communicate this module uses three (bit banging) serial lines.
The TLC5947 module provides in total 24 outputs of 12 bit PWM.
2023-06-18 10:51:50 +02:00
So it allows 4096 greyscales or levels to be set, making the output pretty well tunable.
Main purpose is to drive LED's, see datasheet.
2023-06-22 17:44:23 +02:00
The library is experimental and needs more testing, so please share your experiences.
2023-06-18 10:51:50 +02:00
(changes of the interface are definitely possible).
#### Daisy chaining
2023-06-22 17:44:23 +02:00
This library does **NOT** support daisy chaining (yet).
2023-06-18 10:51:50 +02:00
The current version can control only 1 module.
2023-06-22 17:44:23 +02:00
To control multiple modules, you need to give them their own **clock** line,
and preferable their own latch line.
The data can be shared (to be tested) as data won't be clocked in if
the **clock** line is not shared.
2023-06-18 10:51:50 +02:00
#### Links
- https://www.adafruit.com/product/1429
- https://github.com/RobTillaart/TLC5947
- https://github.com/RobTillaart/PCA9634 (I2C)
- https://github.com/RobTillaart/PCA9635 (I2C)
- https://github.com/RobTillaart/PCA9685 (I2C)
## Interface
```cpp
#include TLC5947.h
```
- **TLC5947(uint8_t clock, uint8_t data, uint8_t latch, uint8_t blank)** constructor.
Defines the pins used for uploading / writing the PWM data to the module.
The blank pin is explained in more detail below.
- **~TLC5947()** destructor
- **bool begin()** set the pinModes of the pins and their initial values.
2023-06-22 17:44:23 +02:00
- **bool setPWM(uint8_t channel, uint16_t PWM)**. set a PWM value to the buffer to
be written later.
channel = 0..23, PWM = 0..4095
Returns true if successful.
- **void setAll(uint16_t PWM)** set the same PWM value for all channels to the buffer, and writes them to device.
2023-06-18 10:51:50 +02:00
- **uint16_t getPWM(uint8_t channel)** get PWM value from the buffer,
Note this value might differ from device when a new value is set after the last **write()**.
- **void write()** writes the buffer (24 x 12 bit) to the device.
2023-06-22 17:44:23 +02:00
#### Percentage wrappers
Wrapper functions to set the device in percentages.
The accuracy of these functions is about 1/4095 = ~0.025%.
Note: the percentages will be rounded to the nearest integer PWM value.
- **bool setPercentage(uint8_t channel, float perc)** wrapper setPWM().
channel = 0..23, perc = 0.0 .. 100.0
Returns true if successful.
- **void setPercentageAll(float perc)** wrapper setAll().
- **float getPercentage(uint8_t channel)** wrapper getPWM().
Note: the error code 0xFFFF will return as 1600%.
2023-06-18 10:51:50 +02:00
#### Blank line
The blank pin (line) is used to set all channels on or off.
This allows to "preload" the registers with values and enable them all at once.
- **void enable()** all channels reflect last updated PWM value.
- **void disable()** all channels are off / 0.
## Performance
Writing 24 x 12 bit takes time, however is still pretty fast.
On a 16 MHz UNO writing all 24 channels takes less than 4 milliseconds.
Note that all channels must be written.
| platform (MHz) | version | command | time (us) | notes |
|:----------------:|:---------:|:----------|:------------|:-------------|
| AVR/UNO (16) | 0.1.0 | setPWM() | 16 | 24 channels |
| AVR/UNO (16) | 0.1.0 | write() | 3808 | 24 channels |
2023-06-22 17:44:23 +02:00
| AVR/UNO (16) | 0.1.1 | setPWM() | 16 | 24 channels |
| AVR/UNO (16) | 0.1.1 | write() | 804 | 24 channels |
2023-06-18 10:51:50 +02:00
| ESP32 (240) | 0.1.0 | setPWM() | 6 | 24 channels |
| ESP32 (240) | 0.1.0 | write() | 128 | 24 channels |
Measured with **TLC5947_performance.ino**.
## Future
#### Must
- update documentation
- links etc.
2023-06-22 17:44:23 +02:00
- schema for multiple devices
2023-06-18 10:51:50 +02:00
- buy hardware
- test test test
#### Should
- add examples
- extend performance sketch
- test if partial write (e.g. first N channels) works.
- test "preloading" when module is disabled.
- "dirty" flag for **bool writePending()**?
- set by **setPWM()** if value changes.
- would speed up unneeded **write()** too.
#### Could
- add unit-tests
- add **void setPercentage(float perc)** and **float getPercentage()** wrappers.
- investigate how to reduce memory usage (now 48 bytes)
- could be 36 (12 bits / channel) or even 24 (8 bits/channel)
- derived class?
- add **setRGB(LED, R, G, B)** wrapper (channel 0..7)
24 channels == 3 x 8 RGB LEDs
- return value for **setPWM()** ?
#### Won't