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

Target-Independent Integer Data Types __UXINT, __XINT, __XWORD

To create IEC code suitable for the different target systems, use the target-independent integer data types __UXINT, __XINT, and __XWORD. The compiler converts these data types into the appropriate standard data types supported by the target system. Systems with address registers of 32-bit and 64-bit width are supported.

The following type conversion operators are provided:

Target-independent data types

On 64-bit platforms

On 32-bit platforms

__UXINT

ULINT

UDINT

__XINT

LINT

DINT

__XWORD

LWORD

DWORD

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

With EcoStruxure Machine Expert V2.2 and later versions, the STRING data type can be encoded in Latin 1 or in UTF-8 format. For project-wide interpretation as UTF-8, enable the parameter UTF8 Encoding for STRING in the Project Settings > Compile options dialog box. For further information, refer to Project-Wide UTF-8 Encoding.

NOTE: Before you set the encoding format to UTF-8, execute the static analysis rule SA0175 on your code to help detect constructs that may cause issues with UTF-8 encoding.
NOTE: If you use UTF-8 encoding, add the {attribute 'monitoring_encoding' := 'UTF-8'} pragma to the declaration of a variable. It allows you to monitor the contents of the variable in UTF-8 encoding.

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 bytes in the string and can be placed in parentheses or square brackets. If no size specification is given, the default size of 80 bytes will be used. 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.

String length:

  • For Latin 1 encoding, 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.

  • With UTF-8 encoding, one character can have a length of up to four bytes. The length of the string indicates the number of bytes which are reserved for the STRING. Thus, there is no longer a 1:1 relationship between the character count and the string length in bytes.

Example of a string declaration with 35 bytes:

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

In general, the length of a string is not limited. When you execute string manipulations with the functions of the Standard library, strings up to a length of 255 are allowed. When you execute string manipulations with the functions of the StringUtils library, longer strings (>255 characters) are also permitted.

When a variable of the data type STRING is reinitialized by resetting the application, the contents of the old string, that exist after the terminating null character of the initial value, are not overwritten. This applies both to initialization with the initialization value and to initialization with the default initialization value of 0.

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 for string termination (each only one in case of a STRING).

WSTRING data types are encoded as Unicode in UTF-16 format.

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.