Deklaration von Variablen, die auf einem Interface basieren

Syntax
VAR | VAR_INPUT | VAR_OUTPUT
name_1, name_2, ..., name_n : interface;
END_VAR
 
TYPE
name_1: STRUCT
name_e1 : interface;
...
END_STRUCT; 
END_TYPE

Bedeutung

Deklaration einer oder mehrerer →Variablen, die auf einem →Interface basieren ( ein Feature der →objektorientierte Programmierung)
Solche Variablen verhalten sich wie Referenz-Variablen (siehe "Deklaration von Referenz-Variablen (inkl. Zuweisungen darauf)" für Details). Das bedeutet, solche Variablen werden mit dem Wert NULL initialisiert (d.h., eine Variable, die auf einem Interface basiert, verweist auf nichts).

Einschränkungen und Hinweise zur Verwendung

  • Für Variablen, die auf einem Interface basieren, sind die folgenden Möglichkeiten nicht zulässig, auch wenn der jeweilige Abschnitt selbst diese Möglichkeit unterstützt:

  • Für den Zugriff auf eine Methode des Interfaces über die Variable geben Sie den Namen der Variable (z.B. IN1) und den Namen der Methode (z.B. SwitchState) durch das Zeichen . voneinander getrennt ein.
    Beispiel: IN1.SwitchState

  • Beachten Sie beim Zugriff auf Variablen basierend auf einem Interface mit dem Wert NULL:
    logi.CAD 3 prüft diese ST-Konstrukte nicht bei der Eingabe im ST-Editor, sondern erst beim Ausführen der Anwendung. Dabei erfolgt diese Fehlerbehandlung:

    1. Der Ausgang ENO der umfassenden →POE wid auf den Wert FALSE (bzw. einer Entsprechung) gesetzt.

    2. Der restliche Baustein-Code wird nicht mehr ausgeführt.


    logi.cals empfiehlt Ihnen, Code in Ihrer Anwendung (z.B. IF-Anweisungen) einzufügen, um die Verwendung von solchen Variablen mit dem Inhalt NULL zu erkennen. Derzeit bietet logi.CAD 3 jedoch noch keine Möglichkeit, um dies im ST-Code zu prüfen.

  • Mit Hilfe eines Zuweisungsversuchs erhalten Sie für Variablen basierend auf einem Interface entweder eine gültige Referenz auf die referenzierte Instanz oder das Ergebnis NULL.

Die Deklaration von Variablen basierend auf einem Interface ist innerhalb dieser Abschnitte möglich:

Abschnitt

Die Deklaration der Variable erfolgt als:

VAR ... END_VAR

interne Variable (siehe "Deklaration von internen Variablen")

VAR_INPUT ... END_VAR

Eingangsvariable (siehe "Deklaration von Eingangsvariablen in ST")

VAR_OUTPUT ... END_VAR

Ausgangsvariable (siehe "Deklaration von Ausgangsvariablen in ST")

TYPE
name_1: STRUCT
...
END_STRUCT;
END_TYPE

als Strukturelement (siehe "Deklaration eines strukturierten Datentyps in ST")


Abweichung zur IEC-Norm

In logi.CAD 3 ist es nicht möglich, Variablen basierend auf einem Interface im Abschnitt für →temporäre Variablen (VAR_TEMP ... END_VAR) zu deklarieren.

Zuweisungen auf Variablen basierend auf einem Interface

→Zuweisungen auf Variablen basierend auf einem Interface sind – wie üblich – mit dem Zuweisungsoperators " :=" möglich. Zusätzlich unterstützt logi.CAD 3 auch den Operator "?=" (siehe "Zuweisungsversuch in ST" für Details).

Syntax für Zuweisungen:

Syntax
interface_variable_1 := function_block_instance_1;
interface_variable_1 := interface_variable_2;
interface_variable_1 := NULL;

Der Ausdruck auf der rechten Seite des Zuweisungsoperators ":=" darf eines der folgenden Konstrukte sein:

  • eine →Instanz eines →Funktionsbaustein-Typs, der das gleiche Interface implementiert oder der von einem Basis-Funktionsbaustein abgeleitet wurde und dieser Basis-Funktionsbaustein das gleiche Interface implementiert

  • eine andere deklarierte Variable basierend auf dem gleichen oder einem abgeleiteten Interface

  • NULL

Beispiele für Verwendung von Interfaces und Variablen basierend auf diesen Interfaces (inkl. Zuweisungen)

