Supported LED chipsets¶
APA102 (aka Adafruit DotStar)¶
The APA102 is an RGB LED with an integrated driver chip that can be addressed via SPI. That makes it ideal for the Raspberry Pi as talking to an SPI device from Python is really easy. Another advantage of this chip is its support for high SPI data rates (for short strips of less than 200 LEDs you can easily do 8 MHz) which results in very high framerates and smooth-looking animations.
You can find cheap strips on AliExpress etc. or buy them at Adafruit - they sell them as DotStar.
This driver was originally written by tinue and can be found here.
-
class
drivers.apa102.
APA102
(num_leds: int, max_clock_speed_hz: int = 4000000, max_global_brightness: float = 1.0)[source]¶ Note
A very brief overview of the APA102
An APA102 LED is addressed with SPI. The bits are shifted in one by one, starting with the least significant bit.
An LED usually just forwards everything that is sent to its data-in to data-out. While doing this, it remembers its own color and keeps glowing with that color as long as there is power.
An LED can be switched to not forward the data, but instead use the data to change it’s own color. This is done by sending (at least) 32 bits of zeroes to data-in. The LED then accepts the next correct 32 bit LED frame (with color information) as its new color setting.
After having received the 32 bit color frame, the LED changes color, and then resumes to just copying data-in to data-out.
The really clever bit is this: While receiving the 32 bit LED frame, the LED sends zeroes on its data-out line. Because a color frame is 32 bits, the LED sends 32 bits of zeroes to the next LED. As we have seen above, this means that the next LED is now ready to accept a color frame and update its color.
So that’s really the entire protocol:
- Start by sending 32 bits of zeroes. This prepares LED 1 to update its color.
- Send color information one by one, starting with the color for LED 1, then LED 2 etc.
- Finish off by cycling the clock line a few times to get all data to the very last LED on the strip
The last step is necessary, because each LED delays forwarding the data a bit. Imagine ten people in a row. When you yell the last color information, i.e. the one for person ten, to the first person in the line, then you are not finished yet. Person one has to turn around and yell it to person 2, and so on. So it takes ten additional “dummy” cycles until person ten knows the color. When you look closer, you will see that not even person 9 knows the color yet. This information is still with person 2. Essentially the driver sends additional zeroes to LED 1 as long as it takes for the last color frame to make it down the line to the last LED.
- Restrictions of this driver:
- strips cannot have more than 1024 LEDs
The constructor initializes the strip connection via SPI
-
clear_strip
()¶ Clears the color buffer, then invokes a blackout on the strip by calling
show()
Return type: None
-
color_bytes_to_tuple
()¶ Converts a 3-byte color value (like
FF001A
) into an RGB color tuple (like(255, 0, 26)
).Parameters: rgb_color ( int
) – a 3-byte RGB color value represented as a base-10 integerReturn type: tuple
Returns: color tuple (red, green, blue)
-
color_tuple_to_bytes
(green, blue)¶ Converts an RGB color tuple (like
(255, 0, 26)
) into a 3-byte color value (likeFF001A
)Parameters: Return type: Returns: the tuple components joined into a 3-byte value with each byte representing a color component
-
freeze
()¶ Freezes the strip. All state-changing methods (
on_color_change()
andon_brightness_change()
) must not do anything anymore and leave the buffer unchanged.Return type: None
-
get_pixel
(led_num)¶ Returns the pixel at index
led_num
Parameters: led_num ( int
) – the index of the pixel you want to getReturn type: tuple
Returns: (red, green, blue)
as tuple
-
classmethod
led_prefix
(brightness)[source]¶ generates the first byte of a 4-byte SPI message to a single APA102 module
Parameters: brightness ( float
) – float from 0.0 (off) to 1.0 (full brightness)Return type: int
Returns: the brightness byte
-
max_refresh_time_sec
= 1¶ the maximum time the whole strip takes to refresh
-
on_brightness_change
(led_num)[source]¶ For the LED at
led_num
, regenerate the prefix and store the new prefix to the message bufferParameters: led_num ( int
) – The index of the LED whose prefix should be regeneratedReturn type: None
-
on_color_change
(led_num, red, green, blue)[source]¶ Changes the message buffer after a pixel was changed in the global color buffer. Also, a grayscale correction is performed. To send the message buffer to the strip and show the changes, you must invoke
show()
Parameters: Return type:
-
rotate
(positions=1)¶ Treating the internal leds array as a circular buffer, rotate it by the specified number of positions. The number can be negative, which means rotating in the opposite direction.
Parameters: positions ( int
) – the number of steps to rotateReturn type: None
-
set_brightness
(led_num, brightness)¶ Sets the brightness for a single LED in the strip. A global multiplier is applied.
Parameters: Return type:
-
set_global_brightness
(brightness)¶ Sets a global brightness multiplicator which applies to every single LED’s brightness.
Parameters: brightness ( float
) – the global brightness (0.0 - 1.0
) multiplicator to be setReturn type: None
-
set_global_brightness_percent
(brightness)¶ Just like
set_global_brightness()
, but with a 0-100 percent value.Parameters: brightness ( float
) – the global brightness (0.0 - 100.0
) multiplicator to be setReturn type: None
-
set_pixel
(led_num, red, green, blue)¶ The buffer value of pixel
led_num
is set to(red, green, blue)
Parameters: Return type:
-
set_pixel_bytes
(led_num, rgb_color)¶ Changes the pixel
led_num
to the given color in the buffer. To send the buffer to the strip and show the changes, invokeshow()
If you do not know, how the 3-byte
rgb_color
works, just useset_pixel()
.Parameters: Return type:
-
static
spi_end_frame
()[source]¶ As explained above, dummy data must be sent after the last real color information so that all of the data can reach its destination down the line. The delay is not as bad as with the human example above. It is only 1/2 bit per LED. This is because the SPI clock line needs to be inverted.
Say a bit is ready on the SPI data line. The sender communicates this by toggling the clock line. The bit is read by the LED, and immediately forwarded to the output data line. When the clock goes down again on the input side, the LED will toggle the clock up on the output to tell the next LED that the bit is ready.
After one LED the clock is inverted, and after two LEDs it is in sync again, but one cycle behind. Therefore, for every two LEDs, one bit of delay gets accumulated. For 300 LEDs, 150 additional bits must be fed to the input of LED one so that the data can reach the last LED. In this implementation we add a few more zero bytes at the end, just to be sure.
Ultimately, we need to send additional num_leds/2 arbitrary data bits, in order to trigger num_leds/2 additional clock changes. This driver sends zeroes, which has the benefit of getting LED one partially or fully ready for the next update to the strip. An optimized version of the driver could omit the
spi_start_frame()
method if enough zeroes have been sent as part ofspi_end_frame()
.Return type: list
Returns: The end frame to be sent at the end of each SPI transmission
-
static
spi_start_frame
()[source]¶ To start a transmission, one must send 32 empty bits
Return type: list
Returns: The 32-bit start frame to be sent at the beginning of a transmission
-
sync_down
()¶ Reads the shared color and brightness buffers and copies them to the local buffers
Return type: None
No LED Strip (Dummy Driver)¶
-
class
drivers.dummy.
DummyDriver
(num_leds: int, max_clock_speed_hz: int = 4000000, max_global_brightness: float = 1.0)[source]¶ A Dummy Driver that just shows the LED states on the logger. This can be useful for developing without having a real LED strip at hand.
-
clear_strip
()¶ Clears the color buffer, then invokes a blackout on the strip by calling
show()
Return type: None
-
color_bytes_to_tuple
()¶ Converts a 3-byte color value (like
FF001A
) into an RGB color tuple (like(255, 0, 26)
).Parameters: rgb_color ( int
) – a 3-byte RGB color value represented as a base-10 integerReturn type: tuple
Returns: color tuple (red, green, blue)
-
color_tuple_to_bytes
(green, blue)¶ Converts an RGB color tuple (like
(255, 0, 26)
) into a 3-byte color value (likeFF001A
)Parameters: Return type: Returns: the tuple components joined into a 3-byte value with each byte representing a color component
-
freeze
()¶ Freezes the strip. All state-changing methods (
on_color_change()
andon_brightness_change()
) must not do anything anymore and leave the buffer unchanged.Return type: None
-
get_pixel
(led_num)¶ Returns the pixel at index
led_num
Parameters: led_num ( int
) – the index of the pixel you want to getReturn type: tuple
Returns: (red, green, blue)
as tuple
-
rotate
(positions=1)¶ Treating the internal leds array as a circular buffer, rotate it by the specified number of positions. The number can be negative, which means rotating in the opposite direction.
Parameters: positions ( int
) – the number of steps to rotateReturn type: None
-
set_brightness
(led_num, brightness)¶ Sets the brightness for a single LED in the strip. A global multiplier is applied.
Parameters: Return type:
-
set_global_brightness
(brightness)¶ Sets a global brightness multiplicator which applies to every single LED’s brightness.
Parameters: brightness ( float
) – the global brightness (0.0 - 1.0
) multiplicator to be setReturn type: None
-
set_global_brightness_percent
(brightness)¶ Just like
set_global_brightness()
, but with a 0-100 percent value.Parameters: brightness ( float
) – the global brightness (0.0 - 100.0
) multiplicator to be setReturn type: None
-
set_pixel
(led_num, red, green, blue)¶ The buffer value of pixel
led_num
is set to(red, green, blue)
Parameters: Return type:
-
set_pixel_bytes
(led_num, rgb_color)¶ Changes the pixel
led_num
to the given color in the buffer. To send the buffer to the strip and show the changes, invokeshow()
If you do not know, how the 3-byte
rgb_color
works, just useset_pixel()
.Parameters: Return type:
-
sync_down
()¶ Reads the shared color and brightness buffers and copies them to the local buffers
Return type: None
-