Deklaration von Variablen, die auf einem Interface basieren

Syntax
VAR | VAR_INPUT | VAR_OUTPUT
  name_1, name_2, ..., name_n : interface;
(* Zusätzliche Daten, wie partielle Adressen, sind ebenfalls für die Variablen möglich. *)
END_VAR

TYPE
  name_1: STRUCT
    name_e1 : interface;  (* Zusätzliche Daten, wie partielle Adressen, sind ebenfalls für die Strukturelemente möglich. *)
    ...
  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:
(Informieren Sie sich in der jeweiligen Beschreibung zum Abschnitt über evtl. zusätzliche Möglichkeiten für die Variable.)

AbschnittDie Deklaration der Variable erfolgt als:
VAR ... END_VARinterne Variable (siehe "Deklaration von internen Variablen")
VAR_INPUT ... END_VAREingangsvariable (siehe "Deklaration von Eingangsvariablen in ST")
VAR_OUTPUT ... END_VARAusgangsvariable (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