Forum: Mikrocontroller und Digitale Elektronik "Bester" Weg für Eigenbau USB-DMX-Interface mit ATSAM


von Manfred (manniw)


Lesenswert?

Ich möchte mir ein 4 Fach USB DMX Interface basierend auf einem ATSAME70 
oder V70 bauen. Ich vermute, dass ich nicht darum herumkomme ein eigenes 
USB Protokoll zu entwickeln. Mein Ansatz war hier auf HID aufzubauen. 
Wer mit DMX nicht vertraut ist: Es handelt sich um ein Protokoll zur 
Lichtsteuerung wo immer 512 Werte (von 0-255) gesendet werden. Der 
ATSAME70 hat eine High-Speed-USB-Schnittstelle sodass die Daten 
entsprechend schnell übertragen werden können. Wie gehe ich es nun an 
eine möglichst geringe Latenz hin zu bekommen? Zum einen macht es wohl 
Sinn nur Änderungen zu versenden und nicht jedes mal 4x512 Werte. Dann 
hatte ich gedacht die Daten als "Start Kanal, Kanal-Anzahl, Wert1, 
Wert2..." zu senden, und dabei spätestens nach 255 Kanälen Schluss zu 
machen. Da sich aber nur in seltenen Fällen viele benachbarte Kanäle 
ändern macht es vielleicht mehr Sinn die Werte einzeln zu übertragen als 
"Kanal, Wert, Kanal, Wert usw."? Der Treiber würde dann quasi immer die 
aktualisierten Kanäle von der Software bekommen, die in einen Ringbuffer 
schreiben und diesen dann immer wenn er nicht leer ist irgendwie ans 
Interface senden. Ist er leer geht's in einen sleep der von dem 
neue-Daten Aufruf unterbrochen wird.

Ist der Trick um es möglichst effizient hinzubekommen einfach "beides" 
zu nutzen, also einen HID endpoint für "single channel" requests und 
einen für "multi channel" requests und im Treiber dann zu schauen was 
gerade am meisten Sinn macht? Oder ist der Overhead dieses einen 
zusätzlichen Bytes zu vernachlässigen sodass ich immer den 
"Multi-Channel-Mode" nutzen sollte, und Löcher mit bis zu 2 
unveränderten Werten nebeneinander einfach unverändert sende weil es 
dann egal ist ob ich die Werte nochmal sende oder einen neuen frame 
bastel?

von Andreas M. (amesser)


Lesenswert?

DMX ist schnarchlangsam. Mit USB Full Speed könnte man so etwa 50 DMX 
Busse à 512 Kanäle gleichzeitig bedienen. Ein 5 Euro Raspi Pico bedient 
8 DMX Kanäle im Schlaf. Mit ein Bischen Grips vermutlich noch viel mehr.

Vom Protokoll her würde ich OpenDMX USB vorschlagen, da sollte es von 
der PC Seite her schon fertige Software geben.

Edit: Vertippt, sind "nur" 50 DMX Busse, keine 60

: Bearbeitet durch User
von Frederic S. (frederics)


Lesenswert?

Ich würde dir stark empfehlen Netzwerk (Art Net) zu DMX zu bauen.

- 100m statt 3m max Leistungslänge
- Galvanische Trennung schon inklusive
- deutlich zuverlässiger und angenehmer als USB Protokoll

Dazu gibt es auch zahlreiche Projekte

von Manfred (manniw)


Lesenswert?

Über Art-Net hatte ich auch nachgedacht, die Idee jedoch wieder 
verworfen. Es scheint zum einen keine Ethernet-Phys zu geben die ich 
problemlos löten kann (TQFP Gehäuse oder so), und zum anderen habe ich 
da die Befürchtung, dass die Latenz im Vergleich zu USB ansteigt. Ich 
hatte das mal mit fertiger hardware ausprobiert und das Dimmen bei Fades 
war sehr stufig und keineswegs flüssig wie ich es erwarten würde und von 
meinem billig-udmx-interface kenne wenn ich das auf maximale 
Geschwindigkeit stelle.

Die maximale Leitungslänge ist kein Problem, das Interface sollte 
sowieso in der Regel möglichst in PC Nähe sein, da sind 3m schon 
eigentlich zu weit ;)

Ich hatte aber durchaus schon die Idee einfach beides einzubauen, also 
USB und Art-Net, dann kann man einfach schauen was besser funktioniert.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Manfred schrieb:
> Ich vermute, dass ich nicht darum herumkomme ein eigenes USB Protokoll
> zu entwickeln

