Declaration Editor

The declaration editor is used to declare variables of POUs and global variables, for data type declarations, and in the Watch and Recipe Manager. It gives access to the usual Windows functions, and even those of the IntelliMouse can be used if the corresponding driver is installed.
In Overwrite mode, 'OV' is shown in black on the status bar; switching between Overwrite and Insert modes can be accomplished with the <Ins> key. The declaration of variables is supported by syntax coloring.

The most important commands are found in the context menu (right mouse button).

Declaration Part

All variables to be used only in this POU are declared in the declaration part of the POU. These can include: input variables, output variables , in-put/output variables, local variables, retain variables, and constants. The declaration syntax is based on the IEC1131-3 standard. An example of a correct declaration of variables in TwinCAT PLC Control-Editor:

Declaration Editor 1:
Declarationeditor

Input Variable

Between the key words VAR_INPUT and END_VAR, all variables are declared that serve as input variables for a POU. That means that at the call position, the value of the variables can be given along with a call.

Example:

VAR_INPUT 
    in1:INT; (* 1. Inputvariable*)
END_VAR

Output Variable

Between the key words VAR_OUTPUT and END_VAR, all variables are declared that serve as output variables of a POU. That means that these values are carried back to the POU making the call. There they can be answered and used further.

Example:

VAR_OUTPUT 
    out1:INT; (* 1. Outputvariable*)
END_VAR

Input and Output Variable

Between the key words VAR_IN_OUT and END_VAR, all variables are declared that serve as input and output variables for a POU.

With this variable, the value of the transferred variable is changed ("transferred as a pointer", Call-by-Reference). That means that the input value for such variables cannot be a constant. For this reason, even the VAR_IN_OUT variables of a function block can not be read or written directly from outside via <functionblockinstance><in/outputvariable>.

Example:

VAR_IN_OUT 
    inout1:INT; (* 1. Input/Outputvariable *)
END_VAR

Local Variables

Between the keywords VAR and END_VAR, all of the local variables of a POU are declared. These have no external connection; in other words, they can not be manipulated from the outside.

Example:

VAR 
    loc1:INT; (* 1. Local Variable*)
END_VAR

Remanent Variables

Remanent variables can retain their value throughout the usual program run period. These include Retain variables and Persistent variables.

All other variables are newly initialized, either with their initialized values or with the standard initializations.

Example:

VAR RETAIN 
    rem1:INT; (* Retain Variable*)
END_VAR
Declaration Editor 2:

If a local variable in a program is declared as RETAIN, exactly this variable is stored in the retain area (like a global retain variable).

If a local variable in a function block is declared as RETAIN, the complete instance of this function block is stored in the retain area (all data of the function block), but only the declared retain variable is treated as such.

If a local variable in a function is declared as RETAIN, this has no effect. The variable is not stored in the retain area.

Persistent variables

In addition to the remanent variables specified with RETAIN, there is another class of remanent variables. These variables are saved with their instance path and symbol name. The generation of symbols must be selected for this. While the variables saved with RETAIN are no longer available after a "Rebuild all" of the PLC program and subsequent cold start, persistent variables remain. With a reset of the PLC also RETAIN variables are reinitialized, persistent variables can only be initialized with a overall reset. The persistent variables are saved to a file when the TwinCAT system is shut down and are pre-initialized again with their saved values when the system is restarted.

Sample:

VAR PERSISTENT 
    Rem2:INT; (* Persistente Variable*)
END_VAR
Declaration Editor 3:

In order to check the correctness of the PERSISTENT and RETAIN variables, the system variables contain a byte, bootDataFlags, in the SYSTEMINFO structure. This byte indicates the state of the boot data after loading. The upper four bits indicate the state of the persistent data, while the lower four bits indicate the state of the retain data. In order to be able to use this information, the "TcSystem.lib" library must be linked in.

Bit number

Description

0

RETAIN variables: LOADED (without error)

1

RETAIN variables: INVALID (the back-up copy was loaded, since no valid data was present)

2

RETAIN variables: REQUESTED (RETAIN variables should be loaded, a setting in TwinCAT System Control)

3

reserved

4

PERSISTENT variables: LOADED (without error)

5

PERSISTENT variables: INVALID (the back-up copy was loaded, since no valid data was present)

6

reserved

7

reserved

When shutting TwinCAT down the PERSISTENT and RETAIN data is written into two files on the hard disk. The path can be specified in TwinCAT System Control by means of the TwinCAT system properties (PLC tab). The standard setting is "<Drive>:\TwinCAT\Boot". The files all have a fixed name with fixed extensions:

File name

Description

TCPLC_P_x.wbp

Boot project (x = number of the run-time system)

TCPLC_R_x.wbp

RETAIN variables (x = number of the run-time system)

TCPLC_T_x.wbp

PERSISTENT variables (x = number of the run-time system)

TCPLC_R_x.wb~

Backup copy of the RETAIN variables (x = number of the run-time system)

TCPLC_T_x.wb~

Backup copy of the PERSISTENT variables (x = number of the run-time system)

If the file for the persistent and/or retain variables can not be written when shutting TwinCAT down, the standard reaction is for the backup file to be loaded. In that case bit 1 of the bootDataFlags (for the RETAIN variables) in the PLC and/or bit 5 (for the PERSISTENT variables) is set.

If the back-up file is not to be used under any conditions, a setting must be made in the NT registry. In the registry editor, under

[HKEY_LOCAL_MACHINE\SOFTWARE\Beckhoff\TwinCAT\Plc]
"ClearInvalidRetainData"=dword:00000000
"ClearInvalidPersistentData"=dword:00000000
the value of "ClearInvalidRetainData" or of "ClearInvalidPersistentData" must be set to 1. The default setting is 0.

Constants, Typed literals

Constants are identified by the key word CONSTANT. They can be declared locally or globally.

Syntax:

VAR CONSTANT 
    <Identifier>:<Type> :=
<initialization>;
END_VAR

Example:

VAR CONSTANT 
    con1:INT:=12; (* 1. Constant*)
END_VAR

You will find a listing of possible constants here in the appendix. See there also regarding the possibility of using typed constants (Typed Literals).

External Variables

Global variables which are to be imported into the POU are designated with the keyword EXTERNAL. They also appear in the Watch window of the declaration part in Online mode. If the VAR_EXTERNAL declaration does not match the global declaration in every respect, the following error message appears: "Declaration of '<var>' does not match global declaration!" If the global variable does not exist, the following error message appears: "Unkown global variable: '<var>'!"
Example:

VAR EXTERNAL 
    var_ext1:INT:=12; (* 1st external variable *) 
END_VAR

Keywords

Keywords are to be written in uppercase letters in all editors. Keywords may not be used as variables.


Variables declaration

A variables declaration has the following syntax:

<Identifier> {AT
<Address>}:<Type> {:=<initialization>}; 

The parts in the braces {} are optional.

Regarding the identifier, that is the name of a variable, it should be noted that it may not contain spaces or umlaut characters, it may not be declared in duplicate and may not be identical to any keyword. Upper/lowercase writing of variables is ignored, in other words VAR1, Var1 and var1 are not different variables. Underlines in identifiers are meaningful, e.g. A_BCD and AB_CD are interpreted as different identifiers. Multiple consecutive underlines at the beginning of an identifier or within a identifier are not allowed.

The length of the identifier, as well as the meaningful part of it, are unlimited.

All declarations of variables and data type elements can include initialization. They are brought about by the ":=" operator. For variables of elementary types, these initializations are constants. The default-initialization is 0 for all declarations.

Example:

var1:INT:=12; (* Integer variable with initial
value of 12*)

If you wish to link a variable directly to a definite address, then you must declare the variable with the keyword AT. For faster input of the declarations, use the shortcut mode. In function blocks you can also specify variables with incomplete address statements. In order for such a variable to be used in a local instance, there must be an entry for it in the variable configuration.

Pay attention to the possibility of an automatic declaration!

AT Declaration

If you wish to link a variable directly to a definite address, then you must declare the variable with the keyword AT. The advantage of such a procedure is that you can assign a meaningful name to an address, and that any necessary changes of an incoming or outgoing signal will only have to be made in one place (e.g., in the declaration). Notice that variables requiring an input cannot be accessed by writing. A further restriction is that AT declarations can only be made for local and global variables, and not for input- and output variables from POUs. (Program Organization Units).

Examples:

counter_heat7 AT %QX0.0: BOOL;
lightcabinetimpulse AT %IX7.2: BOOL;
download AT %MX2.2: BOOL;
Declaration Editor 4:

If boolean variables are assigned to a Byte, Word or DWORD address, they occupy one byte with TRUE or FALSE, not just the first bit after the offset!

'Insert' 'Declarations keywords'

You can use this command to open a list of all the keywords that can be used in the declaration part of a POU. After a keyword has been chosen and the choice has been confirmed, the word will be inserted at the present cursor position. You also receive the list, when you open the Input Assistant and choose the Declarations category.

'Insert' 'Types'

With this command you will receive a selection of the possible types for a declaration of variables. You also receive the list when you access the Input Assistant (<F2>).

The types are divided into these categories:

TwinCAT PLC Control supports all standard types of IEC61131-3. Examples for the use of the various types are found in the appendix.

Syntaxcoloring

In the text editors and in the declaration editor, you receive visual support in the implementation and declaration of variables. Errors are avoided, or discovered more quickly, because the text is displayed in color.
A comment left unclosed, thus annotating instructions, will be noticed immediately; keywords will not be accidentally misspelled, etc.

The following color highlighting will be used:

Blue

Keywords

Green

Comments

Pink

Boolean values (TRUE/FALSE)

Red

Input error (for example, invalid time constant, keyword, written in lower case,...)

Black

Variables, constants, assignment operators, ...

Shortcut Mode

The declaration editor for TwinCAT PLC Control allows you to use the shortcut mode. This mode is activated when you end a line with <Ctrl><Enter>

The following shortcuts are supported:

In this context, the following will apply:

B or BOOL

gives the result BOOL

I or INT

gives the result INT

R or REAL

gives the result REAL

S or STRING

gives the result STRING

If no type has been established through these rules, then the type is BOOL and the last identifier will not be used as a type (Example 1.). Every constant, depending on the type of declaration, will turn into an initialization or a string (Examples 2. and 3.). An address (as in %MD12) is extended around the AT... attribute (Example 4.). A text after a semicolon (;) becomes a comment (Example 4.). All other characters in the line are ignored (e.g., the exclamation point in Example 5.).

Examples:

Short Description

Declaration

A

A: BOOL;

A B I 2

A, B: INT := 2;

ST S 2; A String

ST: STRING(2); (* A String *)

X %MD12 R 5; Real Number

X AT %MD12: REAL := 5.0;(* Real Number *)

B !

B: BOOL;

Autodeclaration

If the Autodeclaration of the options dialog box , then a dialog box will appear in all editors after the input of a variable that has not yet been declared. With the help of this dialog box, the variable can now be declared.

Declaration Editor 5:

Dialog to declare variables

With the help of the Class combobox, select whether you are dealing with a local variable (VAR), input variable( (VAR_INPUT), output variable (VAR_OUTPUT), input/output variable (VAR_IN_OUT), or a global variable (VAR_GLOBAL). With the CONSTANT and RETAIN options, you can define whether you are dealing with a constant or a retain variable.

The variable name you entered in the editor has been entered in the Name field, BOOL has been placed in the Type field.
The button... opens the Input Assistant dialog which allows you to select from all possible data types.
If ARRAY is chosen as the variable type, the dialog for entering array boundaries appears.

Declaration Editor 6:

Declaration editor for arrays

For each of the three possible dimensions (Dim.), array boundaries can be entered under Start and End by clicking with the mouse on the corresponding field to open an editing space. The array data type is entered in the Type field. In doing this, the button... can be used to call up an input assistant dialog.

Upon leaving the array boundaries dialog via the OK button, variable declarations in IEC format are set up based on the entries in the Type field in the dialog. Example: ARRAY [1..5, 1..3] OF INT

In the field Initial value, you may enter the initial value of the variable being declared. If this is an array or a valid structure, you can open a special initialization dialog via the button or <F2>, or open the input assistant dialog for other variable types.
In the initialization dialog for an array you are presented a list of array elements; a mouse click on the space following „:=“opens an editing field for entering the initial value of an element.

In the initialization dialog for a structure, individual components are displayed in a tree structure. The type and default initial value appear in brackets after the variable name; each is followed by „:=“. A mouse click on the field following „:=“ opens an editing field in which you can enter the desired initial value. If the component is an array, then the display of individual fields in the array can be expanded by a mouse click on the plus sign before the array name and the fields can be edited with initial values.

After leaving the initialization dialog with OK, the initialization of the array or the structure appears in the field Initial value of the declaration dialog in IEC format. Example: x:=5,field:=2,3,struct2:=(a:=2,b:=3)

In the Address field, you can bind the variable being declared to an IEC address (AT declaration).
If applicable, enter a Comment. The comment can be formatted with line breaks by using the key combination <Ctrl> + <Enter>. By pressing OK, the declaration dialog is closed and the variable is entered in the corresponding declaration editor in accordance to the IEC syntax.

Declaration Editor 7:

The dialog box for variable declaration you also get by the command 'Edit' 'Declare Variable' (see Chapter Editing Functions). If the cursor is resting on a variable in Online mode, the Autodeclare window can be opened with <Shift><F2> with the current variable-related settings displayed.

Line Numbers in the Declaration Editor

In offline mode, a simple click on a special line number will mark the entire text line. In the online mode, a single click on a specific line number will open up or close the variable in this line, in case a structural variable is involved.

Name

Input the identifier of the variable.

Address

Input the address of the variable (AT declaration)

Type

Input the type of the variable. (Input the function block when instantiating a function block)

Initial

Enter a possible initialization of the variable (corresponding to the ":= " assignment operator)

Comment

Enter a comment here.

Both of the display types of the declaration editor can be changed without causing any problems. In the online mode, there are no differences for the display.

Declaration Editor 8:

Declaration Editor as a Table

'Insert' 'New Declaration '

With this command you bring a new variable into the declaration table of the declaration editor. If the present cursor position is located in an field of the table, then the new variable will be pasted in the preceding line; otherwise, the new variable is pasted at the end of the table. Moreover, you can paste a new declaration at the end of the table by using the right arrow key or the tab key in the last field of the table. You will receive a variable that has "Name" located in the Name field, and "Bool" located in the Type field, as its default setting. You should change these values to the desired values. Name and type are all that is necessary for a complete declaration of variables.

Pragma command

The pragma instruction is used to affect the properties of a variable concerning the compilation process. It can be used in with supplementary text in a program line of the declaration editor or in its own line.

The pragma instruction is enclosed in curly brackets, upper- and lower-case are ignored:
{ <Instruction text> }
If the compiler cannot meaningfully interpret the instruction text, the entire pragma is handled as a comment and read over. A warning is issued, however: „Ignore compiler directive ‚<Instruction text>’!“
Depending on the type and contents of pragma, the pragma either operates on the line in which it is located or on all subsequent lines until it is ended by an appropriate pragma, or the same pragma is executed with different parameters, or the end of the file is reached. By file we mean here: declaration part, implementation portion, global variable list, type declaration.

The opening bracket may immediately follow a variable name. Opening and closing brackets must be located on the same line.

The following pragma may currently be used: 
{flag}: {flag [<flags>] [off|on]} 

This pragma allows the properties of a variable declaration to be affected.
<flags> can be a combination of the following flags:

noinit

The variable will not be initialized.

nowatch

The variable can not be monitored.

noread

The variable is exported to the symbol file without read permission.

nowrite

The variable is exported to the symbol file without write permission.

noread, nowrite

The variable is not exported to the symbol file.

With the „on“ modifier, the pragma operates on all subsequent variable declarations until it is ended by the pragma {flag off}, or until overwritten by another {flag <flags> on} pragma. Without the „on“ or „off“ modifier, the pragma operates only on the current variable declaration (that is the declaration that is closed by the next semicolon).
Examples:

The variable a will not be initialized and will not be monitored. The variable b will not be initialized:

VAR
    a : INT {flag noinit, nowatch};
    b : INT {flag noinit};
END_VAR
VAR
    {flag noint, nowatch on}
    a : INT {flag noinit on};
    b : INT; 
    {flag off}
END_VAR

Neither variable will be initialized:

{flag noinit on}
VAR
    a : INT;
    b : INT;
END_VAR
{flag off}
VAR
    {flag noinit on}
    a : INT;
    b : INT;
    {flag off}
END_VAR

The flags „noread“ and „nowrite“ are used in a POU that has read and/or write permission to provide selected variables with restricted access rights. The default for the variable is the same as the setting for the POU in which the variable is declared. If a variable has neither read nor write permission, it will not be exported into the symbol file.
Examples:
If the POU has read and write permission, then with the following pragmas variable a can only be exported with write permission, while variable b can not be exported at all.

VAR
    a : INT {flag noread};
    b : INT {flag noread, nowrite};
END_VAR

Neither variable a nor b will be exported to the symbol file:

{flag noread, nowrite on}
VAR
    a : INT;
    b : INT;
END_VAR
{flag off}

The pragma operates additively on all subsequent variable declarations.
Example:
all POUs in use will be exported with read and write permission

a : afb;
...
FUNCTION_BLOCK afB
VAR
    b : bfb {flag nowrite};
    c : INT;
END_VAR
...
FUNCTION_BLOCK bfB
VAR
    d : INT {flag noread};
    e : INT {flag nowrite};
END_VAR
"a.b.d": Will not be exported.
"a.b.e": Will be exported only with read permission.
"a.c": Will be exported with read and write permission.

Pragmas for Controlling the Display of Library Declaration Parts

During creation of a library in TwinCAT PLC you can define via pragmas which parts of the declaration window should be visible resp. not visible in the Library Manager later when the library will be included in a project. The display of the implementation part of the library will not be affected by that. Thus comments or any variables declarations can be concealed from the user. The pragmas {library private} and {library public} each affect the rest of the same line resp. the subsequent lines, as long as they are not overwritten by the each other one.

Syntax:

{library public} The subsequent test will be displayed in the Library Manager.
{library private} :The subsequent test will be not displayed.


Example: See below the declaration part of a library, which is created in TwinCAT PLC. The comment "(* this is for all *)" should be displayed in the Library Manager after having included the library in a project., the comment "(* but this is not for all ")" however should not be displayed. The variables local and in3 also should not be displayed:

{library public}
    (*this is for all*)
{library private}
    (*this is not for all*)
{library public}
FUNCTION afun   : BOOL
VAR_INPUT
    in      : BOOL;
END_VAR
{library private}
VAR
    local   : BOOL;
END_VAR
{library public}
VAR_INPUT
    in2     : BOOL;
{library private}
    in3     : BOOL;
{library public}
END_VAR

Declaration Editors in Online Mode

In online mode, the declaration editor changes into a monitor window. In each line there is a variable followed by the equal sign (=) and the value of the variable. If the variable at this point is undefined, three question marks (???) will appear. For function blocks, values are displayed only for open instances (command: 'Project' 'Open instance').

In front of every multi-element variable there is a plus sign. By pressing <Enter> or after doubleclicking on such a variable, the variable is opened up. In the example, the traffic signal structure would be opened up.

Declaration Editor 9:

When a variable is open, all of its components are listed after it. A minus sign appears in front of the variable. If you doubleclick again or press <Enter>, the variable will be closed, and the plus sign will reappear.
Pressing <Enter> or doubleclicking on a single-element variable will open the dialog box to write a variable. Here it is possible to change the present value of the variable. In the case of Boolean variables, no dialog box appears; these variables are toggled. The new value will turn red and will remain unchanged. If the "Online" "Write values" command is given, then all variables are placed in the selected list and are once again displayed in black. If the "Online" "Force values" command is given, then all variables will be set to the selected values, until the "Release force" command is given. In this event, the color of the force value changes to red.