Zum Inhalt

Lounge Beleuchtung

Die Beleuchtung in der Lounge besteht aus ca. 2200 LEDs vom Typ WS2812B. Und werden von einem FPGA-Board bespielt. Wir nutzen Lightsd um die Effekte auf den LEDs zu konfigurieren.

Lightsd

Lightsd ist eine in C++ geschriebene Anwendung welche anhand der in der config.yml beschriebenen Effekt erzeugt. Wärend der Ausführung können die meisten Parameter via MQTT angepassst werden .Das beinhaltet die aktiven Operationen als auch deren Parameter (bspw. Helligkeit, Farbwerte, …).

Effekte via Netzwerk einspielen

Zum Entwickeln von Effekten ist es durchaus sehr angenehm wenn man diese lokal ausprobieren kann und nach etwas lokalem Testen auf den LEDs in der W17 testen kann. Lightsd unterstützt das Anzeigen von per UDP Empfangenen Frames. Jeder Frame ist dabei ein (fragmentierte) UDP Paket mit vielen HSV-Werten. Jeder HSV Wert besteht aus drei float32 Feldern (in der Reihenfolge H, S, V). Es gibt keinen zusätzlichen Längenindikator.

Der entsprechende Input kann via Homeassistant aktiviert werden. Derzeit wird er als "Lightsd UDP Input (Port 1337)" geführt. Der Host an den die Pakete geschickt werden müssen ist lightsd.cccda.de. (TODO: offline)

Prototyping mit Python

Wer auch immer gerne Python verwendet um Effekte zu basteln findet ein paar hilfreiche Python Skripte im GitLab. Ein gutes Beispiel ist Raindrop.

Prototyping mit Lua über MQTT

Unter der MQTT-Adresse w17/lounge/light/mqtt-lua/code/set kann man ein Lua-Skript als Wert hinterlegen, welches von Lightsd dann ausgeführt wird:

mosquitto_pub -h mqtt.cccda.de -t w17/lounge/light/mqtt-lua/code/set -m 'function render(pBuffer)
   local buffer = HSVBuffer(pBuffer)
   local size = buffer:size()
   for i = 0, size -1 do
       buffer:set(i, i * (360.0/size), 0.8, 0.8)
   end
end
'

Soundvis

Seit dem Umzug in die W17 funktioniert unser altes Soundvis script leider nicht mehr ausreichend gut. Mit dem Wechsel von ~24 LEDs auf über 2000 LEDs haben wir das Limit erreicht. Nach einigen Abenden gibt es mittlerweile einen neuen Ansatz das Problem zu lösen: Wir haben einen Daemon entwicklet welcher (remote) auf whisky den Sound via Pulseaudio abgreift. Der Sound wird dann analysiert und die Erbenisse (nach FFT) per TCP auf port 1338 (auf whisky) bereitgestellt.

Jedes Datenpaket hat das folgende Format (alle Werte in Little Endian):

Name Type Beschreibung
Length uint32_t Anzahl der Bins
samples float32[Length] Array der Bins

Die Frequenz steigt mit dem Index. Das erste Bin hat die niedrigste Frequenz. Die Frequenzauflösung ist zur Zeit 12 Bins pro Oktave (also 1 pro Halbton) bei 7 Oktaven. Die Oktaven werden um den Ton 440Hz angeordnet, 4 darüber, 3 darunter. Das ergibt ein Frequenzspektrum von 55Hz-7040Hz. Es wird alle 16ms ein Paket gesandt, auch wenn die tieferen Frequenzen seltener gesampled werden.

Pynq

Das Pynq (derzeit auf dem hängenden Rack in der Lounge) bespielt die zwei LED stripes in der Lounge. Das Board enthält auch zwei ARM cores auf denen Linux läuft.

Der source code für die in Bluespec geschriebenen Teil liegt im GitLab.

Zugriff auf die LEDs erhält man durch Speicher der gemappt wurde. Zugriff erfolgt mittels lightsd und dem DevMem output. Die default Konfiguration passt auf unser Setup. Lediglich die Anzahl der stripes und der jeweiligen Anzahl an LEDs muss konfiguriert werden.

Das Memory Layout ist folgendes:

Offset
Data Offset 0x1ff00000
Configuration Offset 0x40000000

Ab der Stelle von Confiugration Offset sind folgende Felder verfügbar:

Name Type Beschreibung
t0l uint32_t T0L Zeit in us
t0h uint32_t T0H Zeit in us
t1l uint32_t T1L Zeit in us
t1h uint32_t T1H Zeit in us
res uint32_t ??????????????
read_addr uint32_t Adresse der Daten
led_count uint32_t[50] Liste der LED counts, je element ein stripe

Ab der angegebenen read_add bzw. Data Offset findet man folgende Daten:

Name Type Beschreibung
LEDs LargeRGB[N] Array aller LEDs (0->N)

LargeRGB hat das Format:

Name Type Beschreibung
b uint8_t blue in RGB
g uint8_t green in RGB
r uint8_t red in RGB
empty uint8_t empty, for future use