High Level interface to a single TLC59116 using Wire (I2C) interface.
(see TLC59116_Unmanaged for lower level library)
Usage:
#include <Wire.h>
void setup() {
}
void loop() {
static TLC59116 &left_arm = tlcmanager[0];
}
There are examples in the Arduino IDE examples, and of course, the download site https://github.com/2splat/arduino-TLC59116 .
This high-level interface tracks each device's state so that commands appear to be independant. For example, you can set the digital-on of a channel without worrying about the other 4 mode settings in each LEDOUTx_Register.
Some optimization of the data sent to the devices is also done.
See the TI spec sheet for much detail: http://www.ti.com/lit/ds/symlink/tlc59116.pdf
- Output pins ("channels") are numbered 0..15.
- Channels are "sinks", acting like Arduino pins that are LOW, even for PWM.
- Connect the minus side of LEDs to the output pins.
- Instead of HIGH/LOW like DigitalWrite(), we use on/off/set.
- Channels are considered ON, OFF, , instead of HIGH/LOW (or, at some PWM value)
- PWM is 8 bit.
- I2C addresses start at 0x60. See TLC59116_Unmanaged for the available addresses (up to 14).
- The device provides a constant-current control (external and software settable). This means you can set the current, usually leave out resistors on each LED/channel, and is more efficient. See also, TLC59116::milliamps().
- This library discovers the devices on the I2C bus and keeps them in a list.
- Use the index in this library: e.g. "0" is the device with the lowest address, "1" is the next highest, etc.
- This library exposes I2C addresses as 7bit addresses.
- Individual devices cannot be "reset", all devices on the I2C bus are affected by a reset.
- By default, all devices respond to broadcast ("allcall") commands (a special address).
- See the various groupings of the functions (below) for functionality.
Protocol:
- Setting up
- Declare a static TLC59116Manager (static scope, or "static" keyword if you are very clever)
- Initialize the serial-output e.g.
Serial.begin(9600)
- This library will warn you about some mistakes or dubious usages.
- You don't have to setup the serial-output, but then you won't see the warnings.
- I like to set the speed to 115200, because at that setting it has little effect on the speed of your program.
- Execute .init() for the manager once, usually in setup()
void setup() {
Serial.begin(9600);
- The devices will then be in a ready state (by default, outputs are enabled, but all channels are off)
- Obtain a reference from yourmanager[i], for i from 0..device_count()-1
- This library passes and returns references so that "." can always be used.
void loop() {
static TLC59116 &first_device = tlcmanager[0];
- Get information about the device as needed from the Info Functions
Serial.print("First device is at ");
Serial.println(tlcmanager[0].
address());
- Set device Global Functions, Group/Broadcast Addresses, Software Current Control, typically in setup()
tlcmanager[4].allcall_address(false);
- Do initial Digital Functions, PWM Functions, typically in setup()
tlcmanager[0].pwm(13, 128);
- During loop, mess with Global Functions, Group/Broadcast Addresses, Software Current Control, Digital Functions, PWM Functions
- This library returns the device-reference for most calls, so you can chain functions, e.g.:
tlcmanager[0].on(1).pwm(2,128).pwm(3,14, 50).delay(200).off(1).delay(200).set_outputs(0x0000);
|
void | _begin_trans (byte register_num) |
|
void | _begin_trans (byte auto_mode, byte register_num) |
|
int | _end_trans () |
|
byte | control_register (byte register_num) |
|
void | control_register (byte register_num, byte data) |
|
void | control_register (byte count, const byte *register_num, const byte data[]) |
|
TLC59116_Unmanaged & | describe_actual () |
|
byte | fetch_registers (byte start_r, byte count, byte registers[]) |
|
void | get_control_registers (byte count, const byte *register_num, byte data[]) |
|
bool | is_OSC_bit (byte mode1_value) |
|
bool | is_SUBADR_bit (byte mode1_value, byte which) |
|
|
Controlling various global features of the device (see also, the "Software Current Control" section)
|
virtual TLC59116 & | enable_outputs (bool yes=true, bool with_delay=true) |
| Master power switch (the TLC59116Manager sets this on/true by default) More...
|
|
bool | is_enable_outputs () |
| Is master power on? More...
|
|
bool | is_enabled () |
|
|
Analogous to DigitalWrite.
Arduino DigitalWrite uses HIGH and LOW, but the device is a "sink", so "on" is actually a LOW. Thus, this library uses "on" and "off" for terminology.
There are several aliases, and overloaded functions here (and for the pwm functions below). The intention was to provide natural overloads and aliases. I've shied away from using the Arduino DigitalWrite and AnalogWrite so far.
These functions only change the specified channels, they'll leave other outputs, like a PWM channel alone.
You can have some channels doing PWM, and some channels doing digital.
|
TLC59116 & | set_outputs (word pattern, word which) |
| Only change the channels (that are marked in bit_which) to on/off as marked in bit_pattern More...
|
|
TLC59116 & | pattern (word bit_pattern, word bit_which=0xFFFF) |
| Alias for set_outputs() More...
|
|
TLC59116 & | on_pattern (word pattern) |
| Turn on by bit pattern. More...
|
|
TLC59116 & | off_pattern (word pattern) |
| Turn off by bit pattern. More...
|
|
TLC59116 & | set (int led_num, bool offon) |
| Turn one on/off, much like DigitalWrite. More...
|
|
TLC59116 & | on (int led_num) |
| Turn one on. More...
|
|
TLC59116 & | off (int led_num) |
| Turn one off. More...
|
|
|
Analogous to AnalogWrite
You can have some channels doing PWM, and some channels doing digital.
Remember, the device is a "sink", even for PWM. Minus side of LED goes to the output pin.
- Bug:
- Be careful with start/end arguments, if they are out of range (0..15) you will have mysterious problems.
- Todo:
- Put in range checking
|
TLC59116 & | set_outputs (byte led_num_start, byte led_num_end, const byte brightness[]) |
| PWM, start..end, list-of-brightness. More...
|
|
TLC59116 & | pwm (byte led_num_start, byte led_num_end, const byte brightness[]) |
| Alias of set_outputs() above. More...
|
|
TLC59116 & | pwm (byte led_num_start, byte led_num_end, byte pwm_value) |
| PWM, start..end same brightness. More...
|
|
TLC59116 & | set_outputs (const byte brightness[16]) |
| Set all 16 PWM according to the brightness list. More...
|
|
TLC59116 & | pwm (const byte(&brightness)[16]) |
| Set all 16 PWM according to the brightness list, same as above. More...
|
|
TLC59116 & | pwm (byte led_num, byte brightness) |
| PWM for one channel. More...
|
|
|
- Warning
- The TLC59116 has a hardware bug:
If you decrease the value (blink_time or brightness) in these functions, the chip may act like the value is max for one "cycle". This causes a full-brightness result for group_pwm, and a 10 second blink-length for group_blink. I think this is because:
- There is a continously running timer, counting up.
- The "value" is compared to the timer, and triggers the action and a reset of the timer.
- If you move the "value" down, you may skip over the current timer value, so it runs to the maximum value before wrapping around again. "reset" is the only thing that I know of that will reset the timer. But, more experimentation is needed.
I recommend you only set group functions once (or only increase values).
Of course, you could TLC59116Manager::reset() everytime, too.
|
TLC59116 & | group_pwm (word bit_pattern, byte brightness) |
|
TLC59116 & | group_blink (byte blink_period, byte on_ratio=128) |
| Blink all the LEDs, at their current/last PWM setting. More...
|
|
TLC59116 & | group_blink (word bit_pattern, int blink_delay, int on_ratio=128) |
|
TLC59116 & | group_blink (double blink_length_secs, double on_percent=50.0) |
|
TLC59116 & | group_blink (word bit_pattern, double blink_length_secs, double on_percent=50.0) |
|
TLC59116 & | group_blink (unsigned int bit_pattern, int blink_length_secs, double on_percent=50.0) |
|
|
Addresses for broadcast (allcall_address) and group-broadcase (SUBADR_x).
Addresses should be specified as 0x60..0x6F.
It is illegal to set any address to Reset_Addr (0x6B), it will be ignored with warning.
|
byte | Reset_address () |
| The reset-address, unchangeable. More...
|
|
byte | allcall_address () |
| Get broadcast address, see below to set/enable. More...
|
|
TLC59116 & | allcall_address (byte address, bool enable=true) |
| Set and enable/disable the broadcast address (allcall_addr). More...
|
|
TLC59116 & | allcall_address_enable () |
| Enable broadcast. More...
|
|
TLC59116 & | allcall_address_disable () |
| Disable broadcast. More...
|
|
bool | is_allcall_address () |
| Is broadcast enabled? More...
|
|
byte | SUBADR_address (byte which) |
| Get the SUBADR_n address. More...
|
|
bool | is_SUBADR_address (byte which) |
| Is SUBADR_n enabled? More...
|
|
TLC59116 & | SUBADR_address (byte which, byte address, bool enable=true) |
| Set the SUBADR_n address. More...
|
|
TLC59116 & | SUBADR_address_enable (byte which) |
| Enable SUBADR_n. More...
|
|
TLC59116 & | SUBADR_address_disable (byte which) |
|
|
TLC59116 & | set_milliamps (byte ma, int Rext=Rext_Min) |
|
int | milliamps (int Rext=Rext_Min) |
|
|
Since we allow function-chaining, it seems like a few convenience functions might be nice.
Note all the functions (not just these convenience functions) that look like
TLC59116& xxx(...)
They return a reference to the device, so you can chain functions.
|
TLC59116 & | delay (int msec) |
|
|
You can enable debug output by editing TLC59116.cpp, and TLC59116_Unmanaged.cpp. Add one or both:
#define TLC59116_LOWLEVEL 1
#define TLC59116_DEV 1
|
TLC59116 & | describe_shadow () |
| Print the registers, as we've cached them. cf. describe_actual() More...
|
|
TLC59116 & | resync_shadow_registers () |
|
|
byte | address () |
|
|
static void | _begin_trans (TwoWire &bus, byte addr, byte register_num) |
|
static void | _begin_trans (TwoWire &bus, byte addr, byte auto_mode, byte register_num) |
|
static int | _end_trans (TwoWire &bus) |
|
static byte | best_iref (byte ma, int Rext=Rext_Min) |
|
static void | describe_group_mode (byte *registers) |
|
static void | describe_registers (byte *registers) |
|
static byte | i_out (byte CM, byte HC, byte CC, int Rext=Rext_Min) |
|
static byte | i_out (byte iref_value, int Rext=Rext_Min) |
|
static byte | i_out_d (byte CM, byte HC, byte D, int Rext=Rext_Min) |
|
static bool | is_control_register (byte register_num) |
|
static bool | is_default_single_addr (byte address) |
|
static bool | is_default_SUBADR (byte address) |
|
static bool | is_device_range_addr (byte address) |
|
static byte | is_valid_led (byte v) |
|
static void | LEDOUTx_CHECK (int line, byte led_num) |
|
static byte | LEDOUTx_Register (byte led_num) |
|
static byte | LEDx_digital_off_bits (byte led_num) |
|
static byte | LEDx_digital_on_bits (byte led_num) |
|
static byte | LEDx_gpwm_bits (byte led_num) |
|
static byte | LEDx_pwm_bits (byte led_num) |
|
static byte | LEDx_Register_bits (byte led_num, byte register_value) |
|
static byte | LEDx_Register_mask (byte led_num) |
|
static byte | LEDx_set_mode (byte was, byte led_num, byte mode) |
|
static void | LEDx_set_mode (byte registers[], byte to_what, word which) |
|
static byte | LEDx_to_Register_bits (byte led_num, byte out_mode) |
|
static byte | normalize_address (byte address) |
|
static byte | PWMx_Register (byte led_num) |
|
static byte | reverse_cc (byte CC) |
|
static Scan & | scan (void) |
|
static byte | set_with_mask (byte was, byte mask, byte new_bits) |
|
static void | set_with_mask (byte *was, byte mask, byte new_bits) |
|
static byte | SUBADRx_Register (byte i) |
|