diff --git a/beleuchtung.py b/beleuchtung.py new file mode 100644 index 0000000..314b042 --- /dev/null +++ b/beleuchtung.py @@ -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() + diff --git a/i2c_handler.py b/i2c_handler.py index f3f7698..dfc3803 100644 --- a/i2c_handler.py +++ b/i2c_handler.py @@ -45,6 +45,9 @@ class I2CSlaveHandler: self.packet_buf = [] self.response_buf = None self.response_idx = 0 + + def update(self): + pass def handle(self): state = self.s_i2c.I2CStateMachine.I2C_IDLE @@ -91,6 +94,8 @@ class I2CSlaveHandler: # Reset response for next transaction self.response_buf = None self.response_idx = 0 + + self.update() def process_packet(self, packet): """Override this method to process packets.""" @@ -122,3 +127,4 @@ def main(): if __name__ == "__main__": main() +