Umfassende Anleitung zur Steuerung eines LED-Streifens mit einem Dreh-Puck und ESP32
Erstellen Sie ein interaktives LED-System mit Python und WiFi-Kommunikation
Wichtige Erkenntnisse
- Hardware-Komponenten und deren Integration: Der Einsatz von ESP32 Mikrocontrollern, adressierbaren LED-Streifen und einem Dreh-Puck bildet die Grundlage für das Projekt.
- Software-Implementierung in Python: Die Programmierung mit MicroPython ermöglicht die effiziente Steuerung und Kommunikation zwischen den Geräten.
- WiFi-basierte Kommunikation: Die Nutzung von MQTT oder WebSockets gewährleistet eine zuverlässige Datenübertragung zwischen Puck und LED-Controller.
Projektübersicht
Dieses Projekt zielt darauf ab, einen adressierbaren LED-Streifen mithilfe eines speziell entwickelten Pucks zu steuern. Der Puck verfügt über einen drehbaren Außenring und einen zentralen Button, der verschiedene Funktionalitäten ermöglicht. Die Steuerung erfolgt über zwei separate ESP32-Controller, die über WiFi kommunizieren.
1. Hardware-Komponenten
1.1 ESP32 Mikrocontroller
Der ESP32 dient als Herzstück des Projekts. Zwei ESP32-Boards werden benötigt: eines für den LED-Controller und eines für den Puck.
- LED-Controller ESP32: Steuert den LED-Streifen und empfängt Befehle vom Puck.
- Puck ESP32: Verarbeitet Eingaben vom Dreh-Puck und sendet Befehle via WiFi.
1.2 Adressierbarer LED-Streifen
Verwenden Sie einen adressierbaren LED-Streifen wie WS2812B oder APA102. Jede LED kann individuell angesteuert werden, was komplexe Animationen und Steuerungen ermöglicht.
1.3 Dreh-Puck mit Button
Der Puck besteht aus einem drehbaren Außenring (Rotary Encoder) und einem zentralen Button. Der Encoder erfasst Drehbewegungen und der Button dient zur Steuerung der Modi.
1.4 Stromversorgung
Stellen Sie sicher, dass sowohl der LED-Streifen als auch die ESP32-Boards ausreichend mit Strom versorgt werden. Nutzen Sie geeignete Netzteile, um Spannungsabfälle zu vermeiden.
2. Software-Komponenten
2.1 Programmiersprache: Python mit MicroPython
Die Programmierung erfolgt in Python, wobei MicroPython auf den ESP32-Boards eingesetzt wird.
2.2 Kommunikationsprotokoll: MQTT
MQTT ist ein leichtgewichtiges Protokoll, ideal für IoT-Anwendungen. Es ermöglicht eine effiziente Kommunikation zwischen dem Puck und dem LED-Controller über WiFi.
2.3 Bibliotheken und Frameworks
- umqtt.simple: Für die MQTT-Kommunikation.
- neopixel: Zur Steuerung des LED-Streifens.
- machine: Für die Kommunikation mit den Hardware-Komponenten.
3. Implementierung
3.1 Aufbau des Puck-Geräts
3.1.1 Hardware-Verkabelung
- Verbinden Sie den Rotary Encoder mit den GPIO-Pins des Puck-ESP32.
- Schließen Sie den Button an einen digitalen Eingang des ESP32 an.
3.1.2 Software-Programmierung
Das Puck-Gerät liest die Eingaben des Encoders und des Buttons und sendet entsprechende Befehle an den LED-Controller über MQTT.
import time
import network
from umqtt.simple import MQTTClient
from machine import Pin, RotaryEncoder
# WLAN-Konfiguration
SSID = 'DeinWLAN'
PASSWORD = 'DeinPasswort'
MQTT_BROKER = '192.168.1.100' # IP des LED-Controllers
# Initialisierung
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(1)
client = MQTTClient("puck_device", MQTT_BROKER)
client.connect()
# Rotary Encoder und Button
encoder = RotaryEncoder(5, 6)
button = Pin(4, Pin.IN, Pin.PULL_UP)
last_click = 0
mode = "single"
def send_command(command, value=None):
if value:
payload = f'{{"action": "{command}", "value": "{value}"}}'
else:
payload = f'{{"action": "{command}"}}'
client.publish(b"led/control", payload.encode())
while True:
if not button.value():
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_click) < 300:
# Doppelklick erkannt
mode = "width" if mode == "single" else "single"
send_command("mode_change", mode)
else:
# Einzelklick
send_command("toggle")
last_click = current_time
time.sleep(0.3)
delta = encoder.steps()
if delta != 0:
direction = "right" if delta > 0 else "left"
if mode == "single":
send_command("move", direction)
elif mode == "width":
send_command("adjust_width", direction)
encoder.reset()
time.sleep(0.1)
3.2 Aufbau des LED-Controllers
3.2.1 Hardware-Verkabelung
-
Verbinden Sie den LED-Streifen mit den entsprechenden GPIO-Pins des LED-Controller-ESP32.
-
Stellen Sie sicher, dass die Stromversorgung ausreichend dimensioniert ist.
3.2.2 Software-Programmierung
Der LED-Controller empfängt Befehle vom Puck und steuert den LED-Streifen entsprechend.
import network
from umqtt.simple import MQTTClient
from neopixel import NeoPixel
from machine import Pin
import json
# WLAN-Konfiguration
SSID = 'DeinWLAN'
PASSWORD = 'DeinPasswort'
MQTT_BROKER = '192.168.1.100'
# Initialisierung
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
pass
client = MQTTClient("led_controller", MQTT_BROKER)
client.connect()
# LED-Streifen
NUM_LEDS = 60
LED_PIN = 4
strip = NeoPixel(Pin(LED_PIN), NUM_LEDS)
active_led = 0
light_width = 1
mode = "single"
is_on = False
def update_leds():
for i in range(NUM_LEDS):
if active_led - light_width//2 <= i <= active_led + light_width//2:
strip[i] = (255, 255, 255)
else:
strip[i] = (0, 0, 0)
strip.write()
def handle_message(topic, msg):
global active_led, light_width, mode, is_on
data = json.loads(msg.decode())
action = data.get("action")
if action == "toggle":
is_on = not is_on
elif action == "move":
direction = data.get("value")
if direction == "right":
active_led = (active_led + 1) % NUM_LEDS
else:
active_led = (active_led - 1) % NUM_LEDS
elif action == "adjust_width":
direction = data.get("value")
if direction == "right":
light_width = min(light_width + 1, NUM_LEDS)
else:
light_width = max(light_width - 1, 1)
elif action == "mode_change":
mode = data.get("value")
update_leds()
def sub_cb(topic, msg):
handle_message(topic, msg)
client.set_callback(sub_cb)
client.subscribe(b"led/control")
while True:
client.wait_msg()
if is_on:
update_leds()
else:
for i in range(NUM_LEDS):
strip[i] = (0, 0, 0)
strip.write()
4. Kommunikation über WiFi
Die beiden ESP32-Controller kommunizieren über ein gemeinsames WiFi-Netzwerk. Der Puck sendet Befehle an den LED-Controller mittels MQTT.
4.1 MQTT-Broker Einrichtung
Ein MQTT-Broker ist notwendig, um die Nachrichten zwischen Puck und LED-Controller zu vermitteln. Sie können einen lokalen Broker wie Mosquitto installieren oder einen Cloud-basierten Dienst verwenden.
4.2 MQTT-Themenstruktur
| Thema | Beschreibung |
|---|---|
| led/control | Empfängt Steuerbefehle vom Puck |
5. Funktionalität im Detail
5.1 Einzelklick: Toggle einer LED
Ein einzelner Klick auf den Button aktiviert oder deaktiviert die aktuelle Haupt-LED.
5.2 Drehen: Verschieben der Haupt-LED
Drehen des Außenrings verschiebt die aktive Haupt-LED nach rechts oder links, abhängig von der Drehrichtung.
5.3 Doppelklick: Moduswechsel zur Breitensteuerung
Ein Doppelklick wechselt den Modus zur Anpassung der Lichtbreite. Im Breitenmodus kann mittels Drehens des Rads die Anzahl der leuchtenden LEDs erweitert oder reduziert werden.
5.4 Speichern der Breite und Rückkehr zum Verschiebungsmodus
Ein weiterer Doppelklick speichert die aktuelle Breite und kehrt zum Modus des Verschiebens der Haupt-LED über die gesamte Breite des Streifens zurück.
5.5 Mindestanforderung: Immer eine LED aktiv
Es wird sichergestellt, dass immer mindestens eine LED aktiv bleibt, indem die Haupt-LED stets eingeschaltet bleibt, auch wenn die Breite geändert wird.
6. Code-Beispiele und Implementierung
6.1 Puck-Gerät: Python-Code
import time
import network
from umqtt.simple import MQTTClient
from machine import Pin, RotaryEncoder
# WLAN-Konfiguration
SSID = 'DeinWLAN'
PASSWORD = 'DeinPasswort'
MQTT_BROKER = '192.168.1.100'
# Initialisierung
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(1)
client = MQTTClient("puck_device", MQTT_BROKER)
client.connect()
encoder = RotaryEncoder(5, 6)
button = Pin(4, Pin.IN, Pin.PULL_UP)
last_click = 0
mode = "single"
def send_command(command, value=None):
if value:
payload = f'{{"action": "{command}", "value": "{value}"}}'
else:
payload = f'{{"action": "{command}"}}'
client.publish(b"led/control", payload.encode())
while True:
if not button.value():
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_click) < 300:
mode = "width" if mode == "single" else "single"
send_command("mode_change", mode)
else:
send_command("toggle")
last_click = current_time
time.sleep(0.3)
delta = encoder.steps()
if delta != 0:
direction = "right" if delta > 0 else "left"
if mode == "single":
send_command("move", direction)
elif mode == "width":
send_command("adjust_width", direction)
encoder.reset()
time.sleep(0.1)
6.2 LED-Controller: Python-Code
import network
from umqtt.simple import MQTTClient
from neopixel import NeoPixel
from machine import Pin
import json
# WLAN-Konfiguration
SSID = 'DeinWLAN'
PASSWORD = 'DeinPasswort'
MQTT_BROKER = '192.168.1.100'
# Initialisierung
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
pass
client = MQTTClient("led_controller", MQTT_BROKER)
client.connect()
# LED-Streifen
NUM_LEDS = 60
LED_PIN = 4
strip = NeoPixel(Pin(LED_PIN), NUM_LEDS)
active_led = 0
light_width = 1
mode = "single"
is_on = False
def update_leds():
for i in range(NUM_LEDS):
if active_led - light_width//2 <= i <= active_led + light_width//2:
strip[i] = (255, 255, 255)
else:
strip[i] = (0, 0, 0)
strip.write()
def handle_message(topic, msg):
global active_led, light_width, mode, is_on
data = json.loads(msg.decode())
action = data.get("action")
if action == "toggle":
is_on = not is_on
elif action == "move":
direction = data.get("value")
if direction == "right":
active_led = (active_led + 1) % NUM_LEDS
else:
active_led = (active_led - 1) % NUM_LEDS
elif action == "adjust_width":
direction = data.get("value")
if direction == "right":
light_width = min(light_width + 1, NUM_LEDS)
else:
light_width = max(light_width - 1, 1)
elif action == "mode_change":
mode = data.get("value")
update_leds()
def sub_cb(topic, msg):
handle_message(topic, msg)
client.set_callback(sub_cb)
client.subscribe(b"led/control")
while True:
client.wait_msg()
if is_on:
update_leds()
else:
for i in range(NUM_LEDS):
strip[i] = (0, 0, 0)
strip.write()
7. Testing und Debugging
7.1 Überprüfung der WLAN-Verbindung
Sicherstellen, dass beide ESP32-Boards mit demselben WLAN-Netzwerk verbunden sind.
7.2 LED-Funktionalität testen
Überprüfen Sie die Helligkeit und die korrekte Animation der LEDs. Stellen Sie sicher, dass die Haupt-LED immer aktiv bleibt und die Breite korrekt angepasst wird.
7.3 Eingabeüberprüfung
Testen Sie die Reaktionen auf Einzel- und Doppelklicks sowie das Drehen des Außenrings. Stellen Sie sicher, dass die Befehle korrekt interpretiert und umgesetzt werden.
8. Weiterführende Ressourcen
Schlussfolgerung
Die Umsetzung dieses Projekts erfordert eine sorgfältige Auswahl und Integration von Hardware- und Software-Komponenten. Durch den Einsatz von ESP32-Mikrocontrollern, adressierbaren LED-Streifen und einem benutzerdefinierten Puck können vielfältige Steuerungsmöglichkeiten realisiert werden. Die Nutzung von Python und MicroPython erleichtert die Programmierung und Anpassung der Steuerlogik, während MQTT eine zuverlässige Kommunikation zwischen den Geräten sicherstellt. Mit dieser Anleitung sind Sie bestens gerüstet, um ein funktionsreiches und anpassbares LED-Steuerungssystem zu entwickeln.
Last updated January 24, 2025