1D-Pong

Kontakt: Pixtxa Vorschau-Bild

Projektstatus: abgeschlossen , Erweiterungen: wait

Direktweg zur Spielanleitung

Vorgeschichte

Ich bekam 44x WERMA MC35 UL Leuchte + Summer 10-30V RGB M12 und überlegte, was man damit tun könnte.

Die Werma-LED-Leuchten stehen wabenförmig angeordnet auf dem Tisch Die Werma-LED-Leuchten stehen in einem Dreieck angeordnet auf dem Tisch Die Werma-LED-Leuchten stehen in einer Linie aufgereiht auf dem Tisch

Schnell war klar, dass sie aufgereiht irgendwie toll aussehen und es ein Spiel werden soll. Einen TWANG32-Hack habe ich schon gebaut, aber 1D-Pong fehlt mir noch.

Was erstmal einfach erschien, bot dann doch mehrere Side-Quests, wodurch das Projekt umfangreicher wurde, als erwartet.

Wenn es dich nicht antreibt
Und nicht an deinen Nerven sägt
Wenn es dich nicht aufreibt
Und deinen Glauben zerschlägt
Es wird dich zernagen
Denn wenn es dich nicht weckt
Kannst Du es noch ertragen
Dann ist es nicht das Projekt
paniq, Zum Projekt

Ergebnis ist aber, dass es doch noch fertig wurde und schön geworden ist. Wie das ging, wird hier erklärt.

Umsetzung

Planung

Die LED-Leuchten können nicht nur als Anzeige genutzt werden, sondern haben einen eingebauten Summer. Dieser kann mit kurzen Impulsen versorgt werden, um genau dort zu piepen, wo gerade etwas passiert. Ein eindimensionales Spiel bedeutet schließlich nicht, dass es mit nur Mono-Tonausgabe auskommen muss.

Als Tasten wurden transparente Adafruit-Arcade-Buttons mit LED gewählt.

Mit OpenSCAD habe ich ein parametrisches CAD-Modell erstellt, um virtuell durch Anpassen der Parameter ausprobieren zu können, welche Abstände zu welcher Größe führen und wie es dann aussähe. Die Wahl fiel auf einen Pixelabstand von 40 mm (≈ 0.635 dpi) und einen Kabelkanal mit 60 mm x 40 mm, welcher auf 1845 mm gekürzt wird.

3D-Ansicht vom Projekt

Gehäuseanpassung

Einzelne Werma-LED-Leuchte liegen auf dem Tisch 2D-Ansicht des nötigen Montage-Lochs

Die LED-Leuchten haben ein Gehäuse mit abgeflachten Seiten, welches sich im passenden Loch nicht verdrehen lässt. Um diese Löcher in gleichmäßigen Abständen den Kabelkanal zu bekommen, kann man ihn einfach in eine CNC-Fräse einspannen und die Löcher fräsen. Die X-Carve CNC Fräse ist zwar toll, aber für 2 m lange Werkstücke dann doch nicht so gut geeignet. Man könnte mehrfach umspannen, aber das ist schwierig auszurichten.

Ausdrucken, Aufkleben, grob Bohren und auf Maß feilen geht recht gut. Aber 44x mal möchte man das doch nicht unbedingt tun.

Mit einer kleinen Handfräsmaschine geht es schneller, da braucht man aber eine ruhige Hand.

Es war also Zeit, neue Wege auszuprobieren. Ein Robo-Arm mit starkem Laser und „nicht hin gucken während der Laser an ist“ als Sicherheitskonzept klingt erstmal interessant, aber Kabelkanal ist aus PVC und sollte nicht thermisch bearbeitet werden (Salzsäure und giftige Gase)

Aber das 3D-Modell der Planung konnte schnell ein CAD-Modell einer Schablone ausgeben, welches frisch gesliced an den 3D Drucker - Prusa i3 MK3s ging, während ich einen Spaziergang in den Baumarkt machte, um den Kabelkanal zu kaufen.

Ansicht vom 3D-Modell der Schablone. Sie hat 5 Löcher für die LED-Leuchten und eins für die Arcade-Tasten

Side-Quest: Endkappen

Ich hatte erwartet, dass es im Baumarkt auch Endkappen für die Kabelkanäle gibt; leider war das nicht der Fall. Da der Drucker noch druckte, als ich zurück kam, suchte ich online nach 3D-Modellen, um dem Drucker schonmal den nächsten Druckauftrag vorzubereiten. Auch dort fand ich keine passenden 3D-Modelle, also erstellte ich selbst eins. Oder besser gesagt, zwei, denn das 3D-Modell zeigte eine Kollision mit dem Arcade-Button, weshalb noch eine Version mit Aussparung geschaffen wurde. Die beiden 3D-Modelle incl. CAD-Script sind hier zu finden: 60x40 Kabelkanal-Endkappe

Zurück zu den Montagelöchern

3D Druck entnommen, neuen Druck gestartet und die Schablone klemmte perfekt im Deckel des Kabel-Kanals.

Die Schablone liegt neben dem Kabelkanal auf dem Tisch Die Schablone klemmt im Deckel vom Kabelkanal

Die Schablone lässt sich also nur mit etwas Kraft verschieben und auch nur in einer Richtung, während die anderen beiden Richtungen fest sind. Die Löcher wurden entsprechend leicht größer designt, sodass man sie mit einem Bündigfräser am Frästisch für Triton TRA001 einfach abformen konnte.

Bearbeitung des Kabelkanals. Erstens: Vier Löcher bohren mit Akkubohrmaschine und Stufenbohrer. Zweitens: Löcher von anderer Seite aufbohren. Drittens: Löcher mit Oberfräse ausfräsen. Viertens: Schablone weiter schieben und am 5. Loch ausrichten, um weitere vier Löcher machen zu können.

Bis alle Löcher gemacht waren, war die erste Endkappe gedruckt. Die zweite wurde während der Montage der LED-Leuchten gedruckt. Durch Fertigungstoleranzen wurde der Kabelkanal ca. 0,1 % (≈ 2 mm) länger als geplant, zusammen mit den 1,5 mm starken Endkappen ergibt sich somit eine Länge von 1850 mm.

Kabelkanal mit Endkappe und Löchern im Deckel Kabelkanal mit montierten LED-Leuchten und Arcade-Tasten

Side-Quest: Arcade Buttons

Irgendwie ist es doch unschön, wenn die LED-Leuchten sieben Farben anzeigen können, während die Tasten nur weiß leuchten können. Praktischerweise gibt es eine Anleitung zum Bau von NeoPixel Arcade Buttons, mit fertigen 3D-Modellen. Allerdings wurden sie für die transparenten Adafruit-Arcade-Buttons ohne LED entworfen und passen nicht gut in die anderen. Vielleicht ist das der Grund, warum die Variante mit LED nur etwa halb so viel kostet wie die ohne LED. Habe es dennoch gedruckt, vielleicht passt es ja trotzdem. Das Oberteil passte gar nicht und wurde neu erstellt, danach passte aber die Gesamthöhe nicht. Hätte man gleich im CAD berücksichtigen können, ein paar Unterlagscheiben lösten das Problem erstmal für weitere Tests. Das Unterteil mit der LED-Aufnahme passte zwar halbwegs, wackelte aber ordentlich herum, da ein Nubsel zur Fixierung im Stem des Schaltmoduls fehlte. Der Nubsel wurde zum CAD-Modell hinzugefügt und dabei auch die nötige Verlängerung mit angebracht, damit die Gesamthöhe passt. Dass die Höhenanpassung auf der Seite erfolgte, bietet zudem etwas mehr Platz für die Anschlussleitungen. Einen Ausdruck später passte die Höhe ohne Unterlagscheibe und es wackelte nicht mehr, also wurde die zweite Taste genauso umgerüstet. Trotzdem fühlten sich die Tasten irgendwie tot an und boten kein tolles Gefühl, da der Schaltpunkt nicht spürbar war. Also yeetete ich die Alps SKCL Cream Switches (linear) und setzte stattdessen auf Alps SKCM White Switches (clicky), welche den Tasten ein sehr erfüllendes Schaltgefühl verpassen. Die eingesetzten RGBW-LEDs können bunt leuchten, bieten aber zudem ein hübsches, echtes Weiß, welches nicht aus RGB gemischt wird. Die 3D-Modelle sind hier zu finden: Cheaper NeoPixel Arcade Buttons

Animation: Taste wechselt Farbe, so lange sie gedrückt wird

Die Ansteuerung für den Test erfolgte erstmal nur per Card10, einer Art Armbanduhr. Ein paar Zeilen für die MicroPython-Kommandozeile reichen hierfür.

Verbindung des Arcade-Buttons mit der Armbanduhr

import color, time, ws2812, gpio gpio.set_mode(gpio.WRISTBAND_1, gpio.mode.INPUT | gpio.mode.PULL_UP) gpio.set_mode(gpio.WRISTBAND_2, gpio.mode.OUTPUT) i = 0 while True: state = gpio.read(gpio.WRISTBAND_1) col1 = color.from_hsv(i % 360, 1.0, 0.1) col2 = color.from_hsv((i + 20) % 360, 1.0, 0.1) col3 = color.from_hsv((i + 40) % 360, 1.0, 0.1) ws2812.set_all(gpio.WRISTBAND_2, [col1, col2, col3]) if state == 1: i += 1 else: i += 20 time.sleep_ms(10)

Beacon-Ansteuerung

Die LED-Leuchten wollen jeweils mit 4x 10-30 V angesprochen werden, also werden 176 Ausgänge benötigt. Matrix-Schaltung geht nicht wirklich, da sonst die Helligkeit abnimmt, was ich nicht möchte.

Werma-Pinbelegung

Die Versorgung erfolgt über einen M12-Stecker, dessen Ausrichtung im Gehäuse von Leuchte zu Leuchte variiert, eine Leiterplatte mit aufgelöteten M12-Buchsen scheidet also aus. 44 M12-Buchsen mit Leitung als Gegenstück sind sehr teuer und passen vor allem nicht in den Kabelkanal. Allerdings habe ich hier auch nicht so harte Anforderungen wie in der Industrie und kann sie einfach direkt anlöten und ohne Dichtung offen lassen. Mit Einzel-Leitungen könnte es schwierig werden, den Kabelkanal zu schließen, ohne was einzuklemmen. Flachband-Leitung ist gebündelt ohne doppelt isoliert zu sein und lässt sich daher einfach abisolieren, ist nicht so störrisch und es bleibt dennoch halbwegs ordentlich.

Ich wurde auf den Baustein TPIC6C596 aufmerksam, welcher ein 8-Bit Schiebe-Register mit Latch-Register und Open-Drain-Ausgängen bietet. Open Drain heißt hier, dass die ICs den Minuspol schalten. Da die LED-Leuchten mit Pluspol als COM betrieben werden dürfen, passt das. Laut Datenblatt brauchen die LED-Leuchten 10-30 V und max. 45 mA, während die Schaltausgänge jeweils bis zu 33 V und mehr als den doppelten Strom schalten können, welcher sich zudem sogar auf mehrere Kanäle verteilen kann. Das IC passt also, aber leider fand ich keine passenden Breakout-Boards. Die einzig gefundenen haben Vorwiderstände für LEDs drauf, was für die LED-Leuchten mit eingebauter Elektronik nicht sinnvoll ist. ICs lassen sich mit den 1,27 mm Rastermaß immerhin halbwegs gut an Flachband-Leitung mit ebenfalls 1,27 mm Rastermaß löten. Aber das Pinout macht es nicht so einfach verwendbar und dass da was abreißt, bevor der Kabelkanal zu ist, ist sehr wahrscheinlich. Bei der topmodellfabrik kündigte sich eine Bestellung bei JLC-PCB an, bei der ich mich anschließen durfte, was die ideale Gelegenheit bot, noch etwas CAD in dieses Projekt zu bringen.

Side-Quest: PCB-Design

Ansicht der Leiterplatten Ober- sowie Unterseite Die Anforderungen waren schnell klar:

Alle 4 cm einen Abgriff für eine LED-Leuchte

COM sowie Rot, Grün, Blau und Sound (= 1 Nibble)

Im Falle einer Flex-Leiterplatte können die Leitungen zum an die Beacons Löten direkt dran sein

Als Backup/ansonsten Ausgeführt als 1,27 mm SMD zum Flachbandleitungen anlöten

Zusätzlich ausgeführt als 2,54 mm THT, falls SMD-Löten von Flachbandleitungen doch zu kompliziert ist

