Beleuchtungscode hinzugefügt
This commit is contained in:
parent
ae9b468be7
commit
00481594cf
2 changed files with 169 additions and 0 deletions
163
beleuchtung.py
Normal file
163
beleuchtung.py
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
import machine
|
||||||
|
import neopixel
|
||||||
|
import utime
|
||||||
|
import urandom
|
||||||
|
from i2c_handler import I2CSlaveHandler, Packet
|
||||||
|
|
||||||
|
class LedHandler(I2CSlaveHandler):
|
||||||
|
def __init__(self, i2c_id, sda, scl, slave_addr):
|
||||||
|
super().__init__(i2c_id, sda, scl, slave_addr)
|
||||||
|
self.np = neopixel.NeoPixel(machine.Pin(29), 20)
|
||||||
|
self.mode = 2 # Start im rainbow mode
|
||||||
|
|
||||||
|
self.std_index = 0
|
||||||
|
self.rainbow_index = 0
|
||||||
|
self.rainbow_colors = self.generate_rainbow_colors(18 * 2) # doppelte Länge
|
||||||
|
self.rot_index = 0
|
||||||
|
self.rot_dir = 1 # Richtung für Puls
|
||||||
|
self.flashing_state = [0] * 20 # Status je LED
|
||||||
|
self.last_update = utime.ticks_ms()
|
||||||
|
def hsv_to_rgb(self, h, s, v):
|
||||||
|
h = float(h)
|
||||||
|
s = float(s)
|
||||||
|
v = float(v)
|
||||||
|
|
||||||
|
if s == 0.0:
|
||||||
|
return (int(v * 255), int(v * 255), int(v * 255))
|
||||||
|
|
||||||
|
i = int(h * 6)
|
||||||
|
f = (h * 6) - i
|
||||||
|
p = v * (1 - s)
|
||||||
|
q = v * (1 - s * f)
|
||||||
|
t = v * (1 - s * (1 - f))
|
||||||
|
i = i % 6
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
r, g, b = v, t, p
|
||||||
|
elif i == 1:
|
||||||
|
r, g, b = q, v, p
|
||||||
|
elif i == 2:
|
||||||
|
r, g, b = p, v, t
|
||||||
|
elif i == 3:
|
||||||
|
r, g, b = p, q, v
|
||||||
|
elif i == 4:
|
||||||
|
r, g, b = t, p, v
|
||||||
|
elif i == 5:
|
||||||
|
r, g, b = v, p, q
|
||||||
|
|
||||||
|
return (int(r * 255), int(g * 255), int(b * 255))
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
now = utime.ticks_ms()
|
||||||
|
|
||||||
|
if self.mode == 1: # rot
|
||||||
|
if utime.ticks_diff(now, self.last_update) >= 30:
|
||||||
|
self.rot_step()
|
||||||
|
self.last_update = now
|
||||||
|
|
||||||
|
elif self.mode == 2: # rainbow
|
||||||
|
if utime.ticks_diff(now, self.last_update) >= 100:
|
||||||
|
self.rainbow_step()
|
||||||
|
self.last_update = now
|
||||||
|
|
||||||
|
elif self.mode == 3: # standard
|
||||||
|
if utime.ticks_diff(now, self.last_update) >= 100:
|
||||||
|
self.standard_step()
|
||||||
|
self.last_update = now
|
||||||
|
|
||||||
|
elif self.mode == 4: # flashing
|
||||||
|
if utime.ticks_diff(now, self.last_update) >= 50:
|
||||||
|
self.flashing_step()
|
||||||
|
self.last_update = now
|
||||||
|
|
||||||
|
super().update()
|
||||||
|
|
||||||
|
def process_packet(self, packet: Packet):
|
||||||
|
cmd = packet[0]
|
||||||
|
if cmd == 0x10:
|
||||||
|
self.mode = packet[2]
|
||||||
|
print(f"Set colormode to {self.mode}")
|
||||||
|
else:
|
||||||
|
print(f"Unknown command 0x{cmd:02X}")
|
||||||
|
self.response_packet = None
|
||||||
|
|
||||||
|
# 🔴 Nicht-blockierende ROT-Animation (Pulsieren)
|
||||||
|
def rot_step(self):
|
||||||
|
brightness = self.rot_index
|
||||||
|
color = (brightness, 0, 0)
|
||||||
|
self.np.fill(color)
|
||||||
|
self.np.write()
|
||||||
|
|
||||||
|
self.rot_index += self.rot_dir * 5
|
||||||
|
if self.rot_index >= 255:
|
||||||
|
self.rot_index = 255
|
||||||
|
self.rot_dir = -1
|
||||||
|
elif self.rot_index <= 0:
|
||||||
|
self.rot_index = 0
|
||||||
|
self.rot_dir = 1
|
||||||
|
|
||||||
|
# 🌈 Verbesserter Regenbogen mit mehr Farben
|
||||||
|
def rainbow_step(self):
|
||||||
|
for i in range(18):
|
||||||
|
color_index = (self.rainbow_index + i) % len(self.rainbow_colors)
|
||||||
|
self.np[i] = self.rainbow_colors[color_index]
|
||||||
|
self.np[18] = (0, 0, 0)
|
||||||
|
self.np[19] = (0, 0, 0)
|
||||||
|
self.np.write()
|
||||||
|
self.rainbow_index = (self.rainbow_index + 1) % len(self.rainbow_colors)
|
||||||
|
|
||||||
|
def generate_rainbow_colors(self, steps):
|
||||||
|
colors = []
|
||||||
|
for i in range(steps):
|
||||||
|
hue = i / steps # 0.0 - 1.0 → 0° - 360°
|
||||||
|
rgb = self.hsv_to_rgb(hue, 1.0, 1.0)
|
||||||
|
colors.append(rgb)
|
||||||
|
return colors
|
||||||
|
|
||||||
|
|
||||||
|
# 🔵 Standard-Lauflicht
|
||||||
|
def standard_step(self):
|
||||||
|
i = self.std_index
|
||||||
|
self.np[i % 17] = (0, 0, 225)
|
||||||
|
if i >= 4:
|
||||||
|
self.np[i - 4] = (0, 225, 100)
|
||||||
|
if i >= 8:
|
||||||
|
self.np[i - 8] = (0, 225, 0)
|
||||||
|
if i >= 12:
|
||||||
|
self.np[i - 12] = (0, 225, 100)
|
||||||
|
self.np[17] = (0, 0, 255)
|
||||||
|
self.np[18] = (0, 0, 255)
|
||||||
|
self.np.write()
|
||||||
|
self.std_index = (i + 1) % 17
|
||||||
|
|
||||||
|
# ✨ Flashing-Effekt mit zufälligen LEDs
|
||||||
|
def flashing_step(self):
|
||||||
|
for i in range(20):
|
||||||
|
if self.flashing_state[i] > 0:
|
||||||
|
self.flashing_state[i] -= 1
|
||||||
|
if self.flashing_state[i] == 0:
|
||||||
|
self.np[i] = (0, 0, 0)
|
||||||
|
elif urandom.getrandbits(6) == 0: # ca. 1:64 Chance zu flashen
|
||||||
|
self.flashing_state[i] = urandom.getrandbits(2) + 1
|
||||||
|
color = urandom.choice([
|
||||||
|
(255, 0, 0), (0, 255, 0), (0, 0, 255),
|
||||||
|
(255, 255, 0), (0, 255, 255), (255, 0, 255)
|
||||||
|
])
|
||||||
|
self.np[i] = color
|
||||||
|
self.np.write()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
handler = LedHandler(i2c_id=0, sda=0, scl=1, slave_addr=0x42)
|
||||||
|
print("LED handler I2C slave started")
|
||||||
|
try:
|
||||||
|
handler.handle()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
handler.deinit()
|
||||||
|
print("I2C slave stopped")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
@ -46,6 +46,9 @@ class I2CSlaveHandler:
|
||||||
self.response_buf = None
|
self.response_buf = None
|
||||||
self.response_idx = 0
|
self.response_idx = 0
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
state = self.s_i2c.I2CStateMachine.I2C_IDLE
|
state = self.s_i2c.I2CStateMachine.I2C_IDLE
|
||||||
while True:
|
while True:
|
||||||
|
@ -92,6 +95,8 @@ class I2CSlaveHandler:
|
||||||
self.response_buf = None
|
self.response_buf = None
|
||||||
self.response_idx = 0
|
self.response_idx = 0
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
|
||||||
def process_packet(self, packet):
|
def process_packet(self, packet):
|
||||||
"""Override this method to process packets."""
|
"""Override this method to process packets."""
|
||||||
# Example: Print command/type and target/channel
|
# Example: Print command/type and target/channel
|
||||||
|
@ -122,3 +127,4 @@ def main():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue