Einführung für Programmierer
Auch wenn der Syntax des Math-Moduls viele Eigenschaften aufweist, die einer Programmiersprache ähneln, ist es wichtig im Kopf zu behalten, dass das Math-Modul keine Programmiersprache ist.
Es handelt sich lediglich um eine Formelsammlung, die mit jeder Iteration des Moduls Formel für Formel ausgewertet wird. Dabei steht der Zeitbezug der einzelnen Signale zueinander im Fokus. Es darf niemals die Situation geben, dass ein Ergebniswert zu einem bestimmten Zeitpunkt nicht mehr definiert ist. Deshalb funktionieren bestimmte Konstrukte nicht, wie z.B.
if (someCondition)
y = 2 * x;
Wie sollte y bestimmt werden, wenn die Bedingung nicht erfüllt ist?
Dementsprechend werden Sie evtl. einige Programmiersprachfunktionen vermissen - wohl am auffälligsten ist, dass es keine Kontrollfluss-Konstrukte gibt.
Ein paar Beispiele, für Funktionen, mit denen eine Art bedingte Ausführung erzielt werden kann, finden Sie hier:
Bedingte Ausführung
Ternary Operator ?
Das Feature, dass klassischen Flow-Control Features wohl noch am meisten ähnelt ist der Ternary Operator, der im Math-Modul so, wie in gängigen Programmiersprachen funktioniert.
Beispiel
Ventil = Temperatur > 25.0 ? 20.0 : 80.0;
In Programmiersprache
Ventil = Temperatur > 25.0 ? 20.0 : 80.0;
// oder
if (Temperatur > 25.0)
Ventil = 20.0;
else
Ventil = 80.0;
Bei Verwendung des Ternary Operator muss darauf geachtet werden, nicht folgende fehleranfällige Konstrukte zu schreiben:
Ergebnis = Messwert != 0.0 ? Maximum / Messwert : -1.0;
Dies kann zu einer Division durch Null führen.
Stattdessen:
Ergebnis = Maximum / nonZero(Messwert);
Select Funktion
Um aus einer Menge verfügbarer Werte einen spezifischen auszuwählen, kann die Funktion select()
verwendet werden.
Beispiel
Auswahl = select(Index, Wert0, Wert1, Wert2, Wert3);
In Programmiersprache
switch(index)
{
case 0: Auswahl = Wert0; break;
case 1: Auswahl = Wert1; break;
case 2: Auswahl = Wert2; break;
case 3: Auswahl = Wert3; break;
default: Auswahl = false;
}
Prioritäts-Encoder
Um, basierend auf einer Menge an Bedingungen einen Wert auszuwählen, kann die Funktion prioEnc()
verwendet werden.
Beispiel
Status = prioEnc(Bedingung0, Bedingung1, Bedingung2, Bedingung3, {none: 1000, map: [10,20,30,40]});
In Programmiersprache
if (Bedingung0)
Status = map[0]; // = 10
else if(Bedingung1)
Status = map[1]; // = 20
else if (Bedingung2)
Status = map[2]; // = 30
else if (Bedingung3)
Status = map[3]; // = 40
else
Status = none; // = 1000
Auch hier gibt es über die Parametrierung der Funktion weitere Optionen, z.B. das Erkennen von Flanken als Bedingung oder das Halten und Weiterführen der letzten gesetzten Bedingung, wenn keine andere gesetzt ist.
Wertebereichbegrenzung
Um einen Messwert auf einen bestimmten Wertebereich zu beschränken, kann die Funktion range()
verwendet werden.
Beispiel
Begrenzt = range(Messwert, [-10.0, 10.0]);
In Programmiersprache
if (Messwert < -10.0)
Begrenzt = -10.0;
else if (Messwert > 10.0)
Begrenzt = 10.0;
else
Begrenzt = Messwert;
Alternativ können auch beliebige Werte spezifiziert werden, die ausgegeben werden sollen, falls die untere bzw. obere Grenze erreicht wurde.
Beispiel
Begrenzt = range(Messwert, [-10.0, 10.0], {lower: -99, upper: 99});
In Programmiersprache
if (Messwert < -10.0)
Begrenzt = lower; // = -99;
else if (Messwert > 10.0)
Begrenzt = upper; // = 99;
else
Begrenzt = Messwert;
Werte zwischenspeichern
Um Werte zwischen Iterationen des Math-Moduls zu speichern, können sog. FlipFlops verwendet werden.
rsFF
Um einen booleschen Wert zu speichern, kann die Funktion rsFF()
verwendet werden.
Beispiel
Zustand = rsFF(BedingungReset, BedingungSet);
In Programmiersprache
if (BedingungReset)
Zustand = false;
else if (BedingungSet)
Zustand = true;
else
Zustand = letzter Zustand;
dLatch
Um einen Wert eines beliebigen Datentyps zu speichern, kann die Funktion dLatch()
verwendet werden.
Beispiel
Merker = dLatch(BedingungHold, Messwert);
In Programmiersprache:
if (BedingungHold)
Merker = letzter Merker;
else
Merker = Messwert;