Aufteilung auf mehrere, aneinanderreihbare Leiterplatten

Sonst werden Leiterplatte und Versand teuer, das Handling wird schwierig und JLC-PCB liefert eh erst ab 5 Stück

Neopixel-LEDs mit auf der Leiterplatte

Der Space hat sie rollenweise bekommen

Dienen als Signal-Repeater, um die Neopixel-LED in der hinteren Taste sauber zu erreichen

Können ggf. als Debug-Output verwendet werden

Fancy Bau-Bilder

Auch für andere Projekte geeignet

Ein IC je Leiterplatte

Kompaktes Haupt-Design

Abgriff mit allen acht Ausgängen

Alle 8 cm möglich, für die (WERMA-)Produkte mit 70 mm Durchmesser

2. Neopixel in dem Fall nicht nötig; Datenleitung überbrückbar

Rest abschneidbar um Platz zu sparen

Pull-Up/-Down für nicht zwingend benötigte Anschlüsse

GND-Ausgang für Dauer-An um z. B. eSIGN oder Transceiver versorgen zu können

Einfach und universell einsetzbar

Pfeile für Richtung des Datenflusses

Beschriftung aller Anschlüsse

Bei THT doppelseitig

Beschriftung der wichtigsten IC-Merkmale

Open Source Hardware

Beschränkung auf Footprints und andere Quelldaten mit passenden Lizenzen

Notfalls selbst erstellen

OSH-Logo und Link zum Repository mit drauf

Ein paar Abende/Nächte CAD-Arbeit später war das Design fertig und wurde zusammen mit den Bauteilen bestellt. Ein paar Tage später konnten die Leiterplatten bestückt werden.

Verdrahtung

Das Konzept der Kontaktierung wurde nochmal geändert. Anstatt Flachbandleitung an die M12-Stecker der LED-Leuchten anzulöten, lassen sich auch Jumper-Leitungen verwenden. Die 5 Pins passen perfekt in die 5-pin M12-Stecker und sind kompakt genug, dass es noch in den Kabelkanal passt, während sich an der anderen Seite nichts ändert und die Flachbandleitung direkt an die Leiterplatte gelötet werden kann. Zur Zugentlastung wurden die Leitungen mit einem Tropfen Sekundenkleber gesichert. Da im Space Zweifel aufkamen, bestätigte ein Test, dass das gut genug hält.

Abgerissene Leitungsummantelung klebt an der Leiterplatte

Die Leiterplatten wurden Nutzenweise bestückt, geteilt, mit Jumper-Leitungen versehen und aneinandergereiht. Ein Controller mit WLED lässt die RGB-LEDs bereits schön bunt aufleuchten.

Leiterplaten in verschieden weit montierten Zuständen Alle 22 Leiterplatten aneinandergereiht mit Regenbogen-Animation

Anschließend wurden die LED-Leuchten verbunden und der Aufbau testweise in den Kabelkanal gepackt. Die Annahme, Flachbandleitungen seien nicht störrisch, hatte nicht berücksichtigt, dass diese 5-adrigen Leitungen 44x vorkommen und somit eher einer 220-Adrigen Flachbandleitung entsprechen. Aber mit Geduld und Gewalt (vom einen mehr als von anderen) ging es. Eine kleine Test-Firmware wurde auch geschrieben.

Mit den LED-Leuchten verbundene Leiterplatten LED-Leuchten in Betrieb, Aufbau weiterhin offen auf dem Tisch Aufbau geschlossen, Seitenansicht ins Innere des Kabelkanals

nyanyanyanyanyanyanya

Der Controller bekam noch eine kleine Adapter-Leiterplatte und anschließend konnte der Aufbau komplett geschlossen werden. Durch die Endkappen und den Kabelkanal wurden kleine Löcher gemacht und Einzelpins abgewinkelter Stiftleisten hindurch gesteckt, welche vom Deckel in Position gehalten werden. Den Aufbau zu zu bekommen, ohne den Controller einzuklemmen, ist leider nicht so einfach, aber üblicherweise macht man das Ding nicht auf.

Ansicht der Controller-Leiterplatte Fertig aufgebaute Hardware

Side-Quest: Glitches beseitigen

