Hardware-Encoder für NeoPixel (WS2812)/Hardware

Aus Hackerspace Bielefeld Wiki
Zur Navigation springen Zur Suche springen

Wir werden konkret

Bevor wir loslegen können, müssen wir uns noch ein paar darüber machen, was unsere Schaltung tun und wie sie arbeiten soll. Da I/O-Pins an einem µController immer Mangelware sind, bieten sich für die Datenübertragung zu unserem Encoder serielle Schnittstellen an. Eigentlich immer vorhanden sind UARTs und SPI-Schnittstellen.

SPI braucht zwar mehr Leitungen als ein UART, ist dafür aber schneller und man kann, sofern die restliche Schaltung das zulässt, mehrere Geräte an ein und derselben Schnittstelle betreiben. UART hat vor allem den Vorteil, daß praktisch jeder Microcontroller einen oder mehrere davon an Bord hat. Dazu kommt, daß sich die Schaltung auch an einem normalen PC oder Mac betreiben lässt. Falls dort keine echte Schnittstelle mehr vorhanden ist, kann man einfach einen USB-Adapter verwenden.

Da selbst kleine FPGAs (Spartan 6 LX 4 z.B.) mehr als genug Ressourcen für unser Projekt bieten, können wir einfach beide Schnittstellen implementieren.

Die ankommenden Bytes könnten wir jetzt direkt in den Pixel-Encoder stecken. Allerdings müssen wir dann immer alle Daten neu übertragen und die zeitliche Entkopplung der Ausgabe an den Encoder ist auch nicht gegeben. Das können wir durch einen Pufferspeicher lösen. Wir benötigen für 512 LEDs je 3 Bytes, also 1,5KiB RAM.

Jetzt können wir die Daten per UART oder SPI in das RAM schreiben und der Encoder kann sie auslesen, wie es ihm passt, und sie zur Anzeige bringen. Sind wir fertig? Noch nicht ganz. Neben Zugriff auf den Speicher wäre es sinnvoll, verschiedene Einstellungen bei Bedarf anpassen zu können. Z.B. gibt es vom WS2812 zwei Varianten mit leicht abweichenden Timings. Dann kann es sein, daß deine Hardware eine andere ist, ein anderes FPGA, anderer Takt - kurzum: Wir wollen Zugriff auf Konfigurationsregister.

Damit wird die Sache noch ein bisschen komplexer: Wir müssen festlegen können, wann wir LED-Daten senden und wann wir auf ein Register zugreifen wollen, und auf welches. Wir brauchen ein Protokoll! Und einen Automaten, der es versteht. Also einen Protokoll-Interpreter.