www.blafusel.de

  Home  |   Privat  |   Impressum  |   Bücher  |   Computer  |   Misc  |   OBD  |   Forum

zonak

Tetris Spiel auf LED Matrix aus WS128B

Tetris

Quasi schon immer, wollte ich irgendein Projekt mit einer großen LED Matrix bauen. Am liebsten eine ganze Videowand oder eine große Textanzeige. Dummerweise braucht man dafür sehr viele LEDs. Die sind zwar billig aber dann muß man sie alle irgendwo montieren und zusammen löten. Und da mir natürlich auch eine eigentlich sinnvolle Anwendung fehlt, blieb das immer eins der vielen brach liegenden Projekte. Inzwischen hat sich aber bei den LEDs einiges getan und relativ neu sind LED Streifen. Auf einer dünnen Trägerfolie sitzt eine RGB LED inkl. Controller vom Typ WS2812B (PDF) von Worldsemi. So ein LED Segment ist immer mit dem nächsten verbunden, wobei die drei Anschlüsse +5V, GND und das Datensignal weiter gereicht werden. Die Streifen können im Grunde beliebig lang sein. Zum kürzen wird einfach zwischen zwei Segmenten mit einer Schere die Folie zerschnitten. Einzelne Segmente können aneinander gelötet werden. Dabei ist nur darauf zu achten, daß sich auf der einen Seite eines Segments der Dateneingang befindet und auf der anderen Seite der Datenausgang. Es muß also immer ein Ausgang gegenüber einem Eingang liegen. Die Daten werden seriell als PWM Signal von der ersten LED an die nächste weitergeschoben, welche wiederum die Daten weiterreicht. Dabei entnimmt jede LED (bzw. der integrierte Controller) die ersten drei Bytes des Datensignals und reicht nur die dann noch folgenden weiter. Die drei Bytes enthalten die Helligkeitswerte für die Farben Grün, Rot, Blau (etwas ungewöhnliche Reihenfolge), wobei das High Bit zuerst gesendet wird. Die Daten werden also in einer sogenannten Daisychain weiter gegeben.
WS2812B LED Streifen

Die Streifen gibt es mit 30, 60 und 144 LEDs pro Meter. Beim Kauf bei ebay ist darauf zu achten, was der Verkäufer schreibt. Viele tricksen da mit den Angaben. Ein Meter 60er Variante kostet etwa € 17,- inkl. Versand. Ich habe erst einmal drei Meter bestellt und dann weitere vier, als ich gesehen habe, das alles klappt. Zusammen kosten also alleine die LEDs schon gut und gerne € 100,-.

Komplette Matrix mit 29 Zeilen à 14 Spalten

Die Streifen sind nicht endlos lang gefertigt. Entweder sind bei der werksseitigen Qualitätskontrolle oder beim späteren Zerstückeln LEDs bereits aus dem Streifen entfernt worden und die gelieferten Streifen weisen mehrere Lötstellen auf, an denen Streifen zusammen gelötet wurden. Das ist wohl gängige Praxis. Leider wurden dabei die Streifen nicht auf Stoß, sondern überlappend verlötet. Das führt dazu, daß der Abstand der LEDs nicht einheitlich 16,7 mm beträgt. Das ist mir aber natürlich erst aufgefallen, als ich die Streifen mit dem rückseitigen Klebeband aufgeklebt hatte und kein sauberes Raster entstand. Ist nicht dramatisch, sollte man aber ggf. beachten.

Pro Farbe werden bei 5 V ca. 20 mA benötigt. Eine LED zieht also 60 mA. Auf einen 60er Meter sind das dann immerhin schon 3,6 A. Für meine knapp sieben Meter mit 406 LEDs benötige ich rein rechnerisch im worst case (alle LEDs weiß) 24,36 A. Das ist ordentlich Leistung und wird noch zu Problemen führen. Auf keinen Fall kann man das über seinen Mikrocontroller und dessen Festspannungsregler ziehen. Strom sparen kann man natürlich kräftig, wenn man die LEDs nicht mit maximaler Helligkeit (0xFF) ansteuert und auch nicht alle gleichzeitig.