Warum? Du kannst auch ein eigenes natives Protokoll entwickeln (z.B. die 
Datenströme der einzelnen Kanäle kontinuierlich über getrennte 
USB-Bulk-Endpoints senden mit "Short Packets" als Ende-Marker), dann 
hast du die volle Flexibilität und Performance der USB-Schnittstelle.

Mit WinUSB+libusb kannst du auch unter Windows ohne Treiberinstallation 
und ohne jegliche manuelle Konfiguration und ohne Admin-Rechte auf das 
Gerät via eigenem Protokoll (keine limitierende Standard-Klasse wie HID 
oder CDC-ACM nötig) zugreifen. Unter Linux ist es mit libusb sowieso 
kein Problem, braucht nur udev-Regeln um Nicht-root-Zugriff zu erlauben.

: Bearbeitet durch User
von C-hater (c-hater)


Lesenswert?

Manfred schrieb:

> Ich möchte mir ein 4 Fach USB DMX Interface

Rein sendend oder soll auch DMX-RDM (in allen Varianten) funktionieren? 
Das ist ein ziemlich großer Unterschied bezüglich der Komplexität...

> basierend auf einem ATSAME70
> oder V70

Warum auch immer. Aber egal.

> Ich vermute, dass ich nicht darum herumkomme ein eigenes
> USB Protokoll zu entwickeln.

Nunja, irgendwie schon. Ganz sicher jedenfalls, wenn du auch RDM 
unterstützen möchtest/musst.

> Mein Ansatz war hier auf HID aufzubauen.

Kann man machen. Um ein eigenes Protokoll kommt man trotzdem nicht 
herum.

> Wie gehe ich es nun an
> eine möglichst geringe Latenz hin zu bekommen?

Primär: Nicht USB verwenden. Bei Full-Speed-USB hast du zwingend 1ms 
Mindestlatenz. Das liegt daran, dass der USB-Hostcontroller in 
1ms-Zyklen arbeitet. Nix geht zeitnäher als mit eben dieser Zykluszeit.

> Zum einen macht es wohl
> Sinn nur Änderungen zu versenden

Nein, macht es nicht, jedenfalls nicht bezüglich der Geschwindigkeit 
Übertragungsstrecke. USB-Fullspeed (=10Mbit/s brutto) reicht mehr als 
locker, um die lächerlichen 4x250kBit/s (=1Mbit/s) für 4 DMX-Kanäle 
durchzuschleusen. Da liegt ein Faktor 10 dazwischen!

von Frank E. (Firma: Q3) (qualidat)


Angehängte Dateien:

Lesenswert?

Für ein einfaches (!) DMX-Interface benutze ich seit Jahren diesen 
RS485-Wandler zum Wahnsinnspreis von ca, 5,-

https://www.amazon.de/Seriell-Konverter-Adapter-FT232RL-Interface/dp/B07Z1V5WQS

Wird von allen mir bekannten Softwares (z.B. PC-Dimmer für Windows oder 
QLC+ auf dem Mac) als "generic" erkannt.

: Bearbeitet durch User
von C-hater (c-hater)


Lesenswert?

Frank E. schrieb:

> Für ein einfaches (!) DMX-Interface benutze ich seit Jahren diesen
> RS485-Wandler zum Wahnsinnspreis von ca, 5,-

Nicht die schlechteste Lösung.

Aber spätestens bei Unterstützung für mehr als einen Kanal (das war Teil 
der Aufgabe!) muss diese Lösung passen. Erst recht natürlich, wenn auch 
noch Support für RDM gefordert ist.

Rein sendend könnte man aber immerhin einfach 4x diese Lösung verwenden. 
Ohne jegliche größere Software-Klimmzüge. Kostet dann halt 4x diesen 
Adapter + 1x 4-Port-Hub. Sollte trotzdem absolut bezahlbar bleiben, da 
spottbillige Massenware.

von Manfred (manniw)


Lesenswert?

C-hater schrieb:
> Manfred schrieb:
>
>> Ich möchte mir ein 4 Fach USB DMX Interface
>
> Rein sendend oder soll auch DMX-RDM (in allen Varianten) funktionieren?
> Das ist ein ziemlich großer Unterschied bezüglich der Komplexität...

RDM habe ich bislang nie genutzt, die Richtungsumschaltung der RS-485 
Bausteine werde ich zwar vorsehen um in Zukunft nur die Software 
anpassen zu müssen, aber für den Anfang muss das ganze kein RDM können.

>> basierend auf einem ATSAME70
>> oder V70
>
> Warum auch immer. Aber egal.

Weil das die am höchsten getakteten CPUs von Atmel/Microchip sind und 
einige der wenigen sind die Full-Speed USB könen.

