Introduction¶
CircuitPython library for TI TLC5957 48-channel 16bit LED-Driver
Setting of LED-Values / API is similar to NeoPixel and Dotstar APIs and compatible with fancyled.
Dependencies¶
This driver depends on:
Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle.
Contributing¶
Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.
Building locally¶
Zip release files¶
To build this library locally you’ll need to install the circuitpython-build-tools package.
python3 -m venv .env
source .env/bin/activate
pip install circuitpython-build-tools
Once installed, make sure you are in the virtual environment:
source .env/bin/activate
Then run the build:
circuitpython-build-bundles --filename_prefix slight-circuitpython-tlc5957 --library_location .
Sphinx documentation¶
Sphinx is used to build the documentation based on rST files and comments in the code. First, install dependencies (feel free to reuse the virtual environment from above):
python3 -m venv .env
source .env/bin/activate
pip install Sphinx sphinx-rtd-theme
Now, once you have the virtual environment activated:
cd docs
sphinx-build -E -W -b html . _build/html
This will output the documentation to docs/_build/html
. Open the index.html in your browser to
view them. It will also (due to -W) error out on any warning like Travis will. This is a good way to
locally verify it will pass.
Table of Contents¶
Simple test¶
Ensure your device works with this simple test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# CircuitPython
"""Simple & Minimallistic example for the TLC5957 library."""
import board
# import busio
import bitbangio
import digitalio
import pulseio
import slight_tlc5957
spi_clock = digitalio.DigitalInOut(board.SCK)
spi_clock.direction = digitalio.Direction.OUTPUT
spi_mosi = digitalio.DigitalInOut(board.MOSI)
spi_mosi.direction = digitalio.Direction.OUTPUT
spi_miso = digitalio.DigitalInOut(board.MISO)
spi_miso.direction = digitalio.Direction.INPUT
# spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
spi = bitbangio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# 6MHz for the grayscale clock
gsclk = pulseio.PWMOut(
board.D9, duty_cycle=(2 ** 15), frequency=(6000 * 1000))
latch = digitalio.DigitalInOut(board.D7)
latch.direction = digitalio.Direction.OUTPUT
# define pixel array
num_leds = 16
pixels = slight_tlc5957.TLC5957(
spi=spi,
latch=latch,
gsclk=gsclk,
spi_clock=spi_clock,
spi_mosi=spi_mosi,
spi_miso=spi_miso,
pixel_count=num_leds)
# set first pixel to orange
# using floating point values (0..1)
pixels[0] = (1, 0.5, 0)
# set first pixel to sky blue
# using 16bit integer values (0..65535)
pixels[1] = (0, 32000, 65535)
# write data to chips
pixels.show()
while True:
pass
|
Simple HW test¶
This example lights up every LED after each other. Its great for production testing your boards.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# CircuitPython
"""Develop and Test TLC5957."""
__doc__ = """
Develop and Test TLC5957.
this script contains a bunch of tests and debug outputs.
its mainly the playground during the development of the library.
"""
import time
import board
# import busio
import bitbangio
import digitalio
import pulseio
import slight_tlc5957
##########################################
print(
"\n" +
(42 * '*') + "\n" +
__doc__ + "\n" +
(42 * '*') + "\n" +
"\n"
)
##########################################
print(42 * '*')
print("initialise digitalio pins for SPI")
spi_clock = digitalio.DigitalInOut(board.SCK)
spi_clock.direction = digitalio.Direction.OUTPUT
spi_mosi = digitalio.DigitalInOut(board.MOSI)
spi_mosi.direction = digitalio.Direction.OUTPUT
spi_miso = digitalio.DigitalInOut(board.MISO)
spi_miso.direction = digitalio.Direction.INPUT
# print((42 * '*') + "\n" + "init busio.SPI")
# spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
print("init bitbangio.SPI")
spi = bitbangio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# maximum frequency is currently hardcoded to 6MHz
# https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/common-hal/pulseio/PWMOut.c#L119
gsclk_freqency = (6000 * 1000) # 6MHz
gsclk = pulseio.PWMOut(
board.D9, duty_cycle=(2 ** 15), frequency=gsclk_freqency)
print("gsclk.frequency: {:}MHz".format(gsclk.frequency / (1000*1000)))
latch = digitalio.DigitalInOut(board.D7)
latch.direction = digitalio.Direction.OUTPUT
##########################################
print(42 * '*')
print("define pixel array / init TLC5957")
num_leds = 16
pixels = slight_tlc5957.TLC5957(
spi=spi,
latch=latch,
gsclk=gsclk,
spi_clock=spi_clock,
spi_mosi=spi_mosi,
spi_miso=spi_miso,
pixel_count=num_leds)
print("pixel_count", pixels.pixel_count)
print("chip_count", pixels.chip_count)
print("channel_count", pixels.channel_count)
##########################################
print(42 * '*')
print("set colors")
for index in range(num_leds):
pixels[index] = (1, 1, 1)
# write data to chips
pixels.show()
time.sleep(10)
##########################################
print(42 * '*')
print("loop..")
value_high = 1000
value_low = 1
while True:
pixel_active_index = 0
for index in range(pixels.channel_count):
if index == pixel_active_index:
pixels.set_channel(index, value_high)
pixels.set_channel((index - 1) % pixels.channel_count, value_low)
pixel_active_index += 1
# write data to chips
pixels.show()
# wait a second
time.sleep(0.5)
# set all to minimal
for index in range(num_leds):
pixels[index] = (value_low, value_low, value_low)
# write data to chips
pixels.show()
time.sleep(2)
|
TLC5957 with FancyLED¶
Example how to combine TLC5957 with FancyLED.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# CircuitPython
"""TLC5957 & FancyLED."""
__doc__ = """
TLC5957 & FancyLED.
this is an example for combining the TLC5957 library with FancyLED.
Enjoy the colors :-)
"""
import board
# import busio
import bitbangio
import digitalio
import pulseio
import slight_tlc5957
import adafruit_fancyled.adafruit_fancyled as fancyled
##########################################
print(
"\n" +
(42 * '*') + "\n" +
__doc__ + "\n" +
(42 * '*') + "\n" +
"\n"
)
##########################################
print(42 * '*')
print("initialise digitalio pins for SPI")
spi_clock = digitalio.DigitalInOut(board.SCK)
spi_clock.direction = digitalio.Direction.OUTPUT
spi_mosi = digitalio.DigitalInOut(board.MOSI)
spi_mosi.direction = digitalio.Direction.OUTPUT
spi_miso = digitalio.DigitalInOut(board.MISO)
spi_miso.direction = digitalio.Direction.INPUT
# print((42 * '*') + "\n" + "init busio.SPI")
# spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
print("init bitbangio.SPI")
spi = bitbangio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# maximum frequency is currently hardcoded to 6MHz
# https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/common-hal/pulseio/PWMOut.c#L119
gsclk_freqency = (6000 * 1000) # 6MHz
gsclk = pulseio.PWMOut(
board.D9, duty_cycle=(2 ** 15), frequency=gsclk_freqency)
print("gsclk.frequency: {:}MHz".format(gsclk.frequency / (1000*1000)))
latch = digitalio.DigitalInOut(board.D7)
latch.direction = digitalio.Direction.OUTPUT
##########################################
print(42 * '*')
print("define pixel array / init TLC5957")
num_leds = 16
pixels = slight_tlc5957.TLC5957(
spi=spi,
latch=latch,
gsclk=gsclk,
spi_clock=spi_clock,
spi_mosi=spi_mosi,
spi_miso=spi_miso,
pixel_count=num_leds)
print("pixel_count", pixels.pixel_count)
print("chip_count", pixels.chip_count)
print("channel_count", pixels.channel_count)
##########################################
# helper function
##########################################
# Declare a 6-element RGB rainbow palette
palette = [
fancyled.CRGB(1.0, 0.0, 0.0), # Red
fancyled.CRGB(0.5, 0.5, 0.0), # Yellow
fancyled.CRGB(0.0, 1.0, 0.0), # Green
fancyled.CRGB(0.0, 0.5, 0.5), # Cyan
fancyled.CRGB(0.0, 0.0, 1.0), # Blue
fancyled.CRGB(0.5, 0.0, 0.5), # Magenta
]
# Positional offset into color palette to get it to 'spin'
offset = 0
##########################################
# main loop
print(42 * '*')
print("rainbow loop")
while True:
for i in range(num_leds):
# Load each pixel's color from the palette using an offset, run it
# through the gamma function, pack RGB value and assign to pixel.
color = fancyled.palette_lookup(palette, offset + i / num_leds)
color = fancyled.gamma_adjust(color, brightness=0.01)
pixels[i] = color
pixels.show()
offset += 0.01 # Bigger number = faster spin
|
TLC5957 with custom 2D-Array mapping¶
Example how to create a pixel-mapping with TLC5957.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# CircuitPython
"""TLC5957 & FancyLED & 2D-Array mapping."""
__doc__ = """
TLC5957 & FancyLED & 2D-Array mapping.
this is an example for combining the TLC5957 library with FancyLED.
Enjoy the colors :-)
"""
import time
import board
# import busio
import bitbangio
import digitalio
import pulseio
import slight_tlc5957
##########################################
print(
"\n" +
(42 * '*') + "\n" +
__doc__ + "\n" +
(42 * '*') + "\n" +
"\n"
)
##########################################
print(42 * '*')
print("initialise digitalio pins for SPI")
spi_clock = digitalio.DigitalInOut(board.SCK)
spi_clock.direction = digitalio.Direction.OUTPUT
spi_mosi = digitalio.DigitalInOut(board.MOSI)
spi_mosi.direction = digitalio.Direction.OUTPUT
spi_miso = digitalio.DigitalInOut(board.MISO)
spi_miso.direction = digitalio.Direction.INPUT
# print((42 * '*') + "\n" + "init busio.SPI")
# spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
print("init bitbangio.SPI")
spi = bitbangio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# maximum frequency is currently hardcoded to 6MHz
# https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/common-hal/pulseio/PWMOut.c#L119
gsclk_freqency = (6000 * 1000) # 6MHz
gsclk = pulseio.PWMOut(
board.D9, duty_cycle=(2 ** 15), frequency=gsclk_freqency)
print("gsclk.frequency: {:}MHz".format(gsclk.frequency / (1000*1000)))
latch = digitalio.DigitalInOut(board.D7)
latch.direction = digitalio.Direction.OUTPUT
##########################################
print(42 * '*')
print("define pixel array / init TLC5957")
rows = 4
cols = 4
num_leds = rows * cols
pixels = slight_tlc5957.TLC5957(
spi=spi,
latch=latch,
gsclk=gsclk,
spi_clock=spi_clock,
spi_mosi=spi_mosi,
spi_miso=spi_miso,
pixel_count=num_leds)
print("pixel_count", pixels.pixel_count)
print("chip_count", pixels.chip_count)
print("channel_count", pixels.channel_count)
##########################################
# helper function
def map_range(value, in_min, in_max, out_min, out_max):
"""Map Value from one range to another."""
return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def map_range_int(value, in_min, in_max, out_min, out_max):
"""Map Value from one range to another."""
return int(
(value - in_min) * (out_max - out_min)
//
(in_max - in_min) + out_min
)
##########################################
# mapping function
pixel_map = [
# pylint: disable=bad-whitespace
[15, 14, 13, 12],
[11, 10, 9, 8],
[7, 6, 5, 4],
[3, 2, 1, 0],
]
def get_pixel_index_from_row_col(row, col):
"""Get pixel_index from row and column index."""
pixel_index = pixel_map[row][col]
return pixel_index
##########################################
# print(42 * '*')
# print("set colors")
# for index in range(num_leds):
# pixels[index] = (1, 1, 1)
# # write data to chips
# pixels.show()
# time.sleep(2)
# print("set colors2")
# for index in range(num_leds):
# pixels[index] = (0, 100, 1000)
# # write data to chips
# pixels.show()
# time.sleep(2)
##########################################
print(42 * '*')
print("set colors")
# set first pixel to orange
pixels[get_pixel_index_from_row_col(0, 0)] = (1.0, 0.5, 0.0)
pixels[get_pixel_index_from_row_col(0, 3)] = (0.1, 0.0, 1.0)
pixels[get_pixel_index_from_row_col(3, 0)] = (0.1, 0.5, 0.0)
pixels[get_pixel_index_from_row_col(3, 3)] = (0.0, 0.5, 1.0)
pixels.show()
time.sleep(2)
print("set color range")
for x in range(cols):
# xN = x / cols
xN = map_range_int(x, 0, cols, 1, 100)
for y in range(rows):
# yN = y / rows
yN = map_range_int(y, 0, rows, 1, 100)
# print(
# "x: {:>2} xN: {:>2} "
# "y: {:>2} yN: {:>2} "
# "pixel_index: {:>2}".format(
# x, xN,
# y, yN,
# get_pixel_index_from_row_col(x, y)
# )
# )
pixels[get_pixel_index_from_row_col(x, y)] = (xN, yN, 0)
pixels.show()
time.sleep(2)
##########################################
# main loop
# Positional offset for blue part
offset = 0
print(42 * '*')
print("loop")
while True:
offsetN = map_range_int(offset, 0.0, 1.0, 1, 200)
for x in range(cols):
xN = map_range_int(x, 0, cols, 1, 500)
for y in range(rows):
yN = map_range_int(y, 0, rows, 1, 500)
pixels[get_pixel_index_from_row_col(x, y)] = (xN, yN, offsetN)
pixels.show()
offset += 0.01 # Bigger number = faster spin
if offset > 1.0:
offset = 0
|
API¶
s-light CircuitPython TLC5957 library.¶
CircuitPython library for TI TLC5957 48-channel 16bit LED-Driver
- Author(s): Stefan Krüger
Implementation Notes¶
Hardware:
- example PCB with TLC5957 and 4x4 SMD RGB LEDs https://github.com/s-light/magic_amulet_pcbs/tree/master/LEDBoard_4x4_HD
Software and Dependencies:
- Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases
-
class
slight_tlc5957.
TLC5957
(spi, spi_clock, spi_mosi, spi_miso, latch, gsclk, pixel_count=16)¶ TLC5957 16-bit 48 channel LED PWM driver.
This chip is designed to drive 16 RGB LEDs with 16-bit PWM per Color. The class has an interface compatible with FancyLED. and with this is similar to the NeoPixel and DotStar Interfaces.
Parameters: - spi (SPI) – An instance of the SPI bus connected to the chip. The clock and MOSI must be set the MISO (input) is currently unused. Maximal data clock frequence is: - TLC5957: 33MHz
- latch (DigitalInOut) – The chip LAT (latch) pin object that implements the DigitalInOut API.
- gsclk (PWMOut) – The chip Grayscale Clock pin object that implements the PWMOut API.
- pixel_count (bool) – Number of RGB-LEDs (=Pixels) are connected.
-
class
Function_Command
¶ Enum for available function commands.
-
set_channel
(channel_index, value)¶ Set the value for the provided channel.
Parameters:
-
show
()¶ Write out Grayscale Values to chips.