Jinx! mit 14400 Pixeln

  • Hallo in die Runde,


    ich arbeite an einer Installation mit 14400 LED Pixeln (Matrix mit 12 x 1200 RGB LEDs). Ich baue dafür einen eigenen Controller mit einem Teensy 4.1, der die 14400 Pixel = 43200 Kanäle ansteuern kann (20 Kanäle Datenleitungen mit je 720 Pixeln). Mit Artnet läuft das erstmal auf dieser Seite.


    Über Artnet sind das ja nun 85 Universen und ich müsste dementsprechend 85 devices anlegen und alles patchen. Auch mit dem Fast-Patch dann noch sehr viel Arbeit. Oder ist das irgendwie einfacher möglich und übersehe ich da etwas?


    Oder ist da gleich der bessere Weg, ein anderes Protokoll zu nehmen? tpm2.net ? Oder was anderes?

    Für tmp2.net kann ich keine library für Teensy/Ethernet finden. Ich weiß nicht, ob ich das hin bekomme.

  • Vorab: Bist Du wegen der Größe sicher, oder ist das ein Vertipper...? - ich kann in Jinx! maximal 480 Pixel in einer Dimension anlegen, also 12x1200 geht bei mir nicht...


    Mich hat das interessiert, also ob Sven das richtig implementiert hat mit dem tpm2net - hat er! :)


    Also von dem her ginge es, nur ein Output Device anlegen mit 43.200 Channels, z.B. auf 36 Blocks verteilt á 1.200 Byte, dann passt das gut in einen normalen Ethernet-Frame. Und dann einfach per "fast patch" alle Pixel in einem Rutsch patchen... ich hab' das mal mit 120 x 120 ausprobiert, und im Wireshark nachgeguckt: Jinx! teilt die Daten dann automatisch auf 36 Blöcke auf und zählt den Index hoch...


    Ich kenn' mich mit Teensy nicht aus, programmiert man da in C...? - landet jeder empfangene Ethernet-Frame in einem Buffer...?


    selbst habe ich früher Byte für Byte (bei "normalem" tpm2) empfangen und in Assembler ausgewertet, inzwischen habe ich auch eine tpm2.net-Empfangsroutine für Arduino/ESP8266 - die funktioniert im Prinzip so:


    Ein Frame wurde empfangen und liegt im Buffer - dann parse ich den:


    - ist das erste Byte 0x9C (Startbyte) und das zweite 0xDA (Frametyp: Daten)? - wenn nicht, Frame verwerfen
    - Ansonsten Byte 3 (Hi-Byte) und 4 (Low-Byte) raus ziehen, daraus die Nutzdatenmenge errechnen
    - Dann an der entsprechenden Stelle (Nutzdatenmenge+6) nachschauen, ob da das Blockende-Byte 0x36 steht - wenn nicht, Frame verwerfen
    - Ansonsten ist der Frame gültig, Byte 7-n weiter verarbeiten.

    Das ist jetzt die simple Version, ohne Aufteilung auf mehrere Blöcke. Die brauchst Du aber, also musst Du noch nachschauen:
    - Byte 4: Paket (Block)nummer
    - Byte 5: Gesamtzahl der Pakete (Blöcke)


    und dann halt die Daten an die entsprechende Stelle (ausrechnen anhand Blocknummer und Framegröße) in deinem Arbeitspuffer schreiben. Das wäre die Luxus/ordentlich-Variante, die für (fast, die Blöcke müssen alle gleich groß sein) beliebige Werte funktioniert...

    Was Du bei Dir vereinfachen kannst, wenn der Teensy fest ne Matrix mit 14.400 Pixeln bedienen soll, und die Aufteilung immer 36 Blöcke á 1.200 Byte ist:

    - 9C, DA, Framegröße und Blockende-Byte gar nicht auswerten. Es schickt ja nur Jinx! auf den Teensy (davon gehe ich mal aus...), also muss das ein tpm2.net-Frame sein, und der wird schon passen (wenn nicht, flackert's/ruckelt's so und so...)
    - nur die Block-Nummer auswerten, und die Bytes dann an die entsprechende Stelle in den Zwischenpuffer kopieren. Also Block 1 ist Byte 1 bis 1.200, Block 2 ist 1.201 bis 2.400, usw.
    - Wenn Du Block 36 empfangen hast, ist das Bild komplett, ausgeben an die Matrix.


    weiß nicht, ob Du das so auf Teensy umsetzen kannst...? - ich kann den Arduino-Code auch rein stellen bei Bedarf, aber der ist wie gesagt ohne Auswertung der Block-Nummer... das sollte aber noch easy rein zu machen sein...

    mehr Infos auch auf http://www.tpm2.de

    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!

  • Vielen Dank für die ausführliche Antwort!


    Physikalisch sind es 12x1200 Pixel auf der Matrix. In der Jinx-Software muss ich das in den Grenzen der 480 Pixel anders abbilden.


    Den Teensy kann ich per Arduino-IDE programmieren in C/C++ und nutze im Moment eine Artnet library, die das nötige für mich macht.


    Das wäre natürlich eine sehr komfortable Lösung mit TPM2.NET und dem super einfachen Patchen und nur ein device anlegen in Jinx!. Den Angaben zu Startbyte usw. kann ich soweit folgen. Mit Ethernet habe ich ansonsten noch nicht gearbeitet und da keine Erfahrung. Ich habe jetzt mal getestet, UDP Pakete zu empfangen. Da kommt auch was an. Allerdings kann ich nach den ersten 6 bytes nur 6x3 bytes Daten sehen, obwohl mir eine größere und korrekte packet size von z.B. 108 angegeben wird. Der packetbuffer ist aber kleiner. Wenn ich Channel/Block auf 3 setze und 35 Blöcke erwartet werden, werden mir nur 1-4 angezeigt. Ich weiß nicht, ob ich das nur nicht richtig anzeigen lasse oder im Serial Monitor nicht korrekt erscheint oder auf was die packet size begrenzt ist ... muss ich mir weiter anschauen und ist vermutlich eine Software-Sache auf Empfänger-Seite im Teensy.


    Ich nutze diesen Code bzw. mit der NativeEthernet library den gleichen und schreibe mir die einzelnen Elemente aus dem packetbuffer auf den seriellen Monitor.


    Nachtrag: Port setze ich natürlich auf 65506 für tpm2.net.

    Nachtrag2: Es scheint, dass aus dem packetbuffer nur maximal 24 bytes angezeigt werden, auch wenn ich von woanders was sende.


    Mit

    Code
    #define UDP_TX_PACKET_MAX_SIZE 50000

    kann ich die Grenze für den Puffer (warum TX und nicht RX?) einfach hoch setzen. Der Teensy 4.1 hat reichlich RAM. Alles als ein Block übertragen mit den 43200 Kanälen scheint aber nicht zu klappen. Da wird mir gar nichts angezeigt. Mit kleineren Blöcken habe ich wieder das Problem, dass nur die ersten 4 durch kommen. Werde ich mir weiter ansehen, warum das begrenzt ist und nochmal genauer testen. Erstmal ganz viel versprechend.


    Im Code war noch ein Delay ... entfernt ... jetzt kann ich 86 Blöcke mit 505 channels empfangen (packet size = 512). Das wäre ja so schon nutzbar und ist ein riesiger Erfolg für mich. Ich hoffe, dass ich diese Datenmenge dann auch schnell genug auf die LEDs sortieren kann und der ganze Rest noch läuft.

  • Sehr interessant Dein Projekt!

    Es wäre schön, wenn Du das Resultat und vielleicht Deinen Code dann vorstellen könntest.

    Ich bin zur Zeit eher auf der ESP32-Schiene mit Wled unterwegs - das hat jetzt mit V 0.14 auch wieder einen großen Sprung gemacht und ist nicht nur wegen der vielen einfach erhältlichen ESP32-Versionen (mit Ethernet, SD etc.) doch recht attraktiv und kommt einer eierlegenden Wollmichsau schon recht nahe. Ich möchte aber demnächst doch auch mal einen Teensy ausprobieren...

  • Im Prinzip läuft die Sache:

    Ich kann die tpm2.net Daten aus Jinx! empfangen und ausgeben. Um 1024 channels/block kommen die Daten interessanterweise am schnellsten durch (dauert ca. 3,5ms). Kürzere oder längere packets machen es langsamer. Es ist da aber so oder so reichlich Luft. Ich habe das nur stichprobenartig mal mit angeschaut.


    Ich finde das eine sehr schöne Selbstbau-Lösung mit dem Teensy. Es sind bis 42 Pins möglich beim Teensy 4.1. Bei 30 fps wären das 1100 LEDs pro Pin = 46200 LEDs insgesamt. Da sind meine 14400 ja bescheiden.


    Jetzt habe ich noch Arbeit, die Daten korrekt auf die LEDs zu mappen. Die Reihenfolge der Pins kann nicht (oder nicht für alle) verändert werden, wie ich jetzt erst gemerkt habe. Dann auf die physikalische Anordnung bringen. Das ist alles lösbar.

    Damit Jinx! 1024 channels sendet, muss ich dort übrigens 1023 einstellen... hat mich ne Zeit gekostet, das zu checken.


    Mit einem Klick alle LEDs zu patchen ist schon sehr, sehr angenehm und macht das extrem flexibel für zukünftige Änderungen.

    Da ich am Ende 10 "Module" von 2m x 20cm baue mit je 120 x 12pixel und zwei Datenleitungen (je 720 pixel) werde ich vielleicht diese zusammenfassen und doch in Jinx patchen, mal sehen.


    Die Kabelverbindungen mit den CAT6 Kabeln sind wie erhofft sehr komfortabel und flexibel. Am Ende splitte ich die 4 Datenleitungen pro Kabel auf 2 auf mit einem steckbaren Splitter. Dann laufen die zwei Leitungen jeweils parallel in dem anderen Kabel. Auch bei 10m kein Problem. 30m Gesamtlänge waren im Test auch kein Problem. Ich benötige nur 10+2m. Vielleicht würden die letzten 2m auch ungeschirmt gehen, aber so ist es auch nochmal etwas robuster beim Verlegen.


    Den Code kann ich gerne zur Verfügung stellen.

  • Ja, stell' den Code doch mal rein, ist bestimmt interessant.

    Bei Ethernet ist es so, dass ein Datenframe (außer Du benutzt "Jumbo Frames", das muss der Switch aber können) max. ca. 1400irgendwas Bytes Nutzdaten übertragen kann. Ansonsten wird das Paket fragmentiert, das muss dann auch wieder Netzwerkkarte, Switch und Empfänger können...


    Deswegen klar: (Zitat) "Alles als ein Block übertragen mit den 43200 Kanälen scheint aber nicht zu klappen." - so ein Riesenframe geht bestimmt nicht durch... ;) - dafür gibt es eben diese Aufteilung auf mehrere Blocks, damit die Frames klein genug bleiben. Jinx! ist hier sehr komfortabel, mit der automatischen Aufteilung und patchen über ein Device. Prinzipiell sollte das auch möglich sein*, das z.B. bei Artnet auch automatisch so zu machen, also z.B. statt dass Du 10 Artnet-Devices patcht, gibt es nur eins, und die Ausgaberoutine teilt das selbst in versch. Universes auf...

    *damit meine ich, man könnte das wohl so programmieren, hat Sven aber nicht gemacht, ist da bei Artnet halt auch nicht üblich...


    Du kannst dann auch das

    Code
    #define UDP_TX_PACKET_MAX_SIZE 50000

    wieder runter setzen, weil das ist ja Verschwendung, so große Frames werden da nie ankommen...

    Das (Zitat) "Um 1024 channels/block kommen die Daten interessanterweise am schnellsten durch (dauert ca. 3,5ms). Kürzere oder längere packets machen es langsamer."


    kann ich mir auch so erklären: Wenn Jinx! die Daten auf mehr Blöcke aufteilen, und mehr Ethernet-Frames verschicken muss, dauert das natürlich länger, als wenn es nur "ein paar" Frames sind... dass es bei größeren Paketen langsamer wird, liegt dann wohl irgendwie an Netzwerkkarte/Switch, dass die evtl. irgendwie Probleme bekommen, wenn man mit der Framegröße an's Maximum geht...

    (Zitat) "Damit Jinx! 1024 channels sendet, muss ich dort übrigens 1023 einstellen... hat mich ne Zeit gekostet, das zu checken." - 1024 lässt sich nicht durch drei teilen... ;) - ich vermute, dass Jinx! nicht RGB eines Pixels über mehre Blöcke verteilen kann... deswegen 1023, das sind glatt durch drei dann 341 Pixel...


    btw., ich habe noch nie ausgerechnet, wie viele Pixel man eigentlich über tpm2.net übertragen kann... ^^ - bei Frames mit 1023 Bytes, also je 341 Pixel, wären das dann (bei max. 255 Blöcken) 86.955 Pixel - also genug für den Teensy :S

    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!