Teilweise piepten manche/alle Summer, Leuchtelemente fielen aus und die Farbwiedergabe der Neopixel änderte sich abhängig davon, wie viele an waren. Der Plan, die Leiterplatten direkt zusammen zu löten, um nur halb so viele Lötstellen machen zu müssen, hatte nicht funktioniert, da die Lötstellen beim Bewegen der Konstruktion doch teils belastet wurden und brachen. Es wurden daher alle Lötstellen zwischen den Leiterplatten nochmal überarbeitet und mit auf beiden Seiten angelöteten Stiftleisten versehen.

Üblicherweise packt der Controller die Daten über Push/Pull Ausgänge in die Eingänge der Schieberegister. Beim Start/Firmware-Upgrade sind diese IOs jedoch Eingänge und somit hochohmig, wodurch die Schieberegister Rauschen empfangen und ausgeben. Der nOE-Eingang um die Ausgänge zu (de-)aktivieren wurde daher an den Controller angeschlossen und mit einem Pull-Up Widerstand versehen, damit beim Start/Firmware-Update alle OpenDrain-Ausgänge deaktiviert sind.

Es wurden zusätzliche Versorgungs-Leitungen verbaut, da die Leiterbahnen nicht ausreichten und es zu einem zu großen Spannungsausfall kam.

Danach stellte sich heraus, dass die Schieberegister nicht mehr gingen. Im Datenblatt steht, dass der HIGH-Pegel für „≥ 0,85 Vcc“ gilt; leider wurde das „cc“ übersehen und daher auf einen Levelshifter verzichtet. HIGH gilt also nicht ab 0,85 V, sondern bei 5 V Betriebsspannung ab 4,25 V. Die Betriebsspannung für die Schieberegister sowie Neopixel wurde per Trimmer am StepDown-Wandler von 5,3 V auf 4,5 V verringert und durch Bauteiltoleranzen funktioniert es damit zum Glück trotzdem.

Firmware

Erstmal konnte vieles von 1D-Pong verwendet werden, es mussten nur die Farben und Ausgabe-Routine angepasst werden.

Sidequest: Extra-Features

Es wurde letztlich alles nochmal umstrukturiert, da viele while-Schleifen und delays zum Einsatz kamen, was die WLAN-Funktionen sehr erschwerte bzw. unmöglich machte.

Im Original-Code wird einfach nur ein zufälliger Start-Spieler gewählt, eine Idle-Animation existierte nicht. In meiner Version fängt die Seite an, welche Idle-Animation unterbricht – außer der Knopf der Gegenseite wird noch innerhalb der Transition zwischen Idle-Animation und Spiel-Start betätigt.

Vorzeitig verlassene Spiele können abgebrochen werden, indem man beide Tasten gedrückt hält, bis alles weiß leuchtet. Wird keine Taste gedrückt, erscheint nach einigen Sekunden die Idle-Animation. Auch diese hat einen Zeitpunkt, bei dem alles weiß leuchtet; lässt man sie bis dort hin laufen, wird ein evtl. begonnenes Spiel ebenfalls beendet.

Zudem gibt es eine (deaktivierbare) Soundausgabe und eine Möglichkeit, die Rundenzahl zu konfigurieren.

Da das Schließen des Kabelkanals etwas kompliziert ist, wurde auch noch die Möglichkeit für FOTA-Updates implementiert. Die LED-Leuchten zeigen in dem Fall den Fortschrittsbalken der Übertragung an.

Geplant ist noch eine einfache Weboberfläche. Darüber sollen neben Soundausgabe und Rundenzahl auch die verwendeten Farben konfigurierbar sein. Statistiken wie Anzahl gespielter/abgebrochener Spiele, insgesamt erzielter Punkte, Anzahl erfolgreicher/verfehlter Schläge und ähnliches könnten da auch (per API) ausgegeben werden.

Mehr „Spielmodi“ sind auch geplant:

Bis x Punkte (Bereits implementiert, einzig verfügbarer)

Bis x Punkte bei y Punkten Mindestabstand; oder bis der Punktezähler voll ist

Gewinner von x Runden (Extra-Runde bei Gleichstand)

Evtl. etwas mit unausgewogenen Schlägergrößen und Boosts; sich bewegenden Schlägern, …

