Declaration of variables based on an interface

Syntax
VAR | VAR_INPUT | VAR_OUTPUT
name_1, name_2, ..., name_n : interface;
(* Additional pieces of data, such as partial addresses, are also possible for the variables. *)
END_VAR
 
TYPE
name_1: STRUCT
name_e1 : interface; (* Additional pieces of data, such as partial addresses, are also possible for the structure element. *)
...
END_STRUCT;
END_TYPE

Meaning

declaration of one or more →variables based on an →interface (a feature of the →object-oriented programming)
Such variables behave as reference variables do (see "Declaration of reference variables (incl. assignments to them)" for details). This means such variables are initialized with the value NULL (i.e., a variable based on an interface refers to nothing).

Restrictions and notes on usage

  • For variables based on an interface, the following possibilities are not provided, even if the respective section itself provides the possibility:

  • If you want to access a method of the interface via the variable, enter the name of the variable (e.g. IN1) and the name of the method (e.g. SwitchState) separated by the character .Example: IN1.SwitchState

  • Observe when you are accessing variables based on an interface that have the value NULL:
    logi.CAD 3 does not validate these ST-constructs when entered in the ST-editor but when the application is executed. In this case, the following error handling occurs:

    1. The output ENO of the embracing →POU is set to the value FALSE (or an equivalent).

    2. The remaining block code is not executed anymore.


    logi.cals recommends you to add code to your application (e.g. IF-statements) so that the usage of such variables with the content NULL is detected. At present, logi.CAD 3 does not provide any possibility to check this within the ST-code.

  • Use an assignment attempt for variables based on an interface in order to get a valid reference to a referenced instance or the result NULL.

The declaration of variables based on an interface is possible within these sections:
(Consult the respective description of the section about possibly additional possibilities for the variable.)

Section

The declaration of the variable is done as:

VAR ... END_VAR

internal variable (see "Declaration of internal variables in ST")

VAR_INPUT ... END_VAR

input variable (see "Declaration of input variables in ST")

VAR_OUTPUT ... END_VAR

output variable (see"Declaration of output variables in ST")

TYPE name_1: STRUCT ... END_STRUCT;END_TYPE

as structure element (see"Declaration of a structured data type in ST")

Deviation form IEC-standard

In logi.CAD 3 it is not possible to declare variables based on an interface within the section for →temporary variables (VAR_TEMP ... END_VAR).

Assignments to variables based on an interface

→Assignments to variables based on an interface are possible – as usual – by using this operator: :=Moreover, logi.CAD 3 supports the assignment operator "?=" (see "Assignment attempt in ST" for details).

Syntax for assignments:

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

The expression on the right side of the assignment operator ":=" may be one of the following constructs :

  • an →instance of a →function block type that is implementing the same interface or that has been derived from a base function block implementing the same interface

  • another declared variable based on the same or a derived interface

  • NULL

Examples on using interfaces and variables based on these interfaces (incl. assignments)

Example 1
INTERFACE ISwitch (* declaration of an interface with a method prototype *)
METHOD SwitchState
VAR_INPUT
STATE : BOOL;
END_VAR
END_METHOD
END_INTERFACE
INTERFACE IValve (* declaration of an interface with a method prototype *)
METHOD Open
END_METHOD
END_INTERFACE
FUNCTION_BLOCK MySwitch IMPLEMENTS ISwitch, IValve (* declaration of a function block that implements the 2 interfaces *)
VAR
switchState : BOOL;
valveOpen : BOOL;
END_VAR
METHOD PUBLIC SwitchState (* within this function block: declaration of a method of the interface *)
VAR_INPUT
STATE : BOOL;
END_VAR
switchState := STATE;
END_METHOD
METHOD PUBLIC Open (* within this function block: declaration of a method of the interface *)
valveOpen := TRUE;
END_METHOD
END_FUNCTION_BLOCK
FUNCTION_BLOCK myFB
VAR_INPUT
IN1 : ISwitch; (* declaration of a variable based on an interface *)
IN2 : IValve; (* declaration of a variable based on an interface *)
IN3 : BOOL;
END_VAR
IN1.SwitchState(STATE := IN3); (* accessing a method of an interface via the variable "IN1" *)
IF IN3 THEN
IN2.Open(); (* accessing a method of an interface via the variable "IN2" *)
END_IF;
END_FUNCTION_BLOCK
PROGRAM TestSwitches
VAR
switchVal : MySwitch; (* declaration of a function block instance *)
fbinst : myFB; (* declaration of a function block instance *)
i_Switch : ISwitch; (* declaration of a variable based on an interface *)
END_VAR
i_Switch := switchVal; (* assigning the function block instance to the variable based on an interface *)
fbinst(IN1 := i_Switch, IN2 := switchVal, IN3 := TRUE); (* calling a function block instance *)
END_PROGRAM

Compare:

  • The above assignment i_Switch := switchVal; is correct. Reason: The function block instance switchVal is assigned to the variable i_Switch that is based on the interface ISwitch. The function block MySwitch implements this interface ISwitch.

  • The assignment i_Switch := fbinst; would be highlighted as faulty. Reason: Although the function block instance fbinst is assigned to the same variable i_Switch, the function block myFB does not implement the interface ISwitch.

Example 2
INTERFACE ROOM (* declaration: interface ROOM with 2 methods *)
METHOD DAYTIME END_METHOD // called during day-time
METHOD NIGHTTIME END_METHOD // called during night-time
END_INTERFACE
 
FUNCTION_BLOCK LIGHTROOM IMPLEMENTS ROOM (* declaration: function block LIGHTROOM that implements the interface *)
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 (* declaration: function block ROOM_CTRL *)
VAR_INPUT RM : ROOM; END_VAR // interface ROOM as type of the input variable RM
VAR_EXTERNAL
Actual_TOD : TOD; END_VAR // global time definition
IF (RM = NULL) // Important: test valid reference!
THEN RETURN;
END_IF;
IF Actual_TOD >= TOD#20:15:00 OR
Actual_TOD <= TOD#06:00:00
THEN RM.NIGHTTIME(); // call method of RM
ELSE RM.DAYTIME();
END_IF;
END_FUNCTION_BLOCK
 
PROGRAM B // usage
VAR // instantiations
My_Room : LIGHTROOM; // see LIGHTROOM IMPLEMENTS ROOM
My_Room_Ctrl : ROOM_CTRL; // see ROOM_CTRL above
END_VAR
VAR_GLOBAL
Actual_TOD : TOD; END_VAR
My_Room_Ctrl(RM:= My_Room); // call of function block instance with passing the FB-instance My_Room to input RM of the interfaces ROOM
END_PROGRAM