from machine import Pin
import neopixel
import time
import urandom
# -----------------------------
# Konfiguration
# -----------------------------
NUM_LEDS = 8
NUM_STRIPS = 6
STRIP_PINS = [2, 3, 4, 5, 6, 7]
EFFECT_BUTTON_PIN = 8
WHITE_TRIGGER_PIN = 9
# Setup NeoPixel-Streifen
strips = [neopixel.NeoPixel(Pin(pin), NUM_LEDS) for pin in STRIP_PINS]
# Pins
button_pin = Pin(EFFECT_BUTTON_PIN, Pin.IN, Pin.PULL_UP)
white_input = Pin(WHITE_TRIGGER_PIN, Pin.IN, Pin.PULL_UP)
# Modusverwaltung
mode = 0
num_modes = 5 # 0=aus, 1=blinken, 2=lauflicht, 3=regenbogen, 4=random color, 5=color wave
# Debounce
last_button_state = 1
last_debounce_time = time.ticks_ms()
debounce_delay = 200 # ms
# Timer für Effekte
last_effect_time = time.ticks_ms()
# -----------------------------
# Hilfsfunktionen
# -----------------------------
def set_all(r, g, b):
for strip in strips:
for i in range(NUM_LEDS):
strip[i] = (r, g, b)
strip.write()
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 (nicht-blockierend)
# -----------------------------
effect_state = {
"blink_on": True,
"blink_last": time.ticks_ms(),
"chase_pos": 0,
"rainbow_shift": 0,
"color_wave_shift": 0
}
def effect_off():
set_all(0, 0, 0)
def effect_white():
set_all(255, 255, 255)
def effect_blink():
now = time.ticks_ms()
if time.ticks_diff(now, effect_state["blink_last"]) > 300:
effect_state["blink_on"] = not effect_state["blink_on"]
effect_state["blink_last"] = now
color = 255 if effect_state["blink_on"] else 0
set_all(color, color, color)
def effect_chase():
now = time.ticks_ms()
if time.ticks_diff(now, effect_state.get("chase_last", 0)) > 50:
pos = effect_state["chase_pos"]
for strip in strips:
for i in range(NUM_LEDS):
strip[i] = (255, 255, 255) if i == pos else (0, 0, 0)
strip.write()
effect_state["chase_pos"] = (pos + 1) % NUM_LEDS
effect_state["chase_last"] = now
def effect_rainbow():
now = time.ticks_ms()
if time.ticks_diff(now, effect_state.get("rainbow_last", 0)) > 50:
shift = effect_state["rainbow_shift"]
for j in range(NUM_LEDS):
color = wheel((j * 256 // NUM_LEDS + shift) % 256)
for strip in strips:
strip[j] = color
for strip in strips:
strip.write()
effect_state["rainbow_shift"] = (shift + 5) % 256
effect_state["rainbow_last"] = now
def effect_random_colors():
now = time.ticks_ms()
if time.ticks_diff(now, effect_state.get("random_last", 0)) > 300:
for strip in strips:
for i in range(NUM_LEDS):
r = urandom.getrandbits(8)
g = urandom.getrandbits(8)
b = urandom.getrandbits(8)
strip[i] = (r, g, b)
strip.write()
effect_state["random_last"] = now
def effect_color_wave():
now = time.ticks_ms()
if time.ticks_diff(now, effect_state.get("wave_last", 0)) > 30:
shift = effect_state["color_wave_shift"]
for j in range(NUM_LEDS):
color = wheel((j * 10 + shift) % 256)
for strip in strips:
strip[j] = color
for strip in strips:
strip.write()
effect_state["color_wave_shift"] = (shift + 3) % 256
effect_state["wave_last"] = now
# -----------------------------
# Hauptschleife
# -----------------------------
while True:
# Weißlicht hat immer Vorrang
if white_input.value() == 0:
effect_white()
else:
if mode == 0:
effect_off()
elif mode == 1:
effect_blink()
elif mode == 2:
effect_chase()
elif mode == 3:
effect_rainbow()
elif mode == 4:
effect_random_colors()
elif mode == 5:
effect_color_wave()
# Taster für Effektwechsel mit Debounce
current_state = button_pin.value()
if current_state == 0 and last_button_state == 1:
if time.ticks_diff(time.ticks_ms(), last_debounce_time) > debounce_delay:
mode = (mode + 1) % (num_modes + 1)
last_debounce_time = time.ticks_ms()
last_button_state = current_state
# Kurze Pause, um CPU nicht zu blockieren
time.sleep(0.01)