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:

    Neuron Power Engineer 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.

    Neuronrecommends 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, Neuron Power Engineer 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")
This is not possible, if a →class implements the interface.

VAR_OUTPUT ... END_VAR

output variable (see"Declaration of output variables in ST")
This is not possible, if a →class implements the interface.

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 Neuron 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, Neuron Power Engineer 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 := class_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 or of a →class that is implementing the same interface or that has been derived from a base function block or class 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