>> Wie gehe ich es nun an
>> eine möglichst geringe Latenz hin zu bekommen?
>
> Primär: Nicht USB verwenden. Bei Full-Speed-USB hast du zwingend 1ms
> Mindestlatenz. Das liegt daran, dass der USB-Hostcontroller in
> 1ms-Zyklen arbeitet. Nix geht zeitnäher als mit eben dieser Zykluszeit.

Das Problem habe ich bei Full-Speed dann ja nicht mehr, dort soll es ca. 
125 Mikrosekunden Latenz geben.

>> Zum einen macht es wohl
>> Sinn nur Änderungen zu versenden
>
> Nein, macht es nicht, jedenfalls nicht bezüglich der Geschwindigkeit
> Übertragungsstrecke. USB-Fullspeed (=10Mbit/s brutto) reicht mehr als
> locker, um die lächerlichen 4x250kBit/s (=1Mbit/s) für 4 DMX-Kanäle
> durchzuschleusen. Da liegt ein Faktor 10 dazwischen!

Aber es würde die Latenz reduzieren indem weniger Daten übertragen 
werden müssen und somit die Zeit bis eine Übertragung abgeschlossen ist 
auch kürzer wird. Wenn ich immer die kompletten 4 DMX Universen 
übertrage könnte ich gerade eine Werteänderung verpasst haben und sende 
dann 2047 ungeänderte Kanäle bis der geänderte Kanal endlich gesendet 
wird. Durch High-Speed USB ist das wohl jetzt nicht so schlimm, aber 
trotzdem gewissermaßen unnötig.

Ich nutze aktuell ein uDMX Interface, das macht blöderweise aber mit 
einem meiner Rechner Probleme weshalb ich nun eine Alternative suche.

Niklas G. schrieb:
> Du kannst auch ein eigenes natives Protokoll entwickeln (z.B. die
> Datenströme der einzelnen Kanäle kontinuierlich über getrennte
> USB-Bulk-Endpoints senden mit "Short Packets" als Ende-Marker), dann
> hast du die volle Flexibilität und Performance der USB-Schnittstelle.

Das werde ich mir definitiv mal anschauen. Der ATSAM kann maximal 10 
Endpoints, also könnte ich z.B. einen für Konfiguration, dann die 4 DMX 
Universen/Ports (je nach eingestelltem Modus, also DMX out oder DMX in, 
wird dann gelesen oder geschrieben, das muss wohl nicht getrennt 
werden), und hätte dann noch Endpoints um Spielereien wie z.B. 
Ethernet-over-USB zu machen und Artnet zu unterstützen (hat jemand auf 
Github mit nem STM32 gemacht, der meldet sich als USB Netzwerkkarte), 
oder einen Seriellen Port der das Enttec Protokoll spricht. Das wäre 
wohl maximale Flexibilität. Wobei man vermutlich die ungenutzten Dinge 
abschalten sollte (insbesondere das USB-Ethernet).

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Manfred schrieb:
> und einige der wenigen sind die Full-Speed USB könen.

Nein, sogar High-Speed (480 Mbps). Full-Speed sind 12 Mbps.

Manfred schrieb:
> Das Problem habe ich bei Full-Speed dann ja nicht mehr, dort soll es ca.
> 125 Mikrosekunden Latenz geben.

Nein, bei High-Speed.

Manfred schrieb:
> also könnte ich z.B. einen für Konfiguration

Das könnte man auch über den Default Control Endpoint 0 machen.

von J. S. (engineer) Benutzerseite


Lesenswert?

Manfred schrieb:
> Wie gehe ich es nun an
> eine möglichst geringe Latenz hin zu bekommen?

Bist du sicher, dass die Latenz dorthin das Problem ist? Die meisten 
DMX-Controller senden ja das volle  Universum raus und brauchen daher 
für alle möglichen Kanäle den kompletten Loop von 256/250kHz. Das ist 
grottenlangsam in der update-Rate. Wenn schon, musst du eine 
Verbesserung dahingehend fahren, dass du einen splitter baust, der z.B. 
8 x 32 Kanäle fährt, um da erst einmal Tempo reinzubringen, die das 
Zuspielen in den Controller überhaupt erst einmal relevant werden zu 
lassen.

Ich fahre meinen MIDI-DMX z.B. mit nur jeweils 16 Kanälen, wenn ich es 
steuere. Ansonsten ist das nichts anderes als bequemer Mischpultersatz, 
wenn man viel langsam regeln will. Ich habe mir welche vom T geholt 
(Stairville, Botex SDC-24 und den Showtec 32).

von Manfred (manniw)


Lesenswert?