Als Anwendung wollte ich zuerst einmal den üblichen Tetris Clone programmieren - das hello world der LED Matritzen. Natürlich gibt es alles fertig aus der Kiste. Für den Arduino Anwender erst recht, denn die gehören ja am allermeisten zu der cut and copy Fraktion. Aber zum einen will ich das selber machen, um was zu lernen, dann sind die Arduino Pakete sehr aufgebläht, weil sie so toll universell sind und ohne stundenlanges gefrickel im Code, um die Arduinosepzifischen Codeschnipsel zu entfernen, kommt man zu keinem Ergebnis, wenn man nicht die Arduino IDE benutzen will.

LED Streifen mit Verbindungen aus Kupferlackdraht

Im ersten Schritt steht natürlich das Verkabeln der Stripes. Da die lokale Baumarkt- und Geschäftwelt keinen (preiswerten) Bilderrahmen mit dickem und tiefem Rand anbietet, wie er bei IKEA erhältlich ist, weshalb IKEA zum neuen Underdog für Hacker und Maker evancaiert, muß der Rahmen mit den Fotos der Ex herhalten und bietet eine gute Gelegenheit, mit der Vergangenheit aufzuräumen. Auf die Rückwand werden die Streifen geklebt. Da ein LED Segment 16,7 mm lang ist (es sei denn, es wurden Segmente zusammen gelötet), muß der Abstand der Streifen genau so groß sein, soll ein quadratisches Raster entstehen. Die Klebefolie auf der Rückseite der Streifen ist praktisch. Üblicherweise werden die Streifen alle gleich ausgerichtet (also zum Beispiel von unten nach oben). Dann ist aber viel Verkabelung erforderlich, weil die Datenleitung ja vom oberen Ende einer Reihe zum unteren Anfang der nächsten verlegt werden muß. Das ist nur lästig und wenig elegant. Wenn man die Streifen im Wechsel verbaut, reduziert sich das Kabelgewirr. Es ist dann Aufgabe der Software, die "verdrehten" Streifen richtig anzusteuern.

Aufbau mit ATmega328. Arduiono Pro Mini

Die Ansteuerung der LED ist sehr zeitkritisch. Weil das benötigte Signal keinem gängigen Protokoll entspricht, gibt es auch keine Hardwareunterstützung wie bei TWI etc. Es gibt verschiedene Ansätze, wie die Bits vom Microcontroller erzeugt werden können. Die einfache Methode nutzt das Bit banging, bei dem die Bits und das Timing komplett per Software erzeugt wird. Damit die Zeiten exakt eingehalten werden, ist die Bitmusterausgabe in Assembler programmiert, denn nur so kann genau festgelegt werden, welche Ausführungszeiten auftreten. Das behagt einem C-Programmierer nicht aber man kann zum Glück auf die Arbeit anderer Leute zurückgreifen. Eine andere Methode nutzt das SPI Interface der AVRs, was sicher elegant ist. Ich habe den erst besten Code probiert. Der war kurz und knapp und funktionierte auf Anhieb - so macht es Spaß. Für die ersten Schritte nutzte ich das mir bekannte und in meinen Augen sehr brauchbare Entwicklerboard von Pollin. Da bei mir noch ein halbes Dutzend kleiner Arduino Pro Mini Boards herumfliegt, die man vom Chinesen für fast weniger Geld bekommt (ca. € 2,50), als man hierzulande für den darauf verbauten ATmega328 alleine bezahlen würde (dessen Arduino Bootloader man ja nur zu löschen braucht, um wieder einen "nackten" AVR für eigenen Code zu haben), soll der Code später darauf laufen, damit der Controller in einer schicken Spielkonsolensteuerung verschwinden kann. Wichtig ist der kleine Widerstand von 220 Ω in der Datenleitung. Alles andere ist schnell zusammengesteckt. Für die ersten Versuche genügen die Taster auf dem Evaluationsboard. Weil auf dem Board 16 MHz Quarze verbaut sind, habe ich den ATmega328 auf dem Mini Modul auch einfach mit einem solchen Quarz gepimt, weil meine Module "nur" 8 MHz haben, was aber eigentlich auch genügen sollte.

