A few years ago, at a Christmas market in Germany, I bought myself two pack-flat cardboard stars. They’re meant to use a specific light fitting, but in 2019 I bodged them on top of some simple bedside lamps from Woodies, and in 2020 I hung one using a USB cable that was connected to a Raspberry Pi. Why was the cable connected to a Pi? So that the Pi could run some Python code to talk to the LED light strip that was connected to the APA102 driver. The result is a star that cycles colours nicely.
import bibliopixel as bp import bibliopixel.colors as colors import bibliopixel.drivers.channel_order as co import bibliopixel.drivers.serial as serial import bibliopixel.layout as layout from bibliopixel.animation.strip import Strip from bibliopixel.colors.arithmetic import color_scale # causes frame timing information to be output bp.log.setLogLevel(bp.log.DEBUG) class ColorFade(Strip): """Fill the dots progressively along the strip.""" COLOR_DEFAULTS = ( ( "colors", [ colors.Red, colors.Orange, colors.Yellow, colors.Green, colors.Blue, colors.Indigo, colors.Violet, ], ), ) def wave_range(self, start, peak, step): main = [i for i in range(start, peak + 1, step)] return main + [i for i in reversed(main[0 : len(main) - 1])] def __init__(self, layout, step=1, start=0, end=-1, **kwds): super().__init__(layout, start, end, **kwds) self._levels = self.wave_range(0, 255, step) self._level_count = len(self._levels) def pre_run(self): self._step = 0 def step(self, amt=1): c_index, l_index = divmod(self._step, self._level_count) color = self.palette(c_index) color = color_scale(color, self._levels[l_index]) self.layout.fill(color, self._start, self._end) self._step += amt # set number of pixels & LED type here driver = serial.Serial( num=22, ledtype=serial.LEDTYPE.APA102, c_order=co.ChannelOrder.BGR, ) led = layout.Strip(driver) anim = ColorFade(led) try: # run the animation anim.run(fps=30) except KeyboardInterrupt: # Ctrl+C will exit the animation and turn the LEDs offs led.all_off() led.update()