tpm2 - Protokoll zur Matrix-/Lichtsteuerung

  • Hier im Forum gibt es ja in letzter Zeit mehrere LED-Matrizen, "Pixeltische", etc. und nun auch 3 Freewares zur Ansteuerung von sowas.


    Dabei benutzt jeder irgendwie ein eigenes Protokoll - OK, Artnet können alle drei Steuer-SWs, aber das ist schon wieder etwas komplizierter - daher kam der Gedanke auf, hier im Forum ein einfaches Protokoll zu entwickeln, um mit solcher SW einfach über USB/Seriell-Adapter Eigenbau-HW ansteuern zu können. Wunschvorstellung ist dabei, dass möglichst viele mitmachen, so dass der Anwender/Bastler vielseitig diese Steuer-SW mit jener HW kombinieren kann, ohne für jede Kombination wieder extra was programmieren zu müssen.


    Dieses Protokoll, das mehrere User zusammen auf die Beine gestellt haben (McGyver, MichuNeo, Pepe_1981, T64, turi und ich) soll nun hier vorgestellt werden. Da dies ein reiner Vorstellungsthread ist, bleibt er geschlossen - bei Fragen und Anregungen bitte PN, wird dann hier eingepflegt. Wenn es was neues gibt, wird es ebenfalls hier hinzugefügt.


    als Name wurde "tpm2" gewählt, das sind die Anfangsbuchstaben der Nicknames der Entwickler, t, p, m, je 2x - man kann das auch als "Transport Protocol (for) Matrices (generation) 2" lesen... ;)


    Ziele/Vorgaben

    • Das Protokoll sollte nicht auf eine spezielle HW oder Übertragungskanal angewiesen sein - "genormt" wird also nur, wie der Sender die Daten verschicken muss, so dass sie der Empfänger "versteht".
    • in erster Linie zur Datenübertragung gedacht, aber mit der Option, es auch für Steuerbefehle nutzen zu können
    • ausreichend für Bastler-übliche Matrixgrößen - eine Videowand mit 800x600 Pixeln muss damit nicht angesteuert werden können, da gibt es andere Möglichkeiten
    • einfach umzusetzen (die Sende- und Empfangs-SW)
    • dabei aber trotzdem recht vielseitig
    • Grundsätzlich "Fire and Forget", also der Sender muss nicht auf eine Bestätigung warten (wie bei DMX z.B. ja auch) - vorgesehen ist aber eine einfache Rückmeldung, um z.B. einen Port automatisch finden zu können, oder festzustellen, ob der Empfänger überhaupt noch "anwesend" ist
    • "Ausreichend sicher" - Es sollen ja keine Kernkraftwerke damit gesteuert werden, wenn auf einer Matrix alle 20 Minuten mal ein Pixel für einen Frame ne falsche Farbe hat, kann dies toleriert werden.


    Protokoll/Umsetzung
    Es werden Daten blockweise übertragen, also in "Frames", wie bei DMX z.B. auch - ein Frame ist z.B. ein Bild auf einer Matrix, oder eine Lichtszene o.ä.


    Die Blöcke werden - wie bei vielen solcher Protokolle - am Anfang und Ende gekennzeichnet, hier nur mit je einem Byte. Eingebettet die Nutzdaten, davor noch ein paar Steuerbytes. Es gibt keine feste Größe für einen Frame, diese wird mit übertragen. Das macht das Ganze recht flexibel, das Protokoll reicht - bei entsprechend schnellem Kanal - für eine RGB-Matrix mit 21.845 Pixeln, aber wenn man nur einen RGBW-Controller damit steuern will, dann reichen auch 9 Bytes/Frame.


    im einzelnen kommen in so einem Frame:



    Das schöne ist hier eben die variable Framegröße - dadurch gibt es keinen Overhead und immer maximal mögliche Übertragungsgeschwindigkeit. Weiterhin ist damit z.B. auch eine "automatische Adressierung" per Daisy-Chain möglich: der Sender schickt z.B. 2.048 Bytes raus, der erste Empfänger nimmt sich die ersten 512 Bytes raus, setzt die Framegröße um 512 runter und schickt den Rest weiter - usw., bis nichts mehr übrig ist.


    Unabhängig davon ist es natürlich auch hier möglich (wie bei DMX auch), dass mehrere Empfänger "parallel" (an einem Bus o.ä.) die selben Daten empfangen, und jeder sich nur die rausnimmt, die für ihn interessant sind (per Adress-Einstellung).


    Die Befehle sind zum jetzigen Zeitpunkt noch nicht genormt, ebensowenig wie mögliche Antworten darauf - denkbar z.B. Einstellungen aus der Ferne zu machen, oder Automatik-Einstellung, die Steuer-SW fragt die Matrix ab, wie groß sie ist, wie verkabelt, etc. und stellt sich dann automatisch darauf ein.


    Hier ist i.M. noch nichts implementiert, wenn solche Befehle benutzt werden (z.B. auch Sachen wie "folgende Frames auf SD-Karte speichern"), sollten sie natürlich ebenfalls einheitlich sein, damit auch hier SW von User x mit HW von User y zusammenarbeitet.


    Handshake/Flow-Control
    vorgesehen ist, dass der Empfänger nach jedem korrekt empfangenen Frame (also beim Blockende-Byte) als Antwort 0xAC ("ACknowledge) zurück sendet. So weiß der Sender, dass das Gerät empfangen hat, es ist z.B. auch möglich, dass die Sende-SW auf allen möglichen Ports einen Frame rausschickt, wo dann 0xAC zurück kommt, hängt der Empfänger dran (Pixelcontroller macht das z.B. so).


    Diese Rückmeldung soll aber keine "Pflicht" sein, der Sender soll trotzdem weiter senden, auch wenn keine Rückmeldung kommt (vermeidet Verzögerungen), und in der Sende-SW sollte der (z.B. bei USB VCP-)-Port auch manuell einstellbar sein.


    Hardware/unterliegende Schicht/Baudrate etc.
    Für dieses Protokoll sind keine speziellen HW-Voraussetzungen (Übertragungsweg, Stecker, etc.) "genormt" - Es geht wie gesagt nur um die Definition der Datenblöcke, ob diese dann über RS232, TTL, USB, RS485, Ethernet oder Funk übertragen werden, spielt dafür keine Rolle - dies bleibt jedem Anwender selbst überlassen.


    Ebenso die benutzte Baudrate, diese kann ja je nach Anforderung höchst unterschiedlich sein: Für die 128x128-Pixel-Matrix mit 30 fps sind schon eher 100 Mbit (Ethernet o.ä.) angesagt, für den 16x16-Pixel-Tisch reichen 250-500 kBaud über USB, für ne Gebäudelichtsteuerung, wo hier und da mal eine Leuchte ein- oder ausgeschaltet wird, reichen auch 2.400 Baud...


    Für die Übertragung über UDP wird noch ein Port genormt.


    Das soll erst mal zur Definition reichen, wenn ich was wichtiges vergessen habe -> PN

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    Einmal editiert, zuletzt von Pesi ()

  • Hier werden Projekte, HW und SW aufgelistet, die dieses Protokoll unterstützen - ausserdem soll hier noch Beispielcode/Routinen veröffentlicht werden für div. Plattformen (Java, Python, Processing, Ardunio, SEDU bzw. AVR allgemein), so dass man das Protokoll leicht implementieren kann, ohne selbst von Grund auf neue Routinen programmieren zu müssen.


    Steuer-Softwares (tpm2-Sender)


    "tpm2-Hardware"/Firmware (Empfänger)

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    13 Mal editiert, zuletzt von Pesi ()

  • Hier folgen oft gestellte Fragen und Antworten - Fragen bitte in diesem Thread stellen, Fragen und Antworten von allgemeinem Interesse werden dann hier eingepflegt.

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    Einmal editiert, zuletzt von Pesi ()

  • Wie im ersten Post beschrieben, ist tpm2 ja nur ein Protokoll zur Datenübertragung (speziell für LED-Anwendungen), von der unterliegenden Schicht/Hardware unabhängig.


    Das gilt bei Ethernet/Wlan/UDP nicht *ganz*, da dort ja Pakete verschickt werden, die i.A. nicht größer als 1.500 Byte Nutzdaten sein sollten (Ethernet-Framegröße). Daher ist es sinnvoll, auch die tpm2-Frames bei größeren Datenmengen auf entsprechende "Portionen" aufzuteilen.


    damit diese Portionen dann wieder richtig zusammen gesetzt werden können, werden hier also die einzelnen Pakete nummeriert. Dazu wurde bei tpm2.net ein zusätzliches "Paketnummer"-Byte direkt nach den Framesize-Bytes eingeführt.


    Zur Unterscheidung "normales tpm2" oder tpm2.net wurde ebenfalls der Startcode geändert, und zwar auf 0x9C. Ein Frame sieht also so aus:



    Und wird per UDP an den Port 65506 / 0xFFE2 verschickt. Der Port für Antworten vom Empfänger an den Sender ist 65442 / 0xFFA2


    Die Empfangsroutine kann anhand dessen (Startcode 0xC9 oder 0x9C) also unterscheiden, entweder es ist "normales tpm2", dann kommen nach den Framesize-Bytes gleich die Nutzdaten, oder es ist tpm2.net, dann folgt noch das Paketnummer- und Anzahl Pakte-Byte.


    Die Paketnummer geht in "menschlicher Zählweise" von 1 bis 255, also max. 255 Pakete á ca. 1.490 Byte = 379.950 Bytes für einen per tpm2.net verschickten Frame, das wären immerhin z.B. 126.650 RGB-LEDs.


    Die Gesamtzahl der Pakete wird auch mitgeschickt, zur Kontrolle, bzw. automatischen Aufteilung im Empfänger.


    Die Aufteilung der Pakete legt i.A. der Empfänger fest - so dass es sinnvoll ist, das kann je nach Fall unterschiedlich sein. Es sollten jedoch alle Pakete die selbe Größe haben, da es sonst deutlich aufwändiger wird, diese im Empfänger wieder zusammenzusetzen


    Z.B. man hat eine RGB-Matrix mit 32x32 = 1.024 Pixel / 3.072 Bytes - das kann man dann z.B. in 3 Pakete á 1.024 Bytes aufteilen...


    Baut man eine größere Matrix aus Modulen auf, kann es z.B. auch sinnvoll sein, Module mit 16x16 = 256 RGB-Pixel zu bauen, und dann pro Modul ein Paket mit 768 Bytes zu schicken.


    Die Sende-SW muss dann die Pakete so zusammenstellen, wie der Empfänger das haben will - meist hat man dort ja sowieso eine Möglichkeit, das einzustellen bzw. die Pixel zu patchen (in Glediator z.B. ab Version 1.1 über ein GUI, In Jinx! ebenfalls).


    Eine zeitliche Nummerierung ist nicht vorgesehen, es wird davon ausgegangen, dass tpm2.net nur in kleinen Netzen ohne Router o.ä. verwendet wird, die Pakete also in der Reihenfolge ankommen, in der sie losgeschickt wurden.

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    Einmal editiert, zuletzt von Pesi ()

  • Es wird ja schon eine ganze Weile mit den Protokollen TPM2 / TPM2.Net gearbeitet und schon einiges an Hardware unterstützt TPM2.


    Was bisher leider noch gefehlt hat ist eine offizielle Protokoll-Spezifikation.


    Wenn es um die reine Nutzdatenübertragung geht benötigt man die eigentlich auch nicht. Da TPM2 aber u.a. dafür konzipiert wurde mehr leisten zu können bedarf es da schon noch einiges an Spezifikation. Diese haben einige Mitglieder hier im Forum (u.a. Pesi und meine Wenigkeit) lange "ausgeknobelt".


    Anbei nun die daraus resultierten finalen SPECs des TPM2-Protokolls mit der Bitte sich an diese Specs zu halten wenn man Software / Hardware entwickelt die sich "TPM2-kompatibel" nennt.


    Pesi: Kannst Du das PDF oder den Link auf diesen Beitrag oder auch den Beitrag selbst in den Eigentlichen TPM2-Thread kopieren / verschieben. Der ist "closed" sodass ich hier was neues aufmachen musste.


    Wer sich aus den Specs eine .h-Datei für ein Projekt machen möchte dem hänge ich hier mal meine Version an, das spart sicher einiges an Zeit beim definieren der ganzen Konstanten.



    Die Formatierung ist natürlich (mal wieder) vollkommen "anders" wenn man sie hier im Post als Code einfügt ...


    LG,


    Pepe


    TPM2_Specs_V1.0_2013_ger.pdf