Object Method
Symbol:
Methods are an extension of the IEC 61131-3 standard and a means of object-oriented programming used for data encapsulation. A method contains a declaration and an implementation. However, unlike a function, a method is not an independent programming block, but is subordinate to a function block or program. A method can access all valid variables of the higher-level programming block.
You can add a method below a program or a function block. Use the Project > Add object > Method command to open the Add method dialog.
You can use interfaces to organize methods. For more information, see: Implementation of an interface
If you copy a method that is below a programming block and paste it below an interface, or move the method there, the implementation it contains is automatically removed. |
Notes on methods
- All data of a method are temporary and only valid while the method is executed (stack variables). This means that TwinCAT re-initializes all variables and function blocks, which you have declared in a method, with each call of the method.
- Like functions, methods can return a return value.
- According to the IEC 61131-3 standard, methods can have additional inputs and outputs, like normal functions. You assign the inputs and outputs when the method is called.
- From TwinCAT 3.1.4026: Inputs without an explicitly specified initial value must be assigned when the method is called. Inputs with an explicitly specified initial value can be optionally assigned or ignored when the method is called.
- Access to the function block instance or program variables is permitted in the implementation part of a method.
- Use the THIS pointer to point to your own instance.
- It is not possible to access VAR_TEMP variables of the function block in a method.
- You can declare VAR_INST variables for which no reinitialization takes place when methods are called up again (see also chapter Instance variables).
- By using the return type “REFERENCE TO <structured type>”, you can access a single element of the structured data type returned by the method directly when calling the method. For more information see section “Access to a single element of a structured return type during method/function/property call”.
- In principle, access to VAR_IN_OUT variables of a function block is possible in a method. Since this access is potentially risky, it should be used advisedly. Further information can be found in section “Access to VAR_IN_OUT variables of a function block in a method/transition”.
- Methods that are defined in an interface may only define input, output and VAR_IN_OUT variables, but they may not contain implementations.
Example:
The code in the following example causes TwinCAT to write the return value and the outputs of the method to locally declared variables.
Declaration part of method “Method1” of the function block FB_Sample:
METHOD Method1 : BOOL
VAR_INPUT
nIn1 : INT;
bIn2 : BOOL;
END_VAR
VAR_OUTPUT
fOut1 : REAL;
sOut2 : STRING;
END_VAR
// <method implementation code>
MAIN program:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
bReturnValue : BOOL;
nLocalInput1 : INT;
bLocalInput2 : BOOL;
fLocalOutput1 : REAL;
sLocalOutput2 : STRING;
END_VAR
bReturnValue := fbSample.Method1(nIn1 := nLocalInput1,
bIn2 := bLocalInput2,
fOut1 => fLocalOutput1,
sOut2 => sLocalOutput2);
Creating an object Method
- 1. Select a function block or a program in the Solution Explorer in the PLC project tree.
- 2. In the context menu select the command Add > Method...
- The dialog Add Method opens.
- 3. Enter a name and select a return type, the implementation language, and optionally an access modifier
- 4. Click on Open.
- The object is added to the PLC project tree and opens in the editor. The editor consists of the declaration editor at the top and the implementation part at the bottom.
Dialog Add method
Name | Name of the method The standard methods FB_Init and FB_Exit are offered in a selection list if they are not already inserted below the function block. If it is a derived function block, the selection list also offers all methods of the basic function block. |
Return type | Type of the value that is returned |
Implementation language | Implementation language selection list |
Access modifier
Access modifier | Regulates access to the data
In addition to these access modifiers, you can manually add the FINAL modifier to a method:
|
Abstract | : Indicates that the method has no implementation and that the implementation is provided by the derived FB. Background information on the ABSTRACT keyword can be found under ABSTRACT concept. |
Methods with a different access modifier than PUBLIC are marked with a signal symbol in the Solution Explorer in the PLC project tree.
Access modifier | Object icon | Signal symbol |
---|---|---|
PRIVATE | (Lock) | |
PROTECTED | (Star) | |
INTERNAL | (Heart) |
If you copy or move a method from a POU to an interface, TwinCAT automatically deletes the included implementations. |
Special methods for a function block
FB_init | Declarations are implicit by default. Explicit declaration are also possible. Contains initialization code for the function block, as defined in the declaration part of the function block. |
FB_reinit | Explicit declaration required. This is called when the instance of the function block was copied (like during an online change). It re-initializes the new instance module. |
FB_exit | Explicit declaration required. Call for each instance of the function block before another download or a reset or during an online change for all moved or deleted instances. |
Properties and interface properties | They each consist of a Set and/or a Get accessor method. |
Calling a method
Syntax:
<return value variable> := <POU name>.<method name>(<method input name> := <variable name> (, <further method input name> := <variable name> )* );
When you call the method, you assign transfer parameters to the input variables of the method. In doing so, observe the declaration. It is sufficient to specify the names of the input variables without considering their order in the declaration.
Sample:
The code in the following sample causes TwinCAT to write the return value and the outputs of the method to locally declared variables.
Declaration part of "Method1" of the function block FB_Sample:
METHOD Method1 : BOOL
VAR_INPUT
nIn1 : INT;
bIn2 : BOOL;
END_VAR
VAR_OUTPUT
fOut1 : REAL;
sOut2 : STRING;
END_VAR
// <method implementation code>
MAIN program:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
bReturnValue : BOOL;
nLocalInput1 : INT;
bLocalInput2 : BOOL;
fLocalOutput1 : REAL;
sLocalOutput2 : STRING;
END_VAR
bReturnValue := fbSample.Method1(nIn1 := nLocalInput1,
bIn2 := bLocalInput2,
fOut1 => fLocalOutput1,
sOut2 => sLocalOutput2);
Recursive method call
Within the implementation, a method can call itself: either directly with the help of the THIS pointer or with the help of a local variable for the assigned function block.
- Direct call of the relevant function block instance with the THIS pointer:
<Variable für Rückgabewert> := THIS^.<Methodenname> ( <Parameter> );
- Call via a local variable of the method that temporarily instantiates the affected function block:
<Variable für Rückgabewert> := <FB-Instanz>.<Methodenname> ( <Parameter> );
A compiler warning is issued for a recursive call. If the method is specified with the {attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'}
pragma, the compiler warning is suppressed.
You can find an implementation example under Attribute 'estimated-stack-usage'.
To call methods recursively, it is not sufficient to simply specify the method name. If only the method name is specified, a compiler error is output (“Program name, function or function block instance expected instead of ...”).
Access to a single element of a structured return type during method/function/property call
The following implementation can be used to directly access an individual element of the structured data type that is returned by the method/function/property when a method, function or property is called. A structured data type is, for example, a structure or a function block.
- The return type of the method/function/property is defined as "REFERENCE TO <structured type>" (instead of just "<structured type>").
- Note that with such a return type – if, for example, an FB-local instance of the structured data type is to be returned – the reference operator REF= must be used instead of the "normal" assignment operator :=.
The declarations and the sample in this section refer to the call of a property. However, they are equally transferrable to other calls that deliver return values (e.g. methods or functions).
Sample
Declaration of the structure ST_Sample (structured data type):
TYPE ST_Sample :
STRUCT
bVar : BOOL;
nVar : INT;
END_STRUCT
END_TYPE
Declaration of the function block FB_Sample:
FUNCTION_BLOCK FB_Sample
VAR
stLocal : ST_Sample;
END_VAR
Declaration of the property FB_Sample.MyProp with the return type "REFERENCE TO ST_Sample":
PROPERTY MyProp : REFERENCE TO ST_Sample
Implementation of the Get method of the property FB_Sample.MyProp:
MyProp REF= stLocal;
Implementation of the Set method of the property FB_Sample.MyProp:
stLocal := MyProp;
Calling the Get and Set methods in the main program MAIN:
PROGRAM MAIN
VAR
fbSample : FB_Sample;
nSingleGet : INT;
stGet : ST_Sample;
bSet : BOOL;
stSet : ST_Sample;
END_VAR
// Get - single member and complete structure possible
nSingleGet := fbSample.MyProp.nVar;
stGet := fbSample.MyProp;
// Set - only complete structure possible
IF bSet THEN
fbSample.MyProp REF= stSet;
bSet := FALSE;
END_IF
Through the declaration of the return type of the property MyProp as "REFERENCE TO ST_Sample" and through the use of the reference operator REF= in the Get method of this property, a single element of the returned structured data type can be accessed directly on calling the property.
VAR
fbSample : FB_Sample;
nSingleGet : INT;
END_VAR
nSingleGet := fbSample.MyProp.nVar;
If the return type were only to be declared as "ST_Sample", the structure returned by the property would first have to be assigned to a local structure instance. The individual structure elements could then be queried on the basis of the local structure instance.
VAR
fbSample : FB_Sample;
stGet : ST_Sample;
nSingleGet : INT;
END_VAR
stGet := fbSample.MyProp;
nSingleGet := stGet.nVar;
Access to VAR_IN_OUT variables of the function block in a method/transition/property
In principle, the VAR_IN_OUT variables of a function block can be accessed in a method, transition or property of the function block. Note the following for this type of access:
- If the body or an action of the function block is called from outside the FB, the compiler ensures that the VAR_IN_OUT variables of the function block are assigned with this call.
- This is not the case if a method, transition or property of the function block is called, since the VAR_IN_OUT variables of the FB cannot be assigned within a method, transition or property call. Therefore, access to the VAR_IN_OUT variables might occur by calling the method/transition/property before the VAR_IN_OUT variables are assigned to a valid reference. Since this would mean invalid access at runtime, accessing the VAR_IN_OUT variables of the FB in a method, transition or property is potentially risky.
Therefore, the following warning with ID C0371 is issued if the VAR_IN_OUT variables of the FB are accessed in a method, transition or property:
„Warning: Access to VAR_IN_OUT <Var> declared in <POU> from external context <Method/Transition/Property>”
An adequate response to this warning could be to check the VAR_IN_OUT variables within the method/transition/property before it is accessed. The operator __ISVALIDREF can be used for this check, to ascertain whether a reference refers to a valid value. If this check is enabled, it can be assumed that the user is aware of the risk that potentially exists when the VAR_IN_OUT variables of the FB are accessed in a method/transition/property. Checking the reference is regarded as adequate handling of this risk. The corresponding warning can therefore be suppressed via attribute 'warning disable'.
A sample implementation of a method is shown below.
Function block FB_Sample:
FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
bInOut : BOOL;
END_Var
Methode FB_Sample.MyMethod:
METHOD MyMethod
VAR_INPUT
END_VAR
// The warning can be disabled here as the user is aware of the risk that the reference may not be valid by checking its validity
{warning disable C0371}
// Checking the VAR_IN_OUT reference, leave the current method in case of invalid reference
IF NOT __ISVALIDREF(bInOut) THEN
RETURN;
END_IF
// Access to VAR_IN_OUT reference (only if the reference was confirmed as valid before)
bInOut := NOT bInOut;
// The warning may be restored at the end of the access area
{warning restore C0371}
See also: