DotStar LED Strips
71-dotstar_blink_minimal.py
import machine, time
led_count = 8 # The number of LEDs to be controlled
brightness = 1 # 5-bit value (= 0 .. 31)
def flatten_list(iterables):
for iterable in iterables:
for item in iterable:
yield item
# Create a nested array for use as off-screen frame buffer [^1]
led_frame = [0b11100000 + brightness, 0, 0, 0]
leds = [led_frame] * led_count
# Setup hardware SPI connection (10 = MOSI, 11 = SCLK)
spi = machine.SPI(0, baudrate=1000000, sck=machine.Pin(18), mosi=machine.Pin(19)) # Bus 0, clock speed 1 MHz
def set_color(rgb = 0, led_ids = None):
if type(led_ids) == int: # Single led
led_ids = range(led_ids, led_ids + 1)
elif type(led_ids) == list or type(led_ids) == tuple or type(led_ids) == range: # Range of leds
pass
else: # All leds
led_ids = range(led_count)
if type(rgb) == int:
red, green, blue = rgb >> 16, rgb >> 8 & 0xff, rgb & 0xff
elif type(rgb) == list or type(rgb) == tuple:
red, green, blue = rgb
for led_id in led_ids:
leds[led_id] = [0b11100000 + brightness, blue, green, red]
def display():
start_frame = [0b00000000, 0b00000000, 0b00000000, 0b00000000] # Start frame: 4 Bytes of 0's
led_frames = list(flatten_list(leds)) # Flatten nested list (= list containing lists)
end_frame = [0x11111111] * ((led_count + 15) // 16) # End frame: 1 bit for every two LEDs, rounded up to bytes
spi.write(bytearray(start_frame + led_frames + end_frame))
set_color() # Turn all LEDs in off-screen frame buffer off
led_ids = range(0, led_count, 2)
try:
while True:
set_color(0xffff00, led_ids) # Set color of selected LEDs in off-screen frame buffer to red
display() # Write off-screen frame buffer to LED strip
time.sleep(.5)
set_color(0x000000, led_ids) # Turn selected LEDs in off-screen frame buffer off (= set color black)
display() # Write off-screen frame buffer to LED strip
time.sleep(.5)
except KeyboardInterrupt:
pass
set_color() # Turn all LEDs in off-screen frame buffer off
display()
spi.deinit() # Turn off the SPI bus
72-dotstar_blink_w_class.py
import machine, time
class LED_Strip():
def __init__(self, led_count, brightness = 1):
self.led_count = led_count
self.brightness = min(31, brightness) # 5-bit value (= 0 .. 31)
# Create a nested array for use as off-screen frame buffer [^1]
led_frame = [0b11100000 + brightness, 0, 0, 0]
self.leds = [led_frame] * led_count
# Setup hardware SPI connection (19 = MOSI, 18 = SCLK)
self.spi = machine.SPI(0, baudrate=1000000, sck=machine.Pin(18), mosi=machine.Pin(19)) # Bus 0, clock speed 1 MHz
self.clear()
self.display()
def set_color(self, rgb = 0, led_ids = None):
if type(led_ids) == int: # Single led
led_ids = range(led_ids, led_ids + 1)
elif type(led_ids) == list or type(led_ids) == tuple or type(led_ids) == range: # Range of leds
pass
else: # All leds
led_ids = range(led_count)
if type(rgb) == int:
red, green, blue = rgb >> 16, rgb >> 8 & 0xff, rgb & 0xff
elif type(rgb) == list or type(rgb) == tuple:
red, green, blue = rgb
for led_id in led_ids:
self.leds[led_id] = [0b11100000 + self.brightness, blue, green, red]
def display(self):
def flatten_list(iterables):
for iterable in iterables:
for item in iterable:
yield item
start_frame = [0b00000000, 0b00000000, 0b00000000, 0b00000000] # Start frame: 4 Bytes of 0's
led_frames = list(flatten_list(self.leds)) # Flatten nested list (= list containing lists)
end_frame = [0x11111111] * ((led_count + 15) // 16) # End frame: 1 bit for every two LEDs, rounded up to bytes
self.spi.write(bytearray(start_frame + led_frames + end_frame))
def clear(self):
self.set_color() # Turn all LEDs in off-screen frame buffer off
def cleanup(self):
self.set_color() # Turn all LEDs in off-screen frame buffer off
self.display() # Write off-screen frame buffer to LED strip
self.spi.deinit()
led_count = 8 # The number of LEDs to be controlled
led_strip = LED_Strip(led_count)
led_ids = range(0, led_count, 2)
try:
while True:
led_strip.set_color(0xffff00, led_ids) # Set color of selected LEDs in off-screen frame buffer to red
led_strip.display() # Write off-screen frame buffer to LED strip
time.sleep(.5)
led_strip.set_color(0x000000, led_ids) # Turn selected LEDs in off-screen frame buffer off (= set color black)
led_strip.display() # Write off-screen frame buffer to LED strip
time.sleep(.5)
except KeyboardInterrupt:
pass
led_strip.cleanup()
73-dotstar_blink_w_external_class.py
import dotstar
import time
led_count = 8
led_strip = dotstar.LED_Strip(led_count)
try:
# led_ids = 1 # A single led
# led_ids = (0, 3, 4, 7, 8, 9) # Multiple leds by tuple or array with ids
# led_ids = range(2, 8) # Multiple leds by range
led_ids = range(0, led_count, 2) # Every second led
# led_ids = None # All leds
while True:
led_strip.set_color(0xff0000, led_ids)
led_strip.display()
time.sleep(.5)
led_strip.set_color(0x000000, led_ids)
led_strip.display()
time.sleep(.5)
except KeyboardInterrupt: # Control-C was pressed
pass
led_strip.cleanup()
dotstar/__init__.py
from .led_strip import *
dotstar/led_strip.py
import machine
class LED_Strip():
BLEND_MODE_OVERWRITE = 0
BLEND_MODE_ADD = 1
BLEND_MODE_MULTIPLY = 2
def __init__(self, led_count, brightness = 1):
self.led_count = led_count
self.brightness = min(31, brightness) # 5-bit value (= 0 .. 31)
# Create a nested array for use as off-screen frame buffer [^1]
led_frame = [0b11100000 + brightness, 0, 0, 0]
self.leds = [led_frame] * self.led_count
# Setup hardware SPI connection (19 = MOSI, 18 = SCLK)
self.spi = machine.SPI(0, baudrate=1000000, sck=machine.Pin(18), mosi=machine.Pin(19)) # Bus 0, clock speed 1 MHz
self.clear()
self.display()
def set_color(self, rgb = 0, led_ids = None, blend_mode = BLEND_MODE_OVERWRITE):
if type(led_ids) == int: # Single led
led_ids = range(led_ids, led_ids + 1)
elif type(led_ids) == list or type(led_ids) == tuple or type(led_ids) == range: # Range of leds
pass
else: # All leds
led_ids = range(self.led_count)
if type(rgb) == int:
red, green, blue = rgb >> 16, rgb >> 8 & 0xff, rgb & 0xff
elif type(rgb) == list or type(rgb) == tuple:
red, green, blue = rgb
for led_id in led_ids:
if blend_mode == self.BLEND_MODE_OVERWRITE:
self.leds[led_id] = [0b11100000 + self.brightness, blue, green, red]
elif blend_mode == self.BLEND_MODE_ADD:
self.leds[led_id] = [max(0, min(255, color_1_component + color_2_component))
for color_1_component, color_2_component in zip(self.leds[led_id], [0, blue, green, red])]
elif blend_mode == self.BLEND_MODE_MULTIPLY:
self.leds[led_id] = [max(0, min(255, int(color_1_component * color_2_component / 255)))
for color_1_component, color_2_component in zip(self.leds[led_id], [255, blue, green, red])]
def display(self):
def flatten_list(iterables):
for iterable in iterables:
for item in iterable:
yield item
start_frame = [0b00000000, 0b00000000, 0b00000000, 0b00000000] # Start frame: 4 Bytes of 0's
led_frames = list(flatten_list(self.leds)) # Flatten nested list (= list containing lists)
end_frame = [0x11111111] * ((self.led_count + 15) // 16) # End frame: 1 bit for every two LEDs, rounded up to bytes
self.spi.write(bytearray(start_frame + led_frames + end_frame))
def clear(self):
self.set_color() # Turn all LEDs in off-screen frame buffer off
def cleanup(self):
self.set_color() # Turn all LEDs in off-screen frame buffer off
self.display() # Write off-screen frame buffer to LED strip
self.spi.deinit()
77-dotstar_rainbow_sweep_w_afterglow.py
import dotstar
import time
led_count = 8
led_strip = dotstar.LED_Strip(led_count)
# From https://github.com/python/cpython/blob/main/Lib/colorsys.py
def hsv_to_rgb(h, s, v):
if s == 0.0:
return v, v, v
i = int(h*6.0) # XXX assume int() truncates!
f = (h*6.0) - i
p = v*(1.0 - s)
q = v*(1.0 - s*f)
t = v*(1.0 - s*(1.0-f))
i = i%6
if i == 0:
return v, t, p
if i == 1:
return q, v, p
if i == 2:
return p, v, t
if i == 3:
return p, q, v
if i == 4:
return t, p, v
if i == 5:
return v, p, q
try:
step_count = 5 # The number of steps after color * step_size = 0 [^1]
step_size = int(255 * (1 / 255) ** (1 / step_count)) # The resulting step_size
hue = 0
while True:
for led_id in range(led_count - 1):
r, g, b = hsv_to_rgb(hue / 360.0, 1, 1)
led_strip.set_color((step_size, step_size, step_size), blend_mode = led_strip.BLEND_MODE_MULTIPLY)
led_strip.set_color((int(255 * r), int(255 * g), int(255 * b)), led_id)
led_strip.display()
time.sleep(.05)
hue += 5
for led_id in range(led_count - 1, 0, -1):
r, g, b = hsv_to_rgb(hue / 360.0, 1, 1)
led_strip.set_color((step_size, step_size, step_size), blend_mode = led_strip.BLEND_MODE_MULTIPLY)
led_strip.set_color((int(255 * r), int(255 * g), int(255 * b)), led_id)
led_strip.display()
time.sleep(.05)
hue += 5
except KeyboardInterrupt: # Control-C was pressed
pass
led_strip.cleanup()