from machine import Pin
import neopixel
import time, urandom
# === KONFIGURATION ===
NUM_LEDS = 8
NUM_STRIPS = 6
STRIP_PINS = [8, 9, 10, 11, 12, 13]
EFFECT_BUTTON_PIN = 14
WHITE_TRIGGER_PIN = 15
# === SETUP ===
strips = [neopixel.NeoPixel(Pin(pin), NUM_LEDS) for pin in STRIP_PINS]
button_pin = Pin(EFFECT_BUTTON_PIN, Pin.IN, Pin.PULL_UP)
white_input = Pin(WHITE_TRIGGER_PIN, Pin.IN, Pin.PULL_UP)
mode = 0
num_modes = 10
last_button_state = 1
last_debounce_time = time.ticks_ms()
debounce_delay = 200
# === BASISFUNKTIONEN ===
def set_all(r, g, b):
for strip in strips:
for i in range(NUM_LEDS):
strip[i] = (r, g, b)
strip.write()
def fade_color(start, end, step, total_steps):
"""Lerpt zwischen zwei Farben"""
return tuple(int(start[i] + (end[i]-start[i]) * step / total_steps) for i in range(3))
def wheel(pos):
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)
# === EFFEKTE ===
def effect_off():
set_all(0, 0, 0)
time.sleep(0.05)
def effect_meteor_rain():
"""Ein heller Punkt zieht mit Schweif über die Leiste"""
meteor_color = (255, 100, 0)
decay = 0.8
for pos in range(NUM_LEDS * 2):
for strip in strips:
# Dim existing
for i in range(NUM_LEDS):
r, g, b = strip[i]
strip[i] = (int(r * decay), int(g * decay), int(b * decay))
# Set meteor
if pos < NUM_LEDS:
strip[pos] = meteor_color
strip.write()
time.sleep(0.05)
def effect_comet():
"""Bunter Komet mit Schweif"""
tail_length = 4
color = wheel(urandom.getrandbits(8))
for pos in range(NUM_LEDS + tail_length):
for strip in strips:
for i in range(NUM_LEDS):
brightness = max(0, 1 - abs(i - pos) / tail_length)
strip[i] = tuple(int(c * brightness) for c in color)
strip.write()
time.sleep(0.05)
def effect_sparkle():
"""Einzelne LEDs blitzen zufällig kurz auf"""
set_all(0, 0, 0)
for strip in strips:
for _ in range(3):
idx = urandom.getrandbits(3) % NUM_LEDS
strip[idx] = (255, 255, 255)
strip.write()
time.sleep(0.08)
def effect_scanner():
"""Punkt läuft hin & her (Knight Rider)"""
color = (255, 0, 0)
for direction in [1, -1]:
for i in range(0, NUM_LEDS, direction):
for strip in strips:
for j in range(NUM_LEDS):
strip[j] = color if j == i else (0, 0, 0)
strip.write()
time.sleep(0.05)
def effect_color_fade():
"""Weiche Übergänge durch Farbspektrum"""
for shift in range(256):
color = wheel(shift)
set_all(*color)
time.sleep(0.03)
def effect_matrix():
"""Grüner 'Matrix'-Regen-Effekt"""
decay = 0.75
for strip in strips:
for i in range(NUM_LEDS - 1, 0, -1):
strip[i] = tuple(int(c * decay) for c in strip[i - 1])
strip[0] = (0, urandom.getrandbits(7) + 128, 0) if urandom.getrandbits(3) == 0 else (0, 0, 0)
strip.write()
time.sleep(0.08)
def effect_fire():
"""Flackerndes Feuer"""
for strip in strips:
for i in range(NUM_LEDS):
heat = urandom.getrandbits(8)
r = int(heat)
g = int(heat * 0.5)
b = int(heat * 0.1)
strip[i] = (r, g, b)
strip.write()
time.sleep(0.05)
def effect_ocean_wave():
"""Sanfte Bewegung in Blau/Grün"""
for shift in range(0, 256, 8):
color = (0, int(100 + 50 * abs((shift % 128) - 64) / 64), int(150 + 100 * abs((shift % 128) - 64) / 64))
set_all(*color)
time.sleep(0.05)
def effect_strobe():
"""Helle Stroboskop-Blitze"""
set_all(255, 255, 255)
time.sleep(0.05)
set_all(0, 0, 0)
time.sleep(0.1)
# === WEISSLICHT ===
def effect_white():
set_all(255, 255, 255)
# === HAUPTSCHLEIFE ===
set_all(0, 0, 0)
print("LED-Controller gestartet mit", num_modes, "Effekten.")
while True:
# Weißlicht-Bypass
if white_input.value() == 0:
effect_white()
continue
# Effektlogik
if mode == 0: effect_off()
elif mode == 1: effect_meteor_rain()
elif mode == 2: effect_comet()
elif mode == 3: effect_sparkle()
elif mode == 4: effect_scanner()
elif mode == 5: effect_color_fade()
elif mode == 6: effect_matrix()
elif mode == 7: effect_fire()
elif mode == 8: effect_ocean_wave()
elif mode == 9: effect_strobe()
# Taster-Debounce
current_state = button_pin.value()
if last_button_state == 1 and current_state == 0:
if time.ticks_diff(time.ticks_ms(), last_debounce_time) > debounce_delay:
mode = (mode + 1) % num_modes
print("→ Neuer Effekt:", mode)
last_debounce_time = time.ticks_ms()
last_button_state = current_state