Skip to content

Variables

Variables are declared in a variable section. A variable can be declared with

A variable declaration consists of

  • a list of variable names,
  • a : (colon), and
  • a data type, with optional variable-specific initialization.
VAR
myVar1, myVar2 : INT; // two variables with an elementary type
myTyped : MyType; // a previously user-defined type
myArray : ARRAY[1..8] OF REAL; // an inline (immediate) type
END_VAR

Each section is opened by its keyword and closed by END_VAR. Which sections are valid depends on the kind of POU (program, function, function block, …).

SectionPurpose
VARInternal variables, local to the entity.
VAR_INPUTInputs, supplied by the caller; not assigned inside the entity.
VAR_OUTPUTOutputs, produced by the entity and read by the caller.
VAR_IN_OUTIn/out parameters passed by reference; readable and writable.
VAR_TEMPTemporary variables, re-initialized on every invocation.
VAR_EXTERNALDeclares access to a VAR_GLOBAL variable defined elsewhere.
VAR_GLOBALGlobal variables available throughout the project.
VAR_ACCESSAccess paths binding variables to external/HMI data (configuration).
VAR_CONFIGPer-instance initial values assigned in the configuration.
FUNCTION_BLOCK Mixer
VAR_INPUT
setpoint : REAL;
END_VAR
VAR_OUTPUT
actual : REAL;
END_VAR
VAR_IN_OUT
tank : TankState; // passed by reference, modified in place
END_VAR
VAR
pid : PIDController; // internal instance, keeps state between cycles
END_VAR
VAR_TEMP
error : REAL; // recomputed each call
END_VAR
END_FUNCTION_BLOCK

Qualifiers placed after the section keyword change how the declared variables behave.

QualifierApplies toMeaning
CONSTANTVAR, VAR_INPUT, VAR_GLOBAL, VAR_EXTERNALRead-only; the value cannot be assigned after initialization.
RETAINVAR, VAR_GLOBALValue is retained across a warm restart.
NON_RETAINVAR, VAR_GLOBALValue is explicitly not retained; re-initialized on restart.
VAR CONSTANT
PI : REAL := 3.14159;
END_VAR
VAR RETAIN
cycleCount : DINT; // survives a warm restart
END_VAR

A Boolean variable can be declared as an edge-triggered flag with R_EDGE (rising edge) or F_EDGE (falling edge). The variable becomes TRUE for one cycle on the corresponding transition of its input.

VAR_INPUT
startBtn : BOOL R_EDGE; // rising-edge input
stopBtn : BOOL F_EDGE; // falling-edge input
END_VAR

A variable can be mapped to a directly-represented (physical or memory) address with AT, followed by a % location.

VAR
sensor AT %IX0.0 : BOOL; // input bit
holding AT %MW100 : WORD; // memory word
END_VAR

The location prefix selects the area — I (input), Q (output), M (memory) — and the size prefix selects the width — X (bit), B (byte), W (word), D (double word), L (long word).

The initial value of a variable is determined, in order of precedence:

  1. The user-defined value given in the VAR declaration with := (highest precedence).
  2. The user-defined value given in the TYPE declaration of its data type with :=.
  3. NULL, if the variable is a reference.
  4. The default initial value of the underlying elementary type (lowest precedence).
VAR
a : INT; // 0 (elementary default)
b : INT := 5; // 5 (declaration initializer)
c : Counter; // uses the TYPE's := default, if any
r : REF_TO Motor; // NULL
END_VAR