Input/Output Variables - VAR_IN_OUT, VAR_IN_OUT CONSTANT
A VAR_IN_OUT variable is an input and output variable that is part of a function block interface and serves as a formal pass-through parameter.
The VAR_IN_OUT variables of a function block must be assigned when the function block is called.
Syntax:
<keyword> <POU name>
VAR_IN_OUT
<variable name> : <data type> ( := <initialization value> )? ;
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG
An input and output variable can be declared in the programming blocks PRG, FUNCTION_BLOCK, METHOD or FUNCTION in the declaration section VAR_IN_OUT. A constant of the declared data type can optionally be assigned as the initialization value. The VAR_IN_OUT variable can be read and written.
Use:
- Call: When the programming block is called, the formal VAR_IN_OUT variable receives the actual variable (referred to as pass-through variable) as an argument. No copy is created at runtime during the parameter passing, but the formal variable receives a reference to the actual variable transferred from outside. The internal value of the referential variables is a memory address to the actual value (transfer as pointer, call by reference). It is not possible to directly specify a constant (literal), a constant variable or a bit variable as an argument.
- Read/write access within the programming block: Any write access to the variable within the programming block has an effect on the transferred variable. When the programming block is exited, any changes made are thus retained. This means that a programming block uses its VAR_IN_OUT variables in the same way as the calling programming block uses its variables. Read access is always allowed.
- Read/write access from outside: VAR_IN_OUT variables cannot be read or written directly from outside via <function block instance name>.<variable name>. This only works for VAR_INPUT and VAR_OUTPUT variables.
- Transferring string variables: If a string variable is transferred as an argument, the actual variable and the formal variable should have the same length. Otherwise the transferred string can be manipulated unintentionally. This problem does not occur with VAR_OUTPUT CONSTANT parameters.
- Transferring bit variables: A bit variable cannot be transferred directly to a VAR_IN_OUT variable but requires an intermediate variable.
- Transfer of properties: not allowed.
Transferring strings to VAR_IN_OUT CONSTANT If a character string is transferred as a variable or as a constant to a formal VAR_IN_OUT CONSTANT variable, the string length can vary. At the most, however, the string length of the VAR_IN_OUT CONSTANT variable will be processed. Further information can be found at the bottom of this page. |
Transfer of properties not possible No property can be transferred to a VAR_IN_OUT or VAR_IN_OUT CONSTANT variable. Exception: An assignment to VAR_IN_OUT (CONSTANT) is possible if the property has the return type REFERENCE. Note, however, that the property may only return an address via REFERENCE that is valid beyond the property call. This would not be the case, for example, if the property returned the reference to a temporary variable. |
Sample:
Function block FB_Sample
FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
bInOut : BOOL;
END_VAR
Program MAIN:
VAR
bTest : BOOL;
fbSample : FB_Sample;
END_VAR
fbSample(bInOut := bTest); // OK
fbSample(); // NOK: not possible as the VAR_IN_OUT variable is not assigned in this FB call
fbSample.bInOut := bTest; // NOK: direct access to VAR_IN_OUT variable from the outside not possible
Sample of a workaround for assigning a bit variable to a VAR_IN_OUT input:
Declaration of the bit variables (bBit0):
VAR_GLOBAL
bBit0 AT %MX0.1 : BOOL;
bTemp : BOOL;
END_VAR
Function block with VAR_IN_OUT input bInOut:
FUNCTION_BLOCK FB_Test
VAR_INPUT
bIn : BOOL;
END_VAR
VAR_IN_OUT
bInOut : BOOL;
END_VAR
IF bIn THEN
bInOut := TRUE;
END_IF
Program that calls the function block. Direct assignment of the bit variable to the VAR_IN_OUT input (error) and assignment using an intermediate variable (workaround):
PROGRAM MAIN
VAR
bIn : BOOL;
fbTest1 : FB_Test;
fbTest2 : FB_Test;
END_VAR
// Error C0201: Type 'BIT' doesn't correspond to the type 'BOOL' of VAR_IN_OUT 'bInOut'
fbTest1(bIn := bIn, bInOut := bBit0);
// Workaround
//bTemp := bBit0;
//fbTest2(bIn := bIn, bInOut := bTemp);
//bBit0 := bTemp;
Transfer variable VAR_IN_OUT CONSTANT
A VAR_IN_OUT CONSTANT variable serves as a constant transfer parameter that can be read but not written to.
Syntax:
<keyword> <POU name>
VAR_IN_OUT CONSTANT
<variable name> : <data type>; // formal parameter
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG
VAR_IN_OUT CONSTANT variables are declared without assigning an initialization value.
Use:
- All data types are allowed.
- Write access to the VAR_IN_OUT CONSTANT variable is not permitted.
- Transfer of properties is not permitted.
- If the VAR_IN_OUT CONSTANT variable is of type STRING/WSTRING, a variable, a constant variable, or a constant (literal) can be transferred when the programming block is called. There are no restrictions on the string length of the transferred variable/constant, and the length does not depend on the string length of the VAR_IN_OUT CONSTANT variable. Note that at the most, the string length of the VAR_IN_OUT CONSTANT variable will be processed.
- If the VAR_IN_OUT CONSTANT variable is not of type STRING/WSTRING, a variable can be transferred when the programming block is called. A constant variable can be transferred if the compiler option Replace constants is disabled in the Compile category of the PLC project properties.
If the compiler option Replace constants is enabled in the Compile category of the PLC project properties, the parameter transfer of a constant with a basic data type other than STRING or a constant variable with a basic data type other than STRING generates a compiler error. |
Sample:
In the code, strings are transferred to the F_Manipulate function via various VAR_IN_OUT variables. A compiler error is issued if a literal is transferred to a VAR_IN_OUT variable. Correct code is generated when a literal is transferred to a VAR_IN_OUT CONSTANT variable and when string variables are transferred.
It should also be noted that it is not possible to transfer a STRING variable that is too short to a VAR_IN_OUT variable (compiler error), although this is possible when transferring to a VAR_IN_OUT CONSTANT variable.
Function F_Manipulate:
FUNCTION F_Manipulate : BOOL
VAR_IN_OUT
sReadWrite : STRING(16); (* Can be read or written here in POU *)
nReadWrite : DWORD; (* Can be read or written here in POU *)
END_VAR
VAR_IN_OUT CONSTANT
cReadOnly : STRING(16); (* Constant string variable can only be read here in POU *)
END_VAR
sReadWrite := 'String_from_POU';
nReadWrite := STRING_TO_DWORD(cReadOnly);
Program MAIN:
PROGRAM MAIN
VAR
sVar10 : STRING(10) := '1234567890';
sVar16 : STRING(16) := '1234567890123456';
sVar20 : STRING(20) := '12345678901234567890';
nVar : DWORD;
END_VAR
// The following line of code causes the compiler error:
// VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate' needs variable with write access as input.
F_Manipulate(sReadWrite := '1234567890123456', cReadOnly := '1234567890123456', nReadWrite := nVar);
// The following line of code causes the compiler error:
// String variable 'sVar10' too short for VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate'
F_Manipulate(sReadWrite := sVar10, cReadOnly := sVar10, nReadWrite := nVar);
// Correct code
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890123456', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '12345678901234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar10, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar16, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar20, cReadOnly := sVar20, nReadWrite := nVar);