Programmcode Befehle Syntax Beispiele
Programmcode Befehle Syntax Beispiele
Inhaltsverzeichnis
- 1 Vorwort
- 2 Grundlegendes
- 3 Befehle
- 3.1 PCDimmer
- 3.1.1 get_globalvar() - globale Variable lesen
- 3.1.2 get_lastmidi() - letzen MIDI Input abfragen
- 3.1.3 get_var() - lokale Variable lesen
- 3.1.4 set_globalvar() - globale Variable speichern
- 3.1.5 set_panelbuttoncolor() - Kontrolpanel Button Farbe setzen
- 3.1.6 set_panelbuttontext() - Kontrolpanel Button Text setzen
- 3.1.7 set_var() - lokale Variable speichern
- 3.1.8 ShowMessage() - Nachrichtenbox anzeigen
- 3.1.9 startscene() - Starte Szene/Effekt
- 3.2 Delphi / Pascal
- 3.2.1 Copy() - Substring aus String
- 3.2.2 exit - Prozedur vorzeitig verlassen
- 3.2.3 For Next - For Next Schleife
- 3.2.4 function - Funktion wenn code öfters gebraucht wird
- 3.2.5 IF THEN ELSE - bedingte Abfrage
- 3.2.6 IntToStr() - Variable Integer zu String umwandeln
- 3.2.7 ORD() - ASCII ermitteln
- 3.2.8 random () - Zufallszahl
- 3.2.9 randomize - pseudo Reihenfolge random ändern
- 3.2.10 try - Fehler behandeln
- 3.2.11 var - Variablen Deklaration
- 3.2.12 var array - Array Deklaration
- 3.1 PCDimmer
Vorwort
Seit 05/2022 gibt es Code-Szenen in der Szenenverwaltung. Vorher konnte Code nur bei einem Button im Kontrolpanel hinterlegt werden. Dieses Tutorial ist deshalb vermutlich für beides gültig.
Hier werden die Befehle beschrieben die in einer Code-Szene verwendet werden können. Es wird auch auf Delphi Befehle eingegangen. Möglichst immer mit einem Beispiel. Ich erweitere dieses Tutorial Befehl für Befehl. Immer dann wenn ich den Befehl in der Praxis selbst probiert habe. Eine Kurzhilfe hat Christian jeweils im "Edit-Modus" hinterlegt.
Grundlegendes
CodeSzene - Prinzipieller Aufbau
Sobald eine neue CodeSzene in der Szenenverwaltung hinzugefügt wird beinhaltet sie bereits diesen grundlegenden Programmcode. Euren Programmcode schreibt ihr in die "procedure StartScene;" zwischen "begin" und "end;". Als Beispiel ist ein Befehl (rot markiert) dort zu finden.
Vieleicht schreibt Christian was zu "procedure InitScene;" und "procedure StopScene;". Ich müsste raten.
interface
procedure InitScene;
procedure StartScene;
procedure StopScene;
implementation
procedure InitScene;
begin
end;
procedure StartScene;
begin
ShowMessage('Hello World');
end;
procedure StopScene;
begin
end;
end.
Zeile mit ; abschließen
Jede Programmcode Zeile muss mit ; (Strichpunkt) enden. Der Hintergrund ist, dass der Programmcode nicht Zeilenweise abgearbeitet wird. Der Strichpunkt löst die Befehlsabarbeitung aus.
Sollte man diesen vergessen, vermischt der Befehlsinterpreter euren Code. Es kommt zu den irrsinnigsten Fehlermeldungen.
Es gibt jedoch Ausnahmen. Befehle die wiederum Code enthalten. Zum Beispiel "if". Dieser Code wird meist in geschweifte Klammern gesetzt.
for (int i=0;i<10;i++)
if( values[i]>0&&values[ i+1 ]>0 )
{
out.println ("found!");
break;
}
// Bemerkung
Es ist sehr empfehlenswert Bemerkungen im Code zu hinterlassen. Eine Bemerkung wird mit // gestartet. Es ist kein ; als Abschluss notwendig. Die Bemerkung endet mit dem Zeilenende (Umbruch) automatisch. Kann auch hinter einer Befehlszeile angewendet werden.
procedure StartScene; begin // Mein erster Code ShowMessage( 'Hello World' ); // Eine Messagebox end;
Befehle
PCDimmer
get_globalvar() - globale Variable lesen
Der Befehl (Funktion) get_globalvar(variableNummer) gibt die globale Variable typ Variant zurück die unter "variableNummer" abgelegt ist. Wurde die globale Variable vorher nicht mit set_globalvar(variableNummer, inhalt) gesetzt so ist diese leer. Eine globale Variable kann von allen CodeSzenen genutzt werden. Variableninhalt bleibt erhalten bis PCDimmer (oder Projekt) beendet wird. Im Beispielcode wird die globale Variable Nummer 5 ausgelesen.
procedure StartScene; var variableNummer, testVariable:variant; begin variableNummer := 5; testVariable := get_globalvar(variableNummer); ShowMessage( 'Inhalt Variable ' + VarToStr(variableNummer) + ': ' + VarToStr(testVariable) ); end;
get_lastmidi() - letzen MIDI Input abfragen
Der Befehl (Funktion) get_lastmidi() gibt einen String zurück mit drei Zeichen Länge. Die drei Zeichen sind MIDI_MSG, MIDI_Data1 und MIDI_Data2. Im Beispiel wird gezeigt wie man diese zerrlegt und in eine Zahl umwandelt.
procedure StartScene;
var
MIDI_last_MSG, MIDI_last_Data1, MIDI_last_Data2, MIDI_last_in:variant;
begin
MIDI_last_in := get_lastmidi());
MIDI_last_MSG := Ord(Copy(MIDI_last_in,1,1);
MIDI_last_Data1 := Ord(Copy(MIDI_last_in,2,1));
MIDI_last_Data2 := Ord(Copy(MIDI_last_in,3,1));
ShowMessage( IntToStr(MIDI_last_MSG) + '-' + IntToStr(MIDI_last_Data1) + '-' + IntToStr(MIDI_last_Data2));
end;
get_var() - lokale Variable lesen
Der Befehl (Funktion) get_var(variableNummer) gibt die lokale Variable typ Variant zurück die unter "variableNummer" abgelegt ist. Lokale Variablen können erst genutzt werden, wenn die CodeSzene mindestens ein mal gespeichert wurde. Wurde die lokale Variable vorher nicht mit set_var(variableNummer, inhalt) gesetzt so ist diese leer. Eine lokale Variable kann nur von dieser CodeSzenen genutzt werden, ist nicht in anderen CodeSzenen erreichbar. Variableninhalt bleibt erhalten bis PCDimmer (oder Projekt) beendet wird. Im Beispielcode wird die lokale Variable Nummer 5 ausgelesen.
procedure StartScene; var variableNummer, testVariable:variant; begin variableNummer := 5; testVariable := get_var(variableNummer); ShowMessage( 'Inhalt Variable ' + VarToStr(variableNummer) + ': ' + VarToStr(testVariable) ); end;
set_globalvar() - globale Variable speichern
Der Befehl (Funktion) set_globalvar(variableNummer, inhalt) speichert "inhalt" in die globale Variable "variableNummer" als Typ Variant. Eine globale Variable kann von allen CodeSzenen genutzt werden. Variableninhalt bleibt erhalten bis PCDimmer (oder Projekt) beendet wird. Im Beispielcode wird die globale Variable Nummer 5 gespeichert mit einer Zufallszahl.
Die Anzahl der möglichen Variablen-Nummern ist auf den INTEGER Zahlenraum begrenzt und hängt nur vom Speicher des Rechners ab. Also mehr als genug.
Weiterhin empfehle ich sich eine Liste anzulegen für die globalen Variablen die man benutzt. Am besten mit Variablennummer, einer kurzen Beschreibung und wo diese Variable, CodeSzene/ButtonCode, überall genutzt wird.
procedure StartScene; var variableNummer, testVariable:variant; begin variableNummer := 5; testVariable := random(100); set_globalvar(variableNummer, testVariable); ShowMessage( 'Inhalt Variable ' + VarToStr(variableNummer) + ': ' + VarToStr(testVariable) ); end;
set_panelbuttoncolor() - Kontrolpanel Button Farbe setzen
Der Befehl (Funktion) set_panelbuttoncolor(ButtonX, ButtonY, ButtonColor) setzt die Hintergrundfarbe eines Buttons. Die Farbe in HEX angegeben hat den Aufbau $bbggrr. Butten X/Y bedeutet Spalte/Zeile.
ButtonX := 13; ButtonY := 1; ButtonColorOn := $00ff00; // Farbe definieren mit HEX $bbggrr. Alternative Farbe soft $c0dcc0 ButtonColorOff := $0000ff; // Farbe definieren mit HEX $bbggrr. Alternative Farbe soft $8888ff ButtonTextOn := 'AutoBPM ist an'; ButtonTextOff := 'AutoBPM ist aus'; AutoBPMjOnOff := get_globalvar(2); // Lese globale Varible "AutoBPMOnOff" if( AutoBPMjOnOff = 'Off' ) then begin AutoBPMjOnOff := 'On'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOn); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOn); end else begin AutoBPMjOnOff := 'Off'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOff); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOff); end
set_panelbuttontext() - Kontrolpanel Button Text setzen
Der Befehl (Funktion) set_panelbuttontext(ButtonX, ButtonY, ButtonText) setzt den Text eines Buttons. Butten X/Y bedeutet Spalte/Zeile.
ButtonX := 13; ButtonY := 1; ButtonColorOn := $00ff00; // Farbe definieren mit HEX $bbggrr. Alternative Farbe soft $c0dcc0 ButtonColorOff := $0000ff; // Farbe definieren mit HEX $bbggrr. Alternative Farbe soft $8888ff ButtonTextOn := 'AutoBPM ist an'; ButtonTextOff := 'AutoBPM ist aus'; AutoBPMjOnOff := get_globalvar(2); // Lese globale Varible "AutoBPMjOnOff" if( AutoBPMjOnOff = 'Off' ) then begin AutoBPMjOnOff := 'On'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOn); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOn); end else begin AutoBPMjOnOff := 'Off'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOff); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOff); end
set_var() - lokale Variable speichern
Der Befehl (Funktion) set_var(variableNummer, inhalt) speichert "inhalt" in die lokale Variable "variableNummer" als Typ Variant. Lokale Variablen können erst genutzt werden, wenn die CodeSzene mindestens ein mal gespeichert wurde. Eine lokale Variable kann nur von dieser CodeSzenen genutzt werden, ist nicht in anderen CodeSzenen erreichbar. Variableninhalt bleibt erhalten bis PCDimmer (oder Projekt) beendet wird. Im Beispielcode wird die lokale Variable Nummer 5 gespeichert mit einer Zufallszahl.
Die Anzahl der möglichen Variablen-Nummern ist auf den INTEGER Zahlenraum begrenzt und hängt nur vom Speicher des Rechners ab. Also mehr als genug.
Weiterhin empfehle ich sich eine Liste mit // (Bemerkung) am Anfang der CodeSzene anzulegen für die lokalen Variablen die man benutzt. Am besten mit Variablennummer und einer kurzen Beschreibung.
procedure StartScene; var variableNummer, testVariable:variant; begin variableNummer := 5; testVariable := random(100); set_var(variableNummer, testVariable); ShowMessage( 'Inhalt Variable ' + VarToStr(variableNummer) + ': ' + VarToStr(testVariable) ); end;
ShowMessage() - Nachrichtenbox anzeigen
Der Befehl ShowMessage() erzeugt eine Nachrichtenbox (kleines Fenster) mit einem Button "OK". Die Box wird mit klick auf "OK" geschlossen. Die Nachricht wird als String übergeben. Zeilenumbruch im Meldungstext wird mit #10#13 ausgelöst.
procedure StartScene; begin ShowMessage('Hello World' + #10#13 + 'Zeile 2' ); end;
startscene() - Starte Szene/Effekt
Der Befehl startscene('{Szenen-ID}') startet eine Szene oder Effekt. Angesprochen wird immer die ID. Die ID ist in der Nähe der jeweiligen Szene bzw. des Effekts zu finden.
startscene('{4EE3A38B-BE8B-4939-9A05-B1AC66BFE18F}');
Delphi / Pascal
Wie oben beschrieben, zeige ich nur Befehle auf die ich selbst in PCDimmer probiert habe. Solltet ihr Befehle vermissen oder mehr darüber wissen wollt sucht doch einfach im Internet nach Delphi Befehle (Syntax). Meist kann man dies eins zu eins übernehmen.
Copy() - Substring aus String
Der Befehl COPY(source, ab Position, Zeichenzahl) gibt einen String zurück der anhand der Parameter definiert ist. Im Beispiel wird der letzte MIDI Input (String, drei Zeichen lang) zerrlegt in einzelne Strings (Länge 1).
procedure StartScene; var MIDI_last_MSG, MIDI_last_Data1, MIDI_last_Data2, MIDI_last_in:variant; begin MIDI_last_in := get_lastmidi(); MIDI_last_MSG := Ord(Copy(MIDI_last_in,1,1)); MIDI_last_Data1 := Ord(Copy(MIDI_last_in,2,1)); MIDI_last_Data2 := Ord(Copy(MIDI_last_in,3,1)); ShowMessage( IntToStr(MIDI_last_MSG) + '-' + IntToStr(MIDI_last_Data1) + '-' + IntToStr(MIDI_last_Data2)); end;
exit - Prozedur vorzeitig verlassen
Der Befehl exit beendet eine Prozedur ohne dass diese bis zum Ende durchlaufen wird. Im Beispiel wird geprüft ob ein anderer Effekt aufgerufen wird oder dieser schon läuft. Läuft er, wäre es sinnlos die Prozedur zu durchlaufen. Es wird mit exit abgebrochen.
if EffektCurrent = EffektNewName then exit; // nicht mehrfach ausführen wenn keine Änderung ansteht
For Next - For Next Schleife
Klassische For- Next Schleife.
var i:integer; //... for i := 0 to 2 do begin //... end;
function - Funktion wenn code öfters gebraucht wird
Mit function kann man wiederkehrend Code, oder Berechnungen, zusammen fassen und wiederkehrend aufrufen. Die Funktion muss zuerst unter Interface bekannt gegeben werden. Wird die Funktion aufgerufen können mehrere Variablen übergeben werden. Die Funktion kann diese verarbeiten. Die Funktion kann mit result einen Wert zurück geben.
unit CodeScene; interface procedure InitScene; procedure StartScene; procedure StopScene; function Testerli():variant; implementation procedure InitScene; begin end; procedure StartScene; var Dim1, Dim2 : string; i1, msg1 : variant; begin msg1 := '1'; i1 := Testerli (msg1, 'die Zweite Variable'); ShowMessage('Result Testerli: ' + vartostr(i1)); end; end; procedure StopScene; begin end; function Testerli(msg1in:variant; msg2in:string):variant; begin ShowMessage('Procedure Testerli msg1in: ' + vartostr(msg1in)); ShowMessage('Procedure Testerli msg2in: ' + msg2in); msg1in := 'Rueckgabe'; result := msg1in; end; end.
IF THEN ELSE - bedingte Abfrage
Die Befehle IF [Bedingung] THEN [Befehle bei Bedingung erfüllt] ELSE [Befehle bei Bedingung nicht erfüllt] führen unterschiedliche Befehle je nach Bedingung aus. Ich empfehle hier zusätzlich noch BEGIN END anzuwenden. Der Code wird damit übersichtlicher und klarer. Aufpassen auf ; - hier gelten Sonderregeln.
if ( AutoBPMjOnOff = 'Off' ) then begin AutoBPMjOnOff := 'On'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOn); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOn); end else begin AutoBPMjOnOff := 'Off'; set_panelbuttoncolor(ButtonX, ButtonY, ButtonColorOff); set_panelbuttontext(ButtonX, ButtonY, ButtonTextOff); end;
IntToStr() - Variable Integer zu String umwandeln
Der Befehl IntToStr(integer) gibt einen String zurück. Im Beispiel wird der letzte MIDI-ASCII-Wert (abgelegt als Integer) umgewandelt nach String da ShowMessage() nur String aktzeptiert.
procedure StartScene; var MIDI_last_MSG, MIDI_last_Data1, MIDI_last_Data2, MIDI_last_in:variant; begin MIDI_last_in := get_lastmidi(); MIDI_last_MSG := Ord(Copy(MIDI_last_in,1,1)); MIDI_last_Data1 := Ord(Copy(MIDI_last_in,2,1)); MIDI_last_Data2 := Ord(Copy(MIDI_last_in,3,1)); ShowMessage( Ord(IntToStr()MIDI_last_MSG)) + '-' + Ord(IntToStr()MIDI_last_Data1)) + '-' + Ord(IntToStr()MIDI_last_Data2))); end;
ORD() - ASCII ermitteln
Der Befehl ORD(string) gibt ein Integer zurück der dem ASCII Code des Strings entspricht. Im Beispiel wird der letzte MIDI Input (String mit drei Zeichen) zerrlegt und das Zeichen nach ASCII umgewandelt - was dem MIDI-Wert entspricht.
procedure StartScene; var MIDI_last_MSG, MIDI_last_Data1, MIDI_last_Data2, MIDI_last_in:variant; begin MIDI_last_in := get_lastmidi(); MIDI_last_MSG := Ord(Copy(MIDI_last_in,1,1)); MIDI_last_Data1 := Ord(Copy(MIDI_last_in,2,1)); MIDI_last_Data2 := Ord(Copy(MIDI_last_in,3,1)); ShowMessage( IntToStr(MIDI_last_MSG) + '-' + IntToStr(MIDI_last_Data1) + '-' + IntToStr(MIDI_last_Data2)); end;
random () - Zufallszahl
Die Funktion random(maxWert) gibt eine pseudo Zufallszahl zurück. Der Rückgabewert liegt zwischen 0 und maxWert+1. Wird kein maxWert übergeben, so erhält man einen Rückgabewert zurück zwischen 0 und 1. Im Beipiel wird die Drehrichtung angepasst (bei gleicher Geschwindigkeit) um für Abwechslung zu sorgen. Das Gerät hat eine Typischen DMX Kanal bei dem Geschwindigkeit und Drehrichtung auf einem DMX-Kanal liegen. Langsam(links)-Schnell(links)-AUS-Schnell(rechts)-Langsam(rechts).
// Gerätewert alt ermiteln
Geraet_WertAlt:=get_channel(Geraet_ID, Geraet_Kanal);
// Berechnung des neuen Gerätewertes
Geraet_WertNeu:=(Geraet_Max-Geraet_Min)*(BPMKanal_Wert/255)+Geraet_Min;
Geraet_WertAnAus:=get_channel(Geraet_ID, 'SHUTTER');
// Drehung invertieren per Zufall
if random(100)>50 then begin
Geraet_WertNeu:=(120-Geraet_WertNeu)+135;
end;
// Wert an Gerät ausgeben
if Geraet_WertAnAus >0 then begin
set_channel(Geraet_ID, Geraet_Kanal, Geraet_WertAlt, Geraet_WertNeu, Geraet_Fadetime);
end else begin
set_channel(Geraet_ID, Geraet_Kanal, Geraet_WertAlt, 0, Geraet_Fadetime);
end;
randomize - pseudo Reihenfolge random ändern
Mit dem Befehl randomize wird die pseudo Reihenfolge des Befehls random Neupositioniert abhängig von der Tageszeit und sollte daher eine zuverlässige Methode zum Erstellen einer unvorhersehbaren Zahlenfolge bieten. Selbst wenn sie Teil einer vorgegebenen Folge ist.
Wenn also Zufallszahlen benötigt werden, empfiehlt es sich diesen Befehl an einer Stelle einzubauen der möglichst kurz nach Start von PCDimmer liegt.
randomize; // random Zahlenfolge neu nach Tageszeit positionieren
try - Fehler behandeln
Mit dem Befehl try kann man erwartete oder beabsichtigte Fehlersituationen abfangen. Im Abschnitt except dann wieder einen aktzeptablen Zustand herstell und auf den Fehler reagieren. Im Beispiel könnte der Zugriff auf das Array "ButtonFarbe[Dim1]" scheitern.
try Test := ButtonFarbe[Dim1]; except begin Dim1 := Dim1Old; break; end end;
var - Variablen Deklaration
Mit dem Befehl var werden die Viariablen deklariert. Dies muss gemacht werden. Ansonsten kommt es zu Fehlern. Die Variablen sind nur innerhalb der Szene gültig und werden vor dem eigentlichem Code definiert. Der Inhalt der Variablen wird nicht dauerhaft gespeichert. Ist somit beim nächsten Aufruf nicht mehr gesetzt. Weiterhin muss am Ende durch : getrennt der Variablentyp angegeben werden. Typisch wäre "integer", "real", "boolean" und "string". Am flexibelsten ist allerdings "variant". Dieser ändert sich je nach Verwendung automatisch. Man muss also etwas mitdenken!
Benötigt man verschiede Typen an Variablen so muss der Befehl "var" pro Typ einmal verwendet werden.
Hinweis/Warnung: Ich dachte mit dem Variablentyp "variant" hat man alle Sorgen los da dieser sich automatisch anpasst. Leider musste ich feststellen, das man Variant nicht direkt nach Integer konvertieren kann. Weiterhin hatte ich mehrere unerklärliche Fehler die gelöst wurden nach langem suchen und statt Variant z.B. Integer als Typ benutzt wurde.
procedure StartScene; var MIDI_last_MSG, MIDI_last_Data1, MIDI_last_Data2, MIDI_last_in:variant; begin MIDI_last_in := get_lastmidi(); MIDI_last_MSG := Ord(Copy(MIDI_last_in,1,1)); MIDI_last_Data1 := Ord(Copy(MIDI_last_in,2,1)); MIDI_last_Data2 := Ord(Copy(MIDI_last_in,3,1)); ShowMessage( IntToStr(MIDI_last_MSG) + '-' + IntToStr(MIDI_last_Data1) + '-' + IntToStr(MIDI_last_Data2)); end;
var array - Array Deklaration
Kurze Erklärung zum Array. Es gibt noch umfangreichere Arrays. Bitte hierzu im Internet nachschlagen.
Mit dem Befehl var array[Start..Anzahl] of Typ werden die Viariablen deklariert. Auch ein Array. In eckigen Klammer wird die erste Variablennummer und die Anzahl der Variablen übergeben. Im Beispiel: Starte mit Nummer eins und richte zwei ein. Das Array ist nur zur Laufzeit der CodeSzene und innerhalb der Szene gültig. Weiterhin muss am Ende durch : getrennt der Variablentyp angegeben werden. Typisch wäre "integer", "real", "boolean" und "string". Am flexibelsten ist allerdings "variant". Dieser ändert sich je nach Verwendung automatisch. Man muss also etwas mitdenken!
Benötigt man verschiede Typen an Variablen so muss der Befehl var array[Start..Anzahl] of Typ pro Typ einmal verwendet werden. Angesprochen werden die Variablen dann mit Variablenname[Nummer].
var ButtonColor, ColorSet, ButtonAusColor_Off, ButtonAusColor_On, ButtonEffektColor :variant; ButtonEffektColor_Off : array[1..2] of string; ButtonEffektColor_On : array[1..2] of string; begin // ########## Effekt PAR 002 starten ########## // ---------- Zentrale Definitionen, bitte anpassen ColorSet := 1; //Colorset 1 oder 2 auswählen (blau/grün bei mir) // ---------- Zentrale Definitionen, ENDE ButtonColor := get_globalvar(3); ButtonAusColor_Off := Copy(ButtonColor,1,7); ButtonAusColor_On := Copy(ButtonColor,8,7); ButtonEffektColor_Off[1] := Copy(ButtonColor,15,7); ButtonEffektColor_On[1] := Copy(ButtonColor,22,7); ButtonEffektColor_Off[2] := Copy(ButtonColor,29,7); ButtonEffektColor_On[2] := Copy(ButtonColor,36,7); set_panelbuttoncolor(1, 1, ButtonAusColor_Off); set_panelbuttoncolor(2, 1, ButtonEffektColor_Off[ColorSet]); set_panelbuttoncolor(3, 1, ButtonEffektColor_On[ColorSet]);