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_buffer()

Resets all pixels in the color buffer to (0,0,0).

Return type:None
clear_strip()

Clears the color buffer, then invokes a blackout on the strip by calling show()

Return type:None
close()[source]

Closes the SPI connection to the strip.

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 integer
Return 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 (like FF001A)

Parameters:
  • red (float) – red component of the tuple (0.0 - 255.0)
  • green (float) – green component of the tuple (0.0 - 255.0)
  • blue (float) – blue component of the tuple (0.0 - 255.0)
Return type:

int

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() and on_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 get
Return 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 buffer

Parameters:led_num (int) – The index of the LED whose prefix should be regenerated
Return 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:
  • led_num – index of the pixel to be set
  • red (float) – red component of the pixel (0.0 - 255.0)
  • green (float) – green component of the pixel (0.0 - 255.0)
  • blue (float) – blue component of the pixel (0.0 - 255.0)
Return type:

None

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 rotate
Return type:None
set_brightness(led_num, brightness)

Sets the brightness for a single LED in the strip. A global multiplier is applied.

Parameters:
  • led_num (int) – the target LED index
  • brightness (float) – the desired brightness (0.0 - 1.0)
Return type:

None

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 set
Return 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 set
Return type:None
set_pixel(led_num, red, green, blue)

The buffer value of pixel led_num is set to (red, green, blue)

Parameters:
  • led_num (int) – index of the pixel to be set
  • red (float) – red component of the pixel (0.0 - 255.0)
  • green (float) – green component of the pixel (0.0 - 255.0)
  • blue (float) – blue component of the pixel (0.0 - 255.0)
Return type:

None

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, invoke show()

If you do not know, how the 3-byte rgb_color works, just use set_pixel() .

Parameters:
  • led_num (int) – index of the pixel to be set
  • rgb_color (int) – a 3-byte RGB color value represented as a base-10 integer
Return type:

None

show()[source]

sends the buffered color and brightness values to the strip

Return type:None
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 of spi_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
sync_up()

Copies the local color and brightness buffers to the shared buffer so other processes can see the current strip state.

Return type:None
unfreeze()

Revokes all effects of freeze()

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_buffer()

Resets all pixels in the color buffer to (0,0,0).

Return type:None
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 integer
Return 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 (like FF001A)

Parameters:
  • red (float) – red component of the tuple (0.0 - 255.0)
  • green (float) – green component of the tuple (0.0 - 255.0)
  • blue (float) – blue component of the tuple (0.0 - 255.0)
Return type:

int

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() and on_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 get
Return 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 rotate
Return type:None
set_brightness(led_num, brightness)

Sets the brightness for a single LED in the strip. A global multiplier is applied.

Parameters:
  • led_num (int) – the target LED index
  • brightness (float) – the desired brightness (0.0 - 1.0)
Return type:

None

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 set
Return 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 set
Return type:None
set_pixel(led_num, red, green, blue)

The buffer value of pixel led_num is set to (red, green, blue)

Parameters:
  • led_num (int) – index of the pixel to be set
  • red (float) – red component of the pixel (0.0 - 255.0)
  • green (float) – green component of the pixel (0.0 - 255.0)
  • blue (float) – blue component of the pixel (0.0 - 255.0)
Return type:

None

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, invoke show()

If you do not know, how the 3-byte rgb_color works, just use set_pixel() .

Parameters:
  • led_num (int) – index of the pixel to be set
  • rgb_color (int) – a 3-byte RGB color value represented as a base-10 integer
Return type:

None

sync_down()

Reads the shared color and brightness buffers and copies them to the local buffers

Return type:None
sync_up()

Copies the local color and brightness buffers to the shared buffer so other processes can see the current strip state.

Return type:None
unfreeze()

Revokes all effects of freeze()

Return type:None