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)
# === MODUSVERWALTUNG ===
combo_mode = 0
num_combos = 5 # Anzahl der verschiedenen Effektkombinationen
last_button_state = 1
last_debounce_time = time.ticks_ms()
debounce_delay = 250
# === BASISFUNKTIONEN ===
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)
def clear_strip(strip):
for i in range(NUM_LEDS):
strip[i] = (0, 0, 0)
strip.write()
# === EINZELSTREIFEN-EFFEKTE ===
def effect_meteor(strip, step):
"""Laufender Meteor mit Schweif"""
length = 4
color = (255, 80, 0)
decay = 0.7
# Dim
for i in range(NUM_LEDS):
r, g, b = strip[i]
strip[i] = (int(r * decay), int(g * decay), int(b * decay))
# Set new meteor pos
pos = step % (NUM_LEDS + length)
if pos < NUM_LEDS:
strip[pos] = color
strip.write()
def effect_comet(strip, step):
"""Farbiger Komet"""
tail = 3
c = wheel((step * 5) % 256)
pos = step % (NUM_LEDS + tail)
for i in range(NUM_LEDS):
brightness = max(0, 1 - abs(i - pos) / tail)
strip[i] = tuple(int(v * brightness) for v in c)
strip.write()
def effect_fire(strip, step):
"""Flackerndes Feuer"""
for i in range(NUM_LEDS):
heat = urandom.getrandbits(8)
strip[i] = (heat, int(heat * 0.4), int(heat * 0.05))
strip.write()
def effect_matrix(strip, step):
"""Matrix-artiger Regen"""
decay = 0.8
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()
def effect_wave(strip, step):
"""Farbwelle"""
for i in range(NUM_LEDS):
color = wheel((i * 30 + step * 5) % 256)
strip[i] = color
strip.write()
def effect_sparkle(strip, step):
"""Zufällige weiße Funken"""
decay = 0.5
for i in range(NUM_LEDS):
r, g, b = strip[i]
strip[i] = (int(r * decay), int(g * decay), int(b * decay))
if urandom.getrandbits(3) == 0:
idx = urandom.getrandbits(3) % NUM_LEDS
strip[idx] = (255, 255, 255)
strip.write()
def effect_breath(strip, step):
"""Atmen in einer Farbe"""
brightness = int((1 + math.sin(step / 10)) * 127)
color = (0, 0, brightness)
for i in range(NUM_LEDS):
strip[i] = color
strip.write()
def effect_strobe(strip, step):
"""Schnelles Blitzen"""
color = (255, 255, 255) if step % 5 == 0 else (0, 0, 0)
for i in range(NUM_LEDS):
strip[i] = color
strip.write()
def effect_ocean(strip, step):
"""Bewegtes Blau/Grün wie Wasser"""
for i in range(NUM_LEDS):
wave = int((math.sin((i + step) / 4) + 1) * 100)
strip[i] = (0, int(wave * 0.8), wave)
strip.write()
def effect_fadecolor(strip, step):
"""Langsamer Übergang durch Farbspektrum"""
c = wheel((step * 2) % 256)
for i in range(NUM_LEDS):
strip[i] = c
strip.write()
# === EFFEKTZUTEILUNGSPROFILE ===
# Jede Kombination weist den 6 Streifen unterschiedliche Effekte zu.
combos = [
[effect_meteor, effect_fire, effect_matrix, effect_wave, effect_sparkle, effect_fadecolor],
[effect_comet, effect_fire, effect_sparkle, effect_wave, effect_matrix, effect_ocean],
[effect_strobe, effect_wave, effect_meteor, effect_fire, effect_fadecolor, effect_sparkle],
[effect_matrix, effect_fire, effect_comet, effect_ocean, effect_wave, effect_fadecolor],
[effect_fire, effect_fire, effect_wave, effect_wave, effect_matrix, effect_sparkle],
]
# === WEISSLICHT ===
def effect_white():
for strip in strips:
for i in range(NUM_LEDS):
strip[i] = (255, 255, 255)
strip.write()
# === START ===
import math
for s in strips:
clear_strip(s)
print("Kombinierte Lichtshow gestartet! Mit", num_combos, "Kombinationen.")
step = 0
while True:
# Weißlicht hat Vorrang
if white_input.value() == 0:
effect_white()
continue
# Aktuelle Effekt-Kombination
combo = combos[combo_mode]
# Alle Streifen gleichzeitig updaten
for idx, strip in enumerate(strips):
combo[idx % len(combo)](strip, step)
step += 1
time.sleep(0.05)
# Taster -> Nächste Effektkombination
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:
combo_mode = (combo_mode + 1) % num_combos
print("→ Neue Effektkombination:", combo_mode)
last_debounce_time = time.ticks_ms()
last_button_state = current_state