Das Problem ist mir bekannt, daher will ich in Zukunft auf 4 Universen 
gehen um dann nur noch 128 Kanäle oder so pro Universum rauszuschicken, 
im besten Fall 64 oder noch weniger. Die vollen 512 Kanäle habe ich 
sowieso noch nicht genutzt und mir ist auch schon aufgefallen wie viel 
flüssiger ein Faden wird wenn man weniger Kanäle raussendet.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wenn die Latenz (nicht Datenrate!) vom USB selbst ein Problem ist, wird 
es weder mit FullSpeed noch mit HighSpeed funktionieren. Mit dem PC 
kannst du sowieso kein Millisekunden-genaues Timing hinbekommen. Daher 
spielt es keine Rolle ob ein vom PC gesendetes Paket erst 1ms oder 125µs 
später beim Gerät ankommt.

Um überhaupt die Datenrate vom USB auszunutzen musst du große 
Datenpakete am Stück senden. Ob das jetzt jeweils ganze DMX-Universen 
oder eine Reihe an Änderungs-Befehlen ist, ist dafür erstmal egal. Du 
musst auf jeden Fall "vorausschauend" den aktuellen, nächsten (und 
übernächsten?) DMX-Inhalt in große Pakete zusammenpacken und raus 
senden. Auf dem Controller nimmst du das auseinander und sendest die 
einzelnen Zustände einzeln raus. Du kannst ja auch "Pause"-Befehle 
mitschicken, wenn der Controller zwischen einzelnen Zuständen warten 
soll.

Auf dem Controller braucht es also einen Ringpuffer. Auf dem PC nicht, 
der muss nur wissen was schon gesendet wurde, und immer so schnell wie 
der USB erlaubt alles raussenden was da ist; das Lichtmuster ist der 
PC-Software ja in Gänze im Voraus bekannt, und wird nicht in Echtzeit 
ermittelt? In der PC-Software muss praktisch zu jedem Zeitpunkt ein 
USB-Transfer aktiv sein (keine Pausen machen).

Wenn auf dem Controller der Ringpuffer voll läuft (d.h. das 
DMX-Universum ändert sich langsam) sendest du einfach NAK auf dem 
betreffenden Endpoint bis wieder Platz ist. In der Praxis bedeutet das 
schlicht und ergreifend, die USB-Empfangs-Funktion deines jeweiligen 
USB-Framework nur dann aufzurufen, wenn Platz im Ringpuffer ist. Die 
PC-Seite bekommt davon kaum was mit (nur dass der Transfer länger 
dauert).

Und dann ist nur noch die Datenrate vom USB relevant, und die Latenz ist 
unwichtig. Und dann reicht FS vielleicht auch schon.

Auf dem PC im Zeitraster der Darstellung die Zustände raussenden 
funktioniert ziemlich sicher nicht (à la Zustand 1 ans Gerät schicken, 
3ms warten, nächsten Zustand schicken, 7.5ms warten, nächsten schicken 
...).

: Bearbeitet durch User
von Christoph Z. (christophz)


Lesenswert?

Niklas G. schrieb:
> Manfred schrieb:
>> Das Problem habe ich bei Full-Speed dann ja nicht mehr, dort soll es ca.
>> 125 Mikrosekunden Latenz geben.
>
> Nein, bei High-Speed.

Und das garantiert auch nur für Isochrone Transfers (der Endpoint muss 
so konfiguriert sein). Bulk Transfers dürfen auch auf später verschoben 
werden wenn der Bus etwas ausgelastet ist. Dafür darf USB bei einem 
Isochronen Transfer auch Daten verlieren (so wie es bei IP/UDP z. B. 
passieren darf).

Für eine veringerte und recht konstante Lazenz (was für weiche 
Bewegungen wohl relevanter ist) würde ich aus der Hüfte heraus 
vorschlagen:
- 4 Endpoints Isochron (Pro DMX Kanal einen)
- Auf jedem dieser Endpoints jedes mal das ganze Universum 
rausschreiben, dann ist es egal ob Daten verloren gehen, die kommen 
einfach beim nächsten Zyklus

Beitrag #7418629 wurde vom Autor gelöscht.
von Manfred (manniw)


Lesenswert?

Niklas G. schrieb:
> Auf dem PC nicht,
> der muss nur wissen was schon gesendet wurde, und immer so schnell wie
> der USB erlaubt alles raussenden was da ist; das Lichtmuster ist der
> PC-Software ja in Gänze im Voraus bekannt, und wird nicht in Echtzeit
> ermittelt?