Beispiel 1
INTERFACE ISwitch (* Deklaration eines Interfaces mit einem Methoden-Prototyp *)
METHOD SwitchState
VAR_INPUT
STATE : BOOL;
END_VAR
END_METHOD
END_INTERFACE
INTERFACE IValve (* Deklaration eines Interfaces mit einem Methoden-Prototyp *)
METHOD Open
END_METHOD
END_INTERFACE
FUNCTION_BLOCK MySwitch IMPLEMENTS ISwitch, IValve (* Deklaration eines Funktionsbausteins, der die 2 Interfaces implementiert *)
VAR
switchState : BOOL;
valveOpen : BOOL;
END_VAR
METHOD PUBLIC SwitchState (* im Funktionsbaustein: Deklaration einer Methode des Interfaces *)
VAR_INPUT
STATE : BOOL;
END_VAR
switchState := STATE;
END_METHOD
METHOD PUBLIC Open (* im Funktionsbaustein: Deklaration einer Methode des Interfaces *)
valveOpen := TRUE;
END_METHOD
END_FUNCTION_BLOCK
FUNCTION_BLOCK myFB
VAR_INPUT
IN1 : ISwitch; (* Deklaration einer Variable basierend auf einem Interface *)
IN2 : IValve; (* Deklaration einer Variable basierend auf einem Interface *)
IN3 : BOOL;
END_VAR
IN1.SwitchState(STATE := IN3); (* Zugriff auf eine Methode eines Interfaces über die Variable "IN1" *)
IF IN3 THEN
IN2.Open(); (* Zugriff auf eine Methode eines Interfaces über die Variable "IN2" *)
END_IF;
END_FUNCTION_BLOCK
PROGRAM TestSwitches
VAR
switchVal : MySwitch; (* Deklaration einer Funktionsbaustein-Instanz *)
fbinst : myFB; (* Deklaration einer Funktionsbaustein-Instanz *)
i_Switch : ISwitch; (* Deklaration einer Variable basierend auf einem Interface *)
END_VAR
i_Switch := switchVal; (* Zuweisung der Funktionsbaustein-Instanz auf die Variable basierend auf einem Interface *)
fbinst(IN1 := i_Switch, IN2 := switchVal, IN3 := TRUE); (* Aufruf der Funktionsbaustein-Instanz *)
END_PROGRAM

Im Vergleich:

  • Die obige Zuweisung i_Switch := switchVal; ist korrekt. Grund: Die Funktionsbaustein-Instanz switchVal wird der Variable i_Switch zugewiesen und diese Variable basiert auf dem Interface ISwitch. Der Funktionsbaustein MySwitch implementiert dieses Interface ISwitch.

  • Die Zuweisung i_Switch := fbinst; würde jedoch als fehlerhaft gekennzeichnet werden. Grund: Die Funktionsbaustein-Instanz fbinst wird zwar der gleichen Variable i_Switch zugewiesen. Der Funktionsbaustein myFB implementiert das Interface ISwitch jedoch nicht.

Beispiel 2
INTERFACE ROOM (* Deklaration: Interface ROOM mit 2 Methoden *)
METHOD DAYTIME END_METHOD // während des Tages aufgerufen
METHOD NIGHTTIME END_METHOD // während der Nacht aufgerufen
END_INTERFACE
 
FUNCTION_BLOCK LIGHTROOM IMPLEMENTS ROOM (* Deklaration: Funktionsbaustein LIGHTROOM, der das Interface implementiert *)
VAR
LIGHT : BOOL;
END_VAR
METHOD PUBLIC DAYTIME
LIGHT:= FALSE;
END_METHOD
METHOD PUBLIC NIGHTTIME
LIGHT:= TRUE;
END_METHOD
END_FUNCTION_BLOCK
 
FUNCTION_BLOCK ROOM_CTRL (* Deklaration: Funktionsbaustein ROOM_CTRL *)
VAR_INPUT RM : ROOM; END_VAR // Interface ROOM als Typ der Eingangsvariable RM
VAR_EXTERNAL
Actual_TOD : TOD; END_VAR // Globale Zeit-Definition
IF (RM = NULL) // Wichtig: gültige Referenz prüfen!
THEN RETURN;
END_IF;
IF Actual_TOD >= TOD#20:15:00 OR
Actual_TOD <= TOD#06:00:00
THEN RM.NIGHTTIME(); // Methode von RM aufrufen
ELSE RM.DAYTIME();
END_IF;
END_FUNCTION_BLOCK
 
PROGRAM B // usage
VAR // Instanzierungen
My_Room : LIGHTROOM; // Siehe LIGHTROOM IMPLEMENTS ROOM
My_Room_Ctrl : ROOM_CTRL; // Siehe ROOM_CTRL oben
END_VAR
VAR_GLOBAL
Actual_TOD : TOD; END_VAR
My_Room_Ctrl(RM:= My_Room); // Aufruf der Funktionsbaustein-Instanz, wobei die FB-Instanz My_Room dem Eingang RM des Interfaces ROOM übergeben wird
END_PROGRAM