Zuschneiden der Pappe für das lichtformende Raster

Tetris zu programmieren ist zwar keine unlösbare Aufgabe, aber auch nicht ganz trivial. Man muß sich Gedanken über die Spiellogik machen, in welchem Dateityp man die Steine ablegt und wie das Spielfeld. Zudem mußte ich ja auch noch dafür sorgen, daß die x-y Koordinaten der Pixel eines zweidimensionalen Spielfeldes bei der Ausgabe umsortiert werden, weil ich die LED Streifen ja meanderförmig verklebt habe. Nach einigen Stunden stand dann aber das grobe Spielgerüst und es sah schon ganz nett aus. Den Highsore kann man auch speichern.

Das Raster aus Pappe

Was jetzt noch fehlte, waren richtige Kästchen. Die runden LEDs irritieren ein wenig und sehen nicht perfekt aus für ein Spiel, bei dem es um Quadrate geht. Das passende System für ein lichtformendes Raster zu finden, geisterte schon seit langem immer bei mir im Kopf herum. Eine einfache Lösung fällt mir nicht ein und der Markt bietet auch nichts an. Im Baumarkt habe ich mir Pflanzen-, Malerabstreif-, Regerinnengitter, Rohre und Profile angeschaut. Alles nicht passend. Einen Plastikwinkel als Profilleiste hätte ich nehmen können, aber den dann zu schneiden klappte auch nicht gut. Jetzt fehlte mir dann doch der Lasercutter. Also griff ich zu Cuttermesser, Säge und Lineal und malträtierte in Fleißarbeit Pappe, die dann zu einem Raster zusammengesteckt werden kann. Die Wände sind ca 2 cm hoch und das Ergebnis ist eigentlich schon ganz ansehnlich (weil die Frontplatte noch nicht ganz plan aufliegt, zeichnen sich nicht alle Kanten gleichmäßig ab).

LED Matrix mit Abdeckung

Natürlich gibt es Fertigungstoleranzen und perfekt ist die Lösung noch nicht. Trotzdem kann sich die Sache schon sehen lassen. Als Mattscheibe dient eine matt-weiße 0,5 mm dicke Polystyrol Platte.

Ein Problem, was sich aber jetzt herausstellte, war, daß die LEDs flimmerten und die Farben nicht schön waren. Auch schien der Sourcecode eine Macke zu haben, denn mit der Zeit wurden die Pixel immer dunkler. Einiges experimentieren und forschen im Code brachte einfach keine Erkenntnis. Schien alles richtig zu sein. Ein dicker Elko in der Spannungsversorgung brachte auch nichts.
Irgendwann fiel mir dann wieder ein, daß die Dinger ja richtig viel Strom brauchen. Mein Labornetzteil bei 2,5 A aber dicht macht. Also ein PC ATX-Netzteil genommen. Die grüne Leitung mit einem Schalter auf Masse legen, als Ein-/Ausschalter und zwei rote Leitungen (+5 V) und zwei Masse Leitungen anzapfen. Das brachte schon eine erhebliche Verbesserung. Schlagartig flimmerte nichts mehr und die Pixel behielten ihre Farben.

Weiß ist das nicht     Gleichmäßige Ausleuchtung

Nur stimmten die Farben an sich noch immer nicht. Weiß war eher rosa und auf der Fläche gab es Abstufungen. In der Mitte war es schlechter, als am Rand. Unten links ist der Pixel noch weiß und wird dann immer mehr rosa. Unten links speise ich die Spannung ein. Weil ich schon anfangs dachte, daß es nicht optimal sein kann, die ganze Spannung linear durch die Segmente bis zum letzten Element zu schleifen und der dünnen Leiterbahnen mehrere Ampere zuzumuten, hatte ich vom unteren Rand der zweiten Reihe zusätzlich zwei Drähte zur ganz rechten verlegt. Das spiegelt sich jetzt auch bei den Farben wieder: Der Pixel unten in der zweiten Reihe hat die gleiche Helligkeit und Farbe, wie der Pixel unten rechts. Die Farben der dritten Reihe und die der rechten sind identisch. Das brachte die Lösung: Auf den Streifen treten enorme Verluste auf. Es genügt nicht, Spannung an einer Stelle einzuleiten. Sie muß in jede Reihe eingespeist werden. Nachdem ich also zusätzliche Drähte einzog, leuchtete die Fläche gleichmäßig. Das ATX Netzteil quittiert die hohe Leistungsaufnahme durch entsprechendes Ansteuern des internen Lüfters, der zunehmend lauter läuft, wenn viel Fläche leuchtet. Das weiß jetzt noch einen rosa Stich hat, kann auch an der braunen Pappe liegen. Die kleinen Abweichungen einzelner Pixel bei Farbe und Helligkeit sind zu verkraften, denn einfarbige Flächen werden wohl eher nicht zu sehen sein.

