DMX512
Konzept
Der DMX-Treiber gibt ein DMX512-Universum aus (bis 512 Kanäle). Jede Geräteinstanz (z. B. ein LED-Strip) belegt ab ihrer Startadresse eine Reihe von Kanälen. Die Sendefunktion überträgt immer den gesamten Zustand. PROTOCOL beginnt mit DMX512 (z. B. DMX512 (DDF)).
Parameter
| Key | Default | Beschreibung |
|---|---|---|
CONNECTION |
– | SERIALPORT |
DMXTYPE |
– | 0 = STANDARD, 1 = INTERN |
SERIALPORT |
– | Schnittstelle |
MIN_PAUSE |
10 ms | Pause zwischen Frames (im Beispiel 0) |
WAIT_AFTER_CONNECT |
– | s |
SLAVE |
– | DMX-Startadresse(n) 1…512 bzw. Slaveliste |
SLAVESMAX |
– | Anzahl Instanzen (z. B. 10 Strips) |
CONFIGFILE |
– | ENABLED: Startadressen und Kanalzahlen kommen aus der Konfiguration |
Sendefunktion
Im realen Beispiel ist die Sendefunktion eine *PREPROCESS-Zeile mit dem Alias SEND und POLLING 30 ms, ohne eigene Formel. Der Kopf verwendet die SERCOM-artigen Spalten, nur ALIAS und POLLING sind belegt.
Kanalwerte werden in die Rohdaten der Funktion geschrieben:
| Ausdruck | Bedeutung |
|---|---|
SEND.<idx> := wert; |
einzelner Kanal (0…255), zu klären: im Beispiel nicht verwendet |
SETVALUE('SEND','',idx,r,g,b,w); |
schreibt die Werte ab Index idx |
SETVALUES('SEND','',idx,n,r,g,b,w); |
schreibt n Wiederholungen der Wertegruppe ab idx (z. B. n RGBW-Pixel) |
START, COUNT |
Startkanal und Kanalzahl der Instanz (per $.SLAVE.<n>.START / .COUNT gesetzt) |
Der Index ist 0-basiert relativ zum Universum. Das Beispiel rechnet deshalb kanali:=KANAL-1;.
Realer Auszug: myGEKKO LEDSTRIP TYPE A
Datei myGEKKO.Lamp.DMX512 (DDF).LEDSTRIP TYPE A.1(0x0F00000100010100).csv (stark gekürzt; die Originaldatei enthält 10 Lichteffekte):
*GENERAL;
;DEVICE;LEDSTRIP TYPE A;
;MANUFACTURER;myGEKKO;
;TYPE;Lamp;
;PROTOCOL;DMX512 (DDF);
;MODEL_NR;1;
;VERSION_NR;1;
;ID;0x0F00000100010100;
;MIN_CONTROL_VERSION;V10086-00;
;CONNECTION;SERIALPORT;0:SERIALPORT,1:SERIALPORT+,2:IPADDRESS,3:DOMAIN;
;WAIT_AFTER_CONNECT;2;s;
;MIN_PAUSE;0;ms;
;SLAVESMAX;10;
;DMXTYPE;0;0=STANDARD,1=INTERN;
;CONFIGFILE;ENABLED;
*PREPROCESS;ALIAS;SEND;RECEIVE_LEN;DATATYPE;DELIMITER_START;DELIMITER_END;POLLING;FORMULA;
;SEND;;;;;;30;
*GROUP;ID;ALIAS;NAME;
;0;LEDSTRIP;LEDSTRIP;
*ITEM;ALIAS;NAME;VISIBILITY;ID;UNIT;TYPE;DEFAULT;WFORMULA;RFORMULA;POLLING;
;READOK;READOK;HIDDEN;0;;;;;"""
IF $.SLAVE==1 THEN
SLAVES:='';
LOAD_CONFIG(0);
IF GROUP.1.START > 0 THEN
tmpslv:=PRINT(DEC,'%lld',GROUP.1.START);
SLAVES:=CONCAT(SLAVES,tmpslv);
$.SLAVE.1.START:=1;
$.SLAVE.1.COUNT:=GROUP.1.COUNT;
ELSE
$.SLAVE.1.START:=0;
ENDIF;
/* … GROUP.2 … GROUP.5 analog … */
IF ISEQUAL(SLAVES,$.GPARAM.SLAVELIST)==0 THEN
DEBUG(SLAVES,$.GPARAM.SLAVELIST);
$.GPARAM.SLAVELIST:=SLAVES;
ENDIF;
ENDIF;
CLR_R:=ITEM.RED/128;
/* … CLR_G, CLR_B, CLR_W analog … */
sclrr:=DECIMAL_TO_STRING(CLR_R);
/* … */
ITEM.RGBW:=CONCAT(sclrr,',',sclrg,',',sclrb,',',sclrw);
""";1000;
;ON;ON;;1;;;;;"""
CLR_R:=ITEM.RED/128;
/* … */
IF KANAL<START THEN
KANAL:=START;
ELSE IF KANAL>(START+COUNT-4) THEN
KANAL:=START;
ENDIF;
KANALOLD:=KANAL;
SWITCH ITEM.EFFECT
CASE 0:
EFFEKT:='ON';
CASE 1:
EFFEKT:='BLINK';
/* … CASE 2 … 9 … */
DEFAULT:
EFFEKT:='OFF';
ENDSWITCH;
IF ITEM.ON >0 THEN
IF ISEQUAL(EFFEKT,'ON') THEN
KANAL:=START;
kanali:=KANAL-1;
channels:=COUNT/4;
SETVALUES('SEND','',kanali,channels,CLR_R , CLR_G , CLR_B, CLR_W);
ELSE IF ISEQUAL(EFFEKT,'OFF') THEN
/* … */
SETVALUES('SEND','',kanali,channels,0,0,0,0);
ELSE IF ISEQUAL(EFFEKT,'RUNNINGUP') THEN
/* … */
SETVALUE('SEND','',kanaloldi,+0,0,0,0);
SETVALUE('SEND','',kanali,CLR_R , CLR_G , CLR_B, CLR_W);
/* … weitere Effekte … */
ENDIF;
ENDIF;
""";
(Stark gekürzt. Ausgelassene Stellen sind mit /* … */ markiert. Effekte laut Original: ON, BLINK, PINGPONG, RUNNINGUP, RUNNINGDOWN, METEOR, RAINBOWFLOW, POSITION, FILL, AURORA.)
Was der Auszug zeigt:
- Jede Anweisung endet mit
;, auchENDSWITCH;und Funktionsaufrufe wieSETVALUES(…);. NachCASE n:undDEFAULT:steht kein;. - Instanz 1 (
$.SLAVE==1) liest die Konfiguration (LOAD_CONFIG(0);). Sie baut aus den Startadressen der Gruppen die Slaveliste und setztSTART/COUNTder anderen Instanzen über$.SLAVE.<n>.*. - Die Farbwerte der Items werden auf 0…255 skaliert (
ITEM.RED/128) und mitSETVALUESals RGBW-Pixel (4 Kanäle je Pixel) geschrieben. - Effekte werden als Zustandsmaschine über temporäre Variablen realisiert (
KANAL,KANALOLD,EFFEKT). Die Variablen behalten ihren Wert zwischen den Aufrufen.
Fallstricke
- Überlappende Startadressen mehrerer Instanzen überschreiben sich gegenseitig.
- Kanalwerte müssen im Bereich 0…255 liegen.
- Der Index ist 0-basiert (
Startadresse − 1). - Zu kleine
MIN_PAUSEkann einfache Empfänger überfordern.
Checkliste
- [ ]
PROTOCOLbeginnt mitDMX512 - [ ] Sendefunktion
SENDmitPOLLINGvorhanden - [ ]
START/COUNTje Instanz gesetzt, keine Überlappung - [ ] Kanalwerte 0…255, Index
START-1 - [ ] jede Anweisung mit
;abgeschlossen