Leider nicht. Also theoretisch würde es in einigen Fällen vielleicht 
gehen, in der Praxis ist jede Lichtsteuerungssoftware so aufgebaut, dass 
sie in Echtzeit berechnet was ausgegeben werden soll und das ganze dann 
an das Interface sendet.

Niklas G. schrieb:
> Auf dem PC im Zeitraster der Darstellung die Zustände raussenden
> funktioniert ziemlich sicher nicht (à la Zustand 1 ans Gerät schicken,
> 3ms warten, nächsten Zustand schicken, 7.5ms warten, nächsten schicken
> ...).

So wird es üblicherweise gemacht. Man darf ja auch nicht vergessen, dass 
DMX sowieso nicht so schnell ist. Wenn ich also tatsächlich mit der 
vollen High-Speed-USB-Geschwindigkeit immer wieder die 4 Universen ans 
Interface rausschreibe wird das bestimmt immer noch ein vielfaches der 
DMX Refreshrate sein, egal wie klein ich das Universum nun wähle.

Der Treiber hätte dann 4 Arrays mit jeweils 512 Bytes und die Software 
würde dann in diese Array schreiben und ein anderer Thread würde diese 
Arrays so schnell wie möglich ans Interface senden. Bestenfalls könnte 
man am Interface dann mit DMA die Daten direkt in den "Zielpuffer" 
schreiben lassen sodass sie dann beim nächsten Sende-Durchlauf gelesen 
und gesendet werden. Dann braucht es dort nicht mal ein kopieren.

Christoph Z. schrieb:
> Dafür darf USB bei einem
> Isochronen Transfer auch Daten verlieren (so wie es bei IP/UDP z. B.
> passieren darf).

Kommt das in der Praxis denn auch vor? Bei UDP ist es zumindest solange 
man im LAN ist und die Auslastung hinreichend gering ist ja meistens 
kein Problem und packet loss ist extrem selten.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Manfred schrieb:
> Also theoretisch würde es in einigen Fällen vielleicht
> gehen, in der Praxis ist jede Lichtsteuerungssoftware so aufgebaut, dass
> sie in Echtzeit berechnet was ausgegeben werden soll und das ganze dann
> an das Interface sendet.

Das ist ungünstig. Da sollte dein Treiber vielleicht z.B. für eine 
Sekunde die Ausgabe der Software puffern, so viel wie möglich in große 
Pakete zusammenfassen (dann doch wieder mit Ringpuffer) und diese dann 
am Stück über USB raus schieben.

von Manfred (manniw)


Lesenswert?

Niklas G. schrieb:
> Manfred schrieb:
>> Also theoretisch würde es in einigen Fällen vielleicht
>> gehen, in der Praxis ist jede Lichtsteuerungssoftware so aufgebaut, dass
>> sie in Echtzeit berechnet was ausgegeben werden soll und das ganze dann
>> an das Interface sendet.
>
> Das ist ungünstig. Da sollte dein Treiber vielleicht z.B. für eine
> Sekunde die Ausgabe der Software puffern, so viel wie möglich in große
> Pakete zusammenfassen (dann doch wieder mit Ringpuffer) und diese dann
> am Stück über USB raus schieben.

Das wird nicht besser, wenn man z.B. Sound-To-Light nutzen möchte oder 
per Hand einen Lichtwechsel auslöst gibt's eine extreme Verzögerung. Da 
muss man schon so schnell wie möglich die Daten raussenden und hoffen 
das es schnell genug ist, alles andere wird nicht schön. Vermutlich ist 
die Idee mit dem kompletten Universum als Isochronen Transfer schon das 
beste was man machen kann.

Mit 512 Kanälen hat man eine Refresh-Rate von 44 Hz. Halbiert man es auf 
256 Kanäle sind es nur noch 88 Hz, bei 128 Kanälen sind es schon 166 Hz, 
und bei 64 sind es 332 Hz. Wenn man also 4 x 64 Kanäle versendet, und 
das 332 Mal pro Sekunde kommt man auf 84992 Bytes pro Sekunde wenn ich 
in jedem DMX-Paket alle Kanäle wechseln lassen möchte. Wenn ich volle 
512 Kanäle sende bleibt die Datenrate identisch, bedingt durch die 
langsamere DMX Refreshrate. Die 85 Kilobyte pro Sekunde sind aber nur 
ein Bruchteil von dem was High-Speed USB leisten kann, vermutlich muss 
ich also sogar den Treiber etwas "einbremsen" um nicht die CPU des PCs 
völlig unnötig zu belasten und mehrfach pro Millisekunde das ganze 
Universum zu senden wenn das Interface nur alle 3 Millisekunden ein 
neues DMX Paket auf die Leitung schickt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.