Controller Super Nintendo SNES    Steuerung Platine

Für eine schöne Spielsteuerung fehlt natürlich noch der richtige Controller. Im Internet bekommt man zum Beispiel eine Steuerung für die SNES schon für weniger als € 5,-. Das ist billiger, als wenn man selber Tasten kauft und zudem hat man auch gleich ein formschönes und professionell aussehendes Gehäuse für den Microcontroller. Auf der Platine befindet sich ein vergossener Controller, der die Tastendrücke codiert über die Datenleitung sendet. Man könnte diese Signale auswerten, aber wozu? Einfach die Leiterbahnen mit 'nem Dremel auftrennen, mit einem Glasfaserpinsel den Lötstoplack an geeigneten Stellen entfernen und eigene dünne Leitungen (Kupferlackdraht) anlöten. Die beiden Schultertasten werden parallel zu den Cursortasten für links und rechts geschaltet, so daß man wählen kann , womit man lieber steuert. Die grüne Y-Taste wird zum rotieren der Bauteile etc. benutzt. Geschmackssache, wenn man eine andere Belegung bevorzugt.

Neuverkabelte Kontakte

Da der µC im Handmodul steckt, müssen nur drei Adern in der Zuleitung benutzt werden: Versorgungsspannung und die Datenleitung zum Display. Weil genügend Platz im Gehäuse ist und weil sowieso noch ein Modul bei mir rumliegt und auch noch genügend Speicherplatz im µC vorhanden ist, kommt auch noch eine Real Time Clock auf Basis des DS1302 RTC mit Stützbatterie hinein. Um während der Entwicklungszeit neue Firmwareversionen aufzuspielen, darf natürlich ein ISP Adapter nicht fehlen.

ATmega328 Modul und RTC finden Platz

Eine einfache digitale Uhrzeitanzeige wäre irgendwie langweilig. Außerdem passen keine vier Zahlen inkl. Trennzeichen nebeneinander. Gut, daß noch eine weitere Idee schon längere Zeit im Hinterkopf schlummert: Eine Berlin-Uhr ("Mengenlehrenuhr", Demo) würde genau passen. Ein wenig neuen Quellcode später, kann die Zeit angezeigt und beim Start der LED Matrix auch eingestellt werden. Damit man die Kästchen leichter abzählen kann, werden nicht leuchtende Flächen grau ausgeleuchtet. Alternativ könnte man auch Rahmen durch leuchtende Pixel um die Flächen zeichnen... Mal sehen, was besser aussieht.

Berlin-Uhr. Es ist 2x5+3 : 4x5+2 = 13:22
Ergänzend könnte man noch weitere Spiele programmieren. Snake und Conways Spiel des Lebens würden sich anbieten. Allerdings ist die Fläche in meinem Fall etwas zu schmal. Erst mit etwa 10 zusätzlichen Spalten würde es Sinn machen.
Nüchtern betrachtet, muß man sich natürlich fragen, was das ganze soll. Die LEDs ziehen bei Regenbogendarstellung der ganzen Flächhe immerhin 4,3 A. Zusammen mit den Verlusten im Netzteil sind das dann so an die 25 W. Zudem kostet das Display und alles zusammen mehr als ein Flachbildschirm, auf dem man natürlich noch viel mehr anzeigen könnte. Aber der ist dann nicht selbstgemacht...