#!/usr/bin/env python3 import spidev import time NUM_LEDS = 8 # Little Bird Toucan = 8 LEDs # Open SPI interface (Bus 0, Device 0) spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 8000000 # 8 MHz is typical for APA102 spi.mode = 0b00 def send_frame(data): spi.xfer2(data) def set_color(index, r, g, b, brightness=31): """Return 4 bytes for one LED (APA102 format).""" brightness = max(0, min(brightness, 31)) prefix = 0b11100000 | brightness return [prefix, b & 0xFF, g & 0xFF, r & 0xFF] def show(colors): """Send data to LEDs.""" # Start frame (32 bits of zeros) send_frame([0x00, 0x00, 0x00, 0x00]) # LED frames frame = [] for color in colors: frame.extend(color) send_frame(frame) # End frame (at least num_leds/2 bits of 1s) end_bytes = [0xFF] * ((NUM_LEDS + 15) // 16) send_frame(end_bytes) def wheel(pos): """Generate rainbow colors across 0-255 positions.""" if pos < 85: return (pos * 3, 255 - pos * 3, 0) elif pos < 170: pos -= 85 return (255 - pos * 3, 0, pos * 3) else: pos -= 170 return (0, pos * 3, 255 - pos * 3) try: print("Little Bird Toucan demo running! Press Ctrl+C to stop.") i = 0 while True: colors = [] for j in range(NUM_LEDS): r, g, b = wheel((int(i + j * 256 / NUM_LEDS)) & 255) colors.append(set_color(j, r, g, b)) show(colors) i = (i + 1) % 256 time.sleep(0.05) except KeyboardInterrupt: show([set_color(0, 0, 0, 0)] * NUM_LEDS) spi.close() print("\nGoodbye!")