Standard Data Types

Overview

EcoStruxure Machine Expert supports all data types described by standard IEC61131-3.

The following data types are described in this chapter:

Additionally, some standard-extending data types are supported and you can define your own user-defined data types.

BOOL

BOOL type variables can have the values TRUE (1) and FALSE (0). 8 bits of memory space are reserved.

For further information, refer to the chapter BOOL constants.

NOTE: You can use implicit checks to validate the conversion of variable types (refer to the chapter POUs for Implicit Checks).

Integer

The table lists the available integer data types. Each of the types covers a different range of values. The following range limitations apply.

Data Type

Lower Limit

Upper Limit

Memory Space

BYTE

0

255

8 bit

WORD

0

65,535

16 bit

DWORD

0

4,294,967,295

32 bit

LWORD

0

264-1

64 bit

SINT

–128

127

8 bit

USINT

0

255

8 bit

INT

–32,768

32,767

16 bit

UINT

0

65,535

16 bit

DINT

–2,147,483,648

2,147,483,647

32 bit

UDINT

0

4,294,967,295

32 bit

LINT

–263

263-1

64 bit

ULINT

0

264-1

64 bit

NOTE: Conversions from larger types to smaller types may result in loss of information.

For further information, refer to the description of number constants.

NOTE: You can use implicit checks to validate the conversion of variable types (refer to the chapter POUs for Implicit Checks).

REAL / LREAL

The data types REAL and LREAL are floating-point types. They represent rational numbers.

Characteristics of REAL and LREAL data types:

Data type

Lower limit

Upper limit

Memory Space

REAL

-3.402823e+38

3.402823e+38

32 bit

LREAL

-1.7976931348623158e+308

1.7976931348623158e+308

64 bit

Example:

PROGRAM PLC_PRG
VAR
    rMax: REAL := 3.402823E+38; // Largest number
    rPosMin : REAL := 1.0E-44; // Smallest positive number
    rNegMax: REAL := -1.0E-44; // Largest negative number
    rMin: REAL := -3.402823E+38; // Smallest number
    lrMax: LREAL := 1.7976931348623158E+308; // Largest number
    lrPosMin : LREAL := 4.94065645841247E-324; // Smallest positve number
    lNegMax: LREAL := -4.94065645841247E-324; // Largest negative number
    lrMin: LREAL := -1.7976931348623158E+308; // Smallest number
END_VAR
NOTE: The support of data type LREAL depends on the target device. See in the corresponding documentation whether the 64-bit type LREAL gets converted to REAL during compilation (possibly with a loss of information) or persists.
NOTE: If a REAL or LREAL is converted to SINT, USINT, INT, UINT, DINT, UDINT, LINT, or ULINT and the value of the real number is out of the value range of that integer, the result will be undefined and will depend on the target system. Even an exception is possible in this case. In order to get target-independant code, handle any range exceedance by the application. If the REAL/LREAL number is within the integer value range, the conversion will work on all systems in the same way.

When assigning i1 := r1; an error is detected. Therefore, the previous note applies when using conversion operators such as the following:

i1 := REAL_TO_INT(r1);

For further information, refer to REAL/LREAL constants (operands).

NOTE: You can use implicit checks to validate the conversion of variable types (refer to the chapter POUs for Implicit Checks).

STRING

A STRING data type variable can contain any string of characters. The size entry in the declaration determines the memory space to be reserved for the variable. It refers to the number of characters in the string and can be placed in parentheses or square brackets. If no size specification is given, the default size of 80 characters will be used.

In general, the length of a string is not limited. But string functions can only process strings with a length of 1...255 characters. If a variable is initialized with a string too long for the variable data type, the string will be correspondingly cut from right to left.

NOTE: The memory space needed for a variable of type STRING is 1 byte per character + 1 additional byte. This means, the "STRING[80]" declaration needs 81 bytes.

Example of a string declaration with 35 characters:

str:STRING(35):='This is a String';

For further information, refer to WSTRING and STRING Constants (Operands).

NOTE: You can use implicit checks to validate the conversion of variable types (refer to the chapter POUs for Implicit Checks).

WSTRING

The WSTRING data type differs from the STRING type (ASCII) by interpretation in Unicode format, and needing two bytes for each character and two bytes extra memory space (each only one in case of a STRING).

The library standard64.lib provides functions for WSTRING strings.

The number of characters for WSTRING depends on the contained characters. A size of 10 for WSTRING means that the length of the WSTRING can take a maximum of 10 WORDS. For some characters in Unicode, multiple WORDS are required for coding a character so that the number of characters does not have to correspond to the length of the WSTRING (10 in this case). The data type requires one WORD of extra memory as it is terminated with a 0.

If a size is not defined, then 80 WORDS plus one for the terminating character 0 are allocated.

Examples:

wstr:WSTRING:="This is a WString";
wstr10 : WSTRING(10) := "1234567890";

For further information, refer to the following descriptions:

Date and Time Data Types

The data types TIME, TIME_OF_DAY (shortened TOD), DATE, and DATE_AND_TIME (shortened DT) are handled internally like DWORD. The data types LDATE, LDATE_AND_TIME (LDT) and LTIME_OF_DAY (LTOD) are handled internally like LWORD.Time is given in milliseconds in TIME and TOD. Time in TOD begins at 12:00 A.M. Time is given in seconds in DATE and DT beginning with January 1, 1970 at 12:00 A.M.

LTIME is supported as time base for high resolution timers. LTIME is of size 64 bit and resolution nanoseconds.

Syntax of LTIME:

LTIME#<time declaration>

The time declaration can include the time units as used with the TIME constant and as:

  • us : microseconds

  • ns : nanoseconds

Example of LTIME:

LTIME1 := LTIME#1000d15h23m12s34ms2us44ns

For further information, refer to the following descriptions:

NOTE: You can use implicit checks to validate the conversion of variable types (refer to the chapter POUs for Implicit Checks).

ANY / ANY_<type>

When you implement a function, and one of the function inputs (VAR_INPUT) has a generic IEC data type (ANY or ANY_<type>), then the data type of the call parameter is not defined as unique. Variables of different data types can be passed to this function. The value passed and its type can be requested within the function via a predefined structure.

Generic IEC data types that allow the use of elementary data types for function inputs:

Hierarchy of generic data types

Elementary data types

ANY

ANY_BIT

BYTE, WORD, DWORD, LWORD

ANY_DATE

DATE_AND_TIME, DATE, TIME_OF_DAY, LDATE_AND_TIME, LDATE, LTIME_OF_DAY,

ANY_NUM

ANY_REAL

REAL, LREAL

ANY_INT

USINT, UINT, UDINT, ULINT

SINT, INT, DINT, LINT

ANY_STRING

STRING, WSTRING

Example:

FUNCTION ANYBIT_TO_BCD : DWORD
   VAR_INPUT
      value : ANY_BIT;
   END_VAR

If the function ANYBIT_TO_BCD is called, then a variable of data type BYTE, WORD, DWORD, or LWORD can be passed to the function as a parameter.

Predefined structure:

When compiling the code, an ANY data type is replaced internally with the following structure:

TYPE AnyType :
STRUCT
        // the type of the actual parameter
    typeclass : __SYSTEM.TYPE_CLASS ;
        // the pointer to the actual parameter
    pvalue : POINTER TO BYTE;
        // the size of the data, to which the pointer points
    diSize : DINT;
END_STRUCT
END_TYPE

The actual call parameter assigns the structure elements at runtime.

Example:

This code example compares whether the two passed variables have the same type and the same value.

FUNCTION Generic_Compare : BOOL
VAR_INPUT
    any1 : ANY;
    any2 : ANY;
END_VAR
VAR
    icount: DINT;
END_VAR

Generic_Compare := FALSE;
IF any1.typeclass <> any2.typeclass THEN
    RETURN;
END_IF
IF any1.diSize <> any2.diSize THEN
    RETURN;
END_IF
// Byte comparison
FOR icount := 0 TO any1.diSize-1 DO
    IF any1.pvalue[iCount] <> any2.pvalue[iCount] THEN
        RETURN;
    END_IF
END_FOR
Generic_Compare := TRUE;
RETURN;
// END_FUNCTION

Also refer to the description of the __VARINFO operator.