Schlagt mir gerne Ideen vor

Vorschläge für weitere Idle-Animationen werden auch angenommen; sie müssen jedoch mit den sieben Zuständen Rot, Orange, Grün, Cyan, Blau, Violett und Weiß auskommen.

Der Code ist hier veröffentlicht: 1D-Pong Quellcode

Ergebnis

1D-Pong Spiel in Betrieb. Beim Zurückschlagen des Balls ertönt ein kurzes Piepen, beim Verfehlen piept es 3x während der neue Punktestand aufblinkt

Side-Quest: Dokumentation

Beim Bau wurden viele Bilder gemacht, die gesammelt und nun in diese Dokumentation gepackt wurden.

Wenn man das Spiel irgendwo aufbaut, gibt es immer interessierte, die das sehen wollen. Ein Link zu dieser Wiki-Seite ist aber sehr lang und macht QR-Codes entsprechend groß. Um eine eigene, (für mich) einfach zu merkende Kurz-Url zu haben, kümmerte ich endlich darum, wie ich einen Webserver auf meinen Cloud-Computer bekomme und mit meiner Domain verknüpfe, um die Domain endlich mal sinnvoll zu nutzen und auch Pixtxa.de/1D-Pong anbieten zu können.

Spielanleitung

Taste drücken zum Start/Aufschlag

Zurückspielen durch Tastendruck während sich der Ball im grünen Schläger-Bereich befindet

Verfehlen = Punkt für Gegenseite

Punktanzeige in Spielfeldmitte

Spiel gewinnen: Als erstes die zu erreichenden Punkte erzielen

Default-Wert nach Powercycle: 5 Punkte

Konfigurationsbereich: 1-16 Punkte

Hinweis: Boost am Schläger-Ende verfügbar

Reset: Tasten halten/warten bis alles weiß leuchtet

Installationsanleitung

Das Spiel benötigt eine Grundfläche von 185 cm x 6 cm; etwas mehr Platz ist empfehlenswert, damit es etwas verrutschen kann. Die meisten Tische oder Biertische bieten sich gut als Unterlage an. Die Kombination aus Brüstungsgeländer und Kabelbinder kann auch gut funktionieren. Das Spiel selbst ist in jeder Ausrichtung betreibbar; jedoch sollte beachtet werden, dass (idealerweise unabhängig der Körpergröße) die Tasten gut erreichbar und die LED-Leuchten zum Spielen auf ganzer Strecke gut einsehbar sein sollten. Letzteres am Besten auch für Publikum.

Auch wenn die Werma-Beacons IP69k bieten, gilt das leider nicht für die verwendeten Arcade-Buttons, welche nicht mal Regenfest sind. Je nach Wetterlage sollte also ein überdachter Bereich als Aufstellort verwendet werden.

Die Spannungsversorgung von 24V/1A erfolgt über eine Hohlbuchse (innen Plus); ein passendes Steckernetzteil mit Eurostecker liegt bei. Zur Inbetriebnahme muss lediglich die Spannungsversorgung hergestellt werden. Zum Ausschalten kann sie jederzeit getrennt werden; ein herunterfahren ist nicht erforderlich.

Zur Konfiguration können beide Tasten gedrückt gehalten werden. Erst wird alles weiß und das aktuelle Spiel beendet; etwas verzögert erscheint die Konfigurationsanzeige. Dabei zählt der Punktestand für beide Teams von 1 beginnend an alle 300 ms hoch. Beim Überlauf wird die Sound-Ausgabe umgeschaltet (aus/an) und es wird erneut hochgezählt. Beim loslassen wird die Konfiguration übernommen. Hält man also die Tasten, bis beide Teams 5 Punkte haben und lässt dann los, laufen fortan die Spiele so lange, bis eine Seite 10 Punkte erzielt. Beim Powercycle wird wieder die Standard-Konfiguration geladen: Mit Sound-Ausgabe bis 5 Punkte.

Vom Öffnen des Kabelkanals ist abzusehen, da sich das Controllerboard beim Schließen des Kabelkanals gerne verklemmt. Auf der Unterseite sind Löcher, durch die man rein schauen kann; zudem gibt es unter Pixtxa.de/1D-Pong die Projektdoku zu finden.