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>;
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. The VAR_IN_OUT variable can be read and written.

Use:

Input/Output Variables - VAR_IN_OUT, VAR_IN_OUT CONSTANT 1:

Transferring strings to VAR_IN_OUT CONSTANT

If a string is transferred as a variable or as a constant to a formal VAR_IN_OUT CONSTANT variable, the string length can vary. For more information, see "Transfer variable VAR_IN_OUT CONSTANT".

Input/Output Variables - VAR_IN_OUT, VAR_IN_OUT CONSTANT 2:

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.

Input/Output Variables - VAR_IN_OUT, VAR_IN_OUT CONSTANT 3:

Similarity of VAR_IN_OUT to REFERENCE TO

VAR_IN_OUT variables are very similar to references when they are used in interfaces of functions, methods and function modules. It is recommended to prefer VAR_IN_OUT variables if possible.

Advantages of VAR_IN_OUT compared to REFERENCE TO :

- VAR_IN_OUT variables must be assigned in function, method and function block calls.
This means they are always valid.

A reference can be invalid (0).

- Stack variables can also be assigned to a VAR_IN_OUT variable.

- VAR_IN_OUT CONSTANT also offers the option of assignment with read-only access

Sample:

Function block FB_Sample

FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
    bInOut    : BOOL;
END_VAR

MAIN program:

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 pass-through 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:

Input/Output Variables - VAR_IN_OUT, VAR_IN_OUT CONSTANT 4:

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);

MAIN program:

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);