# 5. IEC61131-3 Syntax

# 5.1 Introduction to Basic Concepts

Real-time programming functions are implemented with reference to the IEC61131-3 Software Information Model, which describes the interrelationships between software elements, including: configurations, resources, applications, tasks, program units (POUs), and global variables.

Configuration: The configuration describes the characteristics of the programmable control system (a PLC), including the hardware device (CPU module and the IO expansion and communication module associated with it), and the binding relationship between resources and tasks.

Resources: The physical units that can be loaded to execute the application, for example, each CPU in a PLC can be considered a resource.

Applications: There are three types of applications: real-time applications, non-real-time applications, and communication protocol stack applications. Real-time applications can be written in ladder diagrams (LD) or structured text (ST), non-real-time applications can be written in Python, and communication protocol stack applications can set parameters based on configuration pages. Each application in this project corresponds to a separate process.

Task: In a real-time application, a program unit (POU) needs to be mounted to a task before it can be executed. Each app can contain multiple tasks, and the order of execution is determined based on the priority of the tasks and how they are triggered. There are two ways to trigger a task: timed loop and event trigger.

Program unit (POU): includes three types: program (PROG), program unit includes function (FUN) and function block (FB), in which the program (PROG) constitutes the main program of the application and can define input and output parameters; The function (FUN) defines the input and output parameters, as well as a function return value, there are no static variables used to save the state, and the same result is always returned for the same input parameters; Function blocks (FBs) define input and output parameters, can save state with static variables, and the result of each execution depends on internal (VAR) and external (VAR_EXTERNAL) variables.

Global Variables & Process Mirrors: Global variables are "global" when they are found everywhere in a real-time application. Different POUs in the same application can interact with data through global variables. In addition, the runtime system will set aside a shared memory area to store the input and output variables in the control process as an intermediary between the application and the IO registers, which is called the process mirror area (storing the variables of the control process), which includes the input variable area (I area), the output variable area (Q area), and the intermediate variable area (M area). When you create a new global variable, you can manually bind it to the process mirror address, and the bound global variable can be accessed by NR applications, NRT applications, and communication stack applications. This project will automatically create a global variable for the protocol object (measurement point) added by the user and bind the process image address.

# 5.2 Common Elements

# 5.2.1 Identifiers

An identifier consists of letters, numbers, and underscores, with the first character being a letter or underscore (not a number) and the last character being a letter or number (not an underscore). Identifiers are not case-sensitive, and abcd, ABCD, or aBCd are treated as the same identifier by the compiler. Consecutive underscores are not allowed in identifiers, for example, __LIM_SW5 and LIM___SW5 are considered invalid.

The IEC61131-3 (2003) standard requires that identifiers should distinguish at least the first six characters, i.e., ABCDE1 and ABCDE2 should be judged to be two different identifiers.

The following are legitimate identifiers

Identifiers make up the elements Example
Uppercase letters, lowercase letters, numbers, underscores in the middle of identifiers, underscores as first characters IW215、IW215Z、QX75、IDENT
LIM_SW_5、LimSw5、abcd、ab_Cd_MAIN、_12V7

# 5.2.2 Keywords

Keywords should not contain spaces and are not case-sensitive, e.g., FOR and for are considered the same keyword by the compiler.

For specific definitions of keywords, please refer to Appendix C of IEC61131-3 (2003).

Keywords Description
VAR … END_VAR Variable Declaration
VAR CONSTANT
LOCALVAR0 : INT := 1;
END_VAR
VAR_INPUT Input Variables
VAR_OUTPUT Output Variables
VAR_IN_OUT Input and Output Variables
VAR_EXTERNAL External Variables
VAR_TEMP Temporary Variables
VAR_ACCESS Access Variables (Not Supported)
VAR_CONFIG Configuration Variables (Not Supported)
VAR_GLOBAL Global Variables
RETAIN Qualifier: Hold
NON_RETAIN Qualifier:Non-retaining
CONSTANT Qualifier: Constant
R_EDGE Qualifier: Rising edge
F_EDGE Qualifier: Falling edge
READ_ONLY Qualifier: Read-only
READ_WRITE Qualifiers: Readable and writable
TYPE … END_TYPE Type Declaration
TYPE
COLOR : (RED, YELLOW, BLUE);
END_TYPE
STRUCT … END_STRUCT Structure Type
TYPE
DEVICE : STRUCT
IP : STRING;
PORT : INT;
END_STRUCT;
END_TYPE
ARRAY … OF … Array Type
TYPE
MEASURE : ARRAY [1..10] OF INT;
END_ARRAY
AT Specify the IEC address
NOT Withdrawal
MOD Modular arithmetic
AND and
OR or
XOR Exclusive OR
LABEL Label
JMP Jump
PROGRAM … END_PROGRAM Program Declaration
CONFIGURATION … END_CONFIGURATION Configuration Declaration
CONFIGURATION config
RESOURCE resource1 ON PLC
TASK MAINTASK(INTERVAL := T#100ms, PRIORITY := 1);
PROGRAM MY_PRG1 WITH MAINTASK : MYPRG;
END_RESOURCE
END_CONFIGURATION
RESOURCE … ON … END_RESOURCE Resource Declaration
TASK Mission Statement
PROGRAM … WITH … Task invoker
IF … THEN … ELSIF … ELSE … END_IF IF Sentense
IF d < e THEN f := 1;
ELSIF d = 4 THEN f := 2;
ELSE f := 3;
END_IF;
CASE … OF … ELSE … END_CASE CASE Sentense
CASE f OF
1: g := 11;
2: g := 12;
ELSE g ;= 13;
END_CASE;
FOR … TO … BY … DO … END_FOR FOR Sentense
FOR h := 1 TO 10 BY 2 DO
f[h/2] := h;
END_FOR;
WHILE … DO … END_WHILE WHILE Sentense
WHILE m > 1 DO
N := n / 2;
END_WHILE;
REPEAT … UTIL … END_REPEAT REPEAT Sentense
REPEAT
i := i * j;
UNTIL i < 10000
END_REPEAT;
EXIT Exit Sentense
EXIT;

# 5.2.3 Constants

It is declared in the PLC in the form of "type name#value" or "value".

Type Description Example
BOOL Boolean BOOL#FALSEBOOL#0TRUE
BYTE 8 bits,0 ~ 16#FF 1116#0B2#0000_1011
WORD 16 bits,0 ~ 16#FFFF 0
DWORD 32 bits,0 ~ 16#FFFF FFFF 16#ABCDEF
LWORD 64 bits,0 ~ 16#FFFF FFFF FFFF FFFF 16#ABCDEFABCDEF
SINT Short integer,-128 ~ 127 125
INT Integer,-32768 ~ 32767 -32456
DINT Double precision integer,-231~ 231-1 324534
LINT Long integer,-263 ~ 263-1 545672345
USINT Unsigned short integer,0 ~ 255 1
UINT Unsigned integer,0 ~ 65535 10
UDINT Unsigned double precision integer,0 ~ 231-1 500
ULINT Unsigned long integer,0 ~ 263-1 60000
REAL 32-bit floating-point type 1.0
LREAL 64-bit long floating-point type 2.0
DATE Date DATE#2023-06-29, D#2023-06-29
LDATE Long date LDATE#2023-06-29, LD#2023-06-29
TIME_OF_DAYTOD Time TOD#11:30:00
LTIME_OF_DAYTOD Long Time LTOD#11:30:00
DATE_AND_TIMEDT Date & Time DT#2023-06-09-11:30:00
LDATE_AND_TIMEDT Long Date & Time LDT#2023-06-09-11:30:000001
TIME Duration TIME#1000msT#1d2h7m19s45.7ms
LTIME Long Duration LTIME#0NS, LTIME#213503D23H34M33S709MS551US615NS
STRING String ‘text’
WSTRING Wide String “text”

# 5.2.4 Comments

Comments should begin with "(" and end with ")". Nested comments are not allowed inside annotations, for example, (* (*NESTED *) *) is considered a syntax error. Allow in-line comments starting with //, or block comments starting with /* and ending with */.

# 5.2.5 Preprocessing Instructions

Preprocessing instructions should start with "{" and end with"} ". Example: {VERSION 3.1} {AUTHOR JHC}{x := 256, y := 384}

Currently, the IDE supports the following commands for debugging and printing log information during compilation:

  1. INFO Example:{INFO: "this is an info message."}
  2. WAENING Example:{WARNING: "this is a warn message."}
  3. ERROR Example:{ERROR:"this is an error message."}

# 5.3 Variables

# 5.3.1 Data Type of Variables

# 5.3.1.1 Basic Data Types

The base data types, the keywords for each data type, the number of bits for each data element, and the range of values for each base data type should be shown in the following table. The circumference should be shown in the table below.

Keywords Date Type Bit(N) Value Range Initial Value
BOOL Boolean 1 0,1 0(FALSE)
SINT Short integer 8 [-(2N-1), (2N-1)-1] 0
INT Integer 16 [-(2N-1), (2N-1)-1] 0
DINT Double integer 32 [-(2N-1), (2N-1)-1] 0
LINT Long integer 64 [-(2N-1), (2N-1)-1] 0
USINT Unsigned short integer 8 [0, (2N)-1] 0
UINT Unsigned integer 16 [0, (2N)-1] 0
UDINT Unsigned double integer 32 [0, (2N)-1] 0
ULINT Unsigned long integer 64 [0, (2N)-1] 0
REAL Real number 32 -- 0.0
LREAL Long real number 64 -- 0.0
TIME Duration 32 -- T#0ms
LTIME Long duration 64 -- LT#0ms
DATE Date 32 -- D#1970-01-01
LDATE Long date 64 -- LD#1970-01-01
TIME_OF_DAT or TOD Time of day 32 -- TOD#00:00:00
LTIME_OF_DAT or TOD Long time of date 64 -- LTOD#00:00:00.999999
DATE_AND_TIME or DT Date & time 32 -- DT#1970-01-01-00:00:00
LDATE_AND_TIME or DT Long date & time 64 -- LDT#1970-01-01-00:00:00
STRING Single-byte string 8*N -- '' (empty string)
BYTE 8-bit length bit string 8 -- 0
WORD 16-bit length bit string 16 -- 0
DWORD 32-bit length bit string 32 -- 0
LWORD 64-bit length bit string 64 -- 0
WSTRING Double-byte strings 16*N -- "" (empty string)

# 5.3.1.2 Custom Data Types (DUT)

By right-clicking on the app and selecting the DUT> you can add a user-defined data type. Currently, 6 user-defined data types are supported, which are:

  • Direct Derived Data Type (Alias)
  • Enumerate data types (Enumerate)
  • Scope Data Type (Scope)
  • Array Data Type (Array)
  • Struct Data Type (Struct)
  • Union Data Type (Union)
# 5.3.1.2.1 Direct Derived Data Types

When you declare a direct-derived data type, you can derive a user-defined data type in addition to the underlying data type.

Unless otherwise specified, a direct-derived data type has the same initial value as its derived data type. For example, the derived data type in the following diagram dut_alias_INT used exactly the same way as INT. If you assign an initial value to the dut_alias_INT type in the initial value, the dut_alias_INT type will use the set initial value as the default initial value.

# 5.3.1.2.2 Enumeration

The enumerated data type declares that the value of any data element of that type can only be one of the values given in the list of associated identifiers, which defines an ordered set of enumerated values, starting with the first identifier of the list and ending with the last identifier. Different enumeration data types can use the same identifier as an enumeration value.

To enable the use of unique identifiers in a particular context, enumeration literals can be qualified with a prefix consisting of their associated data type name and the '#' symbol. This prefix must not be used in an enumerated list. If enough information is not provided in the enumeration literal to unambiguously determine its value, a syntax error will occur.

The default default value for an enumerated data type is the first identifier in the enumeration list, or a different enumeration value specified by the user.

For example, dut_my_enum1 the enumeration data type is defined in the following figure, there are three enumeration terms, which are aa, bb, and cc, and their default initial values are aa.

# 5.3.1.2.3 Scope

The scope declaration specifies that the value of any data element of that type can only be between the specified upper and lower bounds. If the value of the range type exceeds the specified value range, it is strictly limited to the range specified by the user.

For range data types, if no initial value is specified, the default default value is the minimum (lower value) of the range.

# 5.3.1.2.4 Arrays

An array declaration specifies that each element of the type is allocated enough data storage space to store all the data that can be accessed through the specified index range.

If not otherwise specified, the default value of the array element is the default value of the corresponding data type.

In the following example, a two-dimensional array is defined dut_array, and the following table is 1. 2 and 2.. 6。 The two-dimensional array contains two rows, five columns, and ten elements, as shown in the following table [1,2], [1,3], [1,4], [1,5], [1,6], [2,2], [2,2], [2,3], [2,4], [2,5], [2,6].

Array initialization, which can be initialized in the following way:

  1. When defining an array, assign an initial value to the elements of the array, for example: [1,2,3,4,5,6,7,8,9,10], then the ten elements will be assigned values from 1 to 10;
  2. Assign values to only some array elements, e.g. [1, 2]; In this initialization, only the first two elements are assigned, and the array elements that are not assigned are initialized using the default values of their base data types, and in the above example, the last eight elements are initialized to 0;
  3. For duplicate initial values, you can define them in batches, and you only need to add the number before the parentheses, for example, the element definition of 4(8) in the example above indicates that the value of 4 elements is 8
  4. When an array element defines an initial value, the parenthesis [] is required to indicate that it is an array structure.

If you only need to define a one-dimensional array, add a dimension.

# 5.3.1.2.5 Structure

The struct declares that a data element specifying that type should contain children of the specified type, which can be accessed by the specified name.

If not otherwise specified, the initial value of the struct element is the initial value of the corresponding element data type.

For example, in the following example, a structure data type is defined dut_struct contains two elements, which are the integer age and the string name. Neither element has an initial value set, so the initial value of its variable type is used as the initial value of the struct element.

# 5.3.1.2.6 Union

Union is a data structure that usually contains different data types. It is defined in a form similar to a Structure data type.

In a union, all elements have the same offset and therefore the same amount of memory. In the following example of a union declaration, an assignment to the union variable element a. also affects its element b

# 5.3.1.3 Pointer Data Type

# 5.3.1.3.1 Pointer Definition

A pointer stores the memory address of an object (e.g., a variable or a function block instance) at runtime. The syntax is as follows:

<pointer name>: POINTER TO <data type | data unit type | function block>;

  • Defining Pointer Types with the POINTER TO Keyword
  • Pointers can point to base data types, user-defined data types, or function block types
# 5.3.1.3.2 Example
FUNCTION_BLOCK FB_Point
VAR
  piNumber: POINTER TO INT;
  iNumber1: INT := 5;
  iNumber2: INT;
END_VAR

piNumber := ADR(iNumber1);  // address of iNumber1 assigned to piNumber
iNumber2 := piNumber^;      // assign the value 5 to the iNumber2 variable by pointer deference
1
2
3
4
5
6
7
8
9

A pointer variable must point to some data in memory before it can be used; if the target has data alignment requirements, it must be ensured that the type to which the pointer refers is the same as the type of data being accessed.

Pointers support both value and address operations:

  • Can be taken directly by attaching a content operator to a pointer identifier, such aspiNumber^ above.
  • TheVAL fetch instruction can be used to obtain the value of a variable at the address of the pointer and assign it to another variable, similar to using the^ symbol to dereference a pointer.
  • The address value of a variable can be obtained by using theADR take-address instruction to assign it to a pointer, e.g.,piNumber := ADR(iNumber1) above.

# 5.3.2 Representation of Variables

Variables can be simply divided into two categories, single-element variables and multi-element variables.

A single-element variable is defined as:

  • A variable that represents a single data element of one of the basic types;
  • Variables that represent enumeration or range types in custom data types;
  • A derived data type in a custom data type whose "parent type" is traceable to a base, enumeration, or range type.

Use the identifiers defined in this article as variable symbol representations. Variables can also be associated with an address, in the address bar by the percent sign "%", the position and size prefixes in the following table, and one or more periods (.) Separated unsigned integers are concatenated to form a special symbol.

Directly represents the position and size prefix properties of the variable

Prefix Implication Default data type
I Input region
Q Output region
M Save region
X Bit BOOL
None Bit,ditto BOOL
B Byte(8 bits) BYTE
W Word(16 bits) WORD
D Double word(32 bits) DWORD
L Long word(64 bits) LWORD

The data type of a multi-element variable is an array or a struct.

An array is a collection of data elements of the same data type, indexed by one or more subscripts, enclosed in parentheses ("[]") and separated by commas.

An example of the use of array variables in ST is as follows:

OUTARY[%MB6,SYM] := INARY[0] + INARY[7] - INARY[%MB6] * %IW62;

A struct variable is a variable that is declared as a previously defined struct type, which is a data type consisting of a collection of named elements.

The elements of a struct variable should consist of two or more identifiers or with a single period (.) delimited array access. The first identifier represents the name of the structured element, and the subsequent identifier represents the sequence of component names that access a specific data element in the data structure.

For example, if the variable person is declared as a dut_struct type, the following code will result in 18 elements being assigned to the variable personage; And the name is assigned 'Whoami':

person.age := 18;

# 5.3.3 Variable Declaration and Initialization

Each declaration of a program organizational unit type (each declaration of a program, function, or function block) should contain at least one variable declaration section at the beginning of it, which specifies the type of variable used in the POU (and also the physical or logical location if required).

Variables declare properties

Type Keywords External read and write Internal read and write Description
Local VAR R/W Variables that are only visible inside the POU
Input VAR_INPUT R/W R Input form parameter variables. When the called POU uses this type of variable, the arguments are copied (call-by-value), and the value of the arguments will not be changed during the calculation.
Ooutput VAR_OUTPUT R R/W The output parameter variable is used to return the return-by-value result, and the value of the variable cannot be changed after the call is completed.
Input and output variables VAR_IN_OUT R/W R/W The called POU directly uses the call-by-reference of the argument variable, and the calculation process directly changes the value of the argument, so VAR_IN_OUT type variables can be used to pass the calculation result (for array or struct variables, this is more efficient).
Temporary variables VAR_TEMP R/W Variables that are only visible inside the POU and are reinitialized each time the program organization unit is executed.
External variables EXTERNAL R/W Used to declare global variables defined in GVL; It can be used in the POU only after it has been declared

Each variable contains the following properties

  1. Category: Categorize variables based on their scope
  2. Name: User-defined, naming conventions should be observed.
  3. Address: The associated process image address (can not be associated).
  4. Data types: Basic types and custom types (DUTs) are included.
  5. Initial value: The user sets the initial value based on the variable type, and the IDE provides the default value.

Notes: User-entered description text that explains the role and use of variables in the program

Variable initialization

When a configuration element (configuration or resource) is started, each variable associated with the configuration element and its program can take one of the following initial values:

  • The value of the variable (reserved value) when the configuration element was last "stopped" does not support the reserved property.
  • user-specified initial values;
  • The default value for the data type associated with the variable

VAR_EXTERNAL is a reference to a global variable and cannot assign an initial value to a variable that VAR_EXTERNAL declares.

During array initialization, parentheses can be used as repeating factors in the array initialization list, e.g., 2(1,2,3) is equivalent to the initialization sequence 1,2,3,1,2,3.

If the number of initialized values given in the initialization list exceeds the number of array entries, the extra (rightmost) initializers are ignored.

If the number of initial values is less than the number of array entries, the remaining array elements are populated with the default initial values for the corresponding data type.

When a variable is declared as a function block instance, the input to the function block and the initial value of any accessible variable can be declared with the assignment operator and the parentheses following the function block type identifier, as shown in the following table. Elements that do not have initial values listed should have the default initial values declared for those elements in the function block declaration.

Initial value assignment of variables

Feature description/example
Directly represents the initialization of the variable
VAR
AT %QX5.1 : BOOL :=1;
AT %MW6 : INT := 8 ;
END_VAR
Boolean type, initialized to 1
Initializes memory word, value is integer 8
Symbolic variables are initialized with address variables
VAR
VALVE_POS AT %QW28 : INT := 100;
END_VAR
Assign the output word 28 to the integer variable VALVE_POS with an initial value of 100
Symbolic variable initialization
VAR
MYBIT : BOOL := 1 ;
OKAY : STRING[10] := 'OK';
END_VAR
Assign a memory bit to the bollean variable MYBIT, with an initial value of 1.
Allocate memory to contain strings with a maximum length of 10 characters. When initialized, the string is 2 in length and contains two byte sequences of the character 'OK' (decimal 79 and 75, respectively) in order suitable for printing as a string.
Array initialization
VAR
BITS : ARRAY[0..7] OF BOOL
:= [1,1,0,0,0,1,0,0] ;
TBT : ARRAY [1..2,1..3] OF INT
:= [1,2,3(4),6] ;
END_VAR
Allocate 8 memory bits to hold the initial value
BITS[0]:= 1, BITS[1] := 1,...,
BITS[6]:= 0, BITS[7] := 0
A 2 x 3 array of integers with initial values TBT:
TBT[1,1]:=1, TBT[1,2]:=2,
TBT[1,3]:=4, TBT[2,1]:=4,
TBT[2,2]:=4, TBT[2,3]:=6.
Struct variable initialization
VAR person: dut_struct  :=
( age := 18,
name := ‘Whoami’);
END_VAR
Initialization of a derived data type variable
This example shows that the age field for the variable person is initialized as 18 and 'Whoami', respectively.
Constant variable initialization
VAR CONSTANT PI : REAL := 3.141592 ; END_VAR
Function block instance initialization
VAR TempLoop :
PID := (PropBand := 2.5, Integral := T#5s);
END_VAR
Assign initial values to the inputs and outputs of the function block instance

# 5.4 Program Organization Unit (POU)

The organizational units of a program defined in IEC 61131 include functions, function blocks, and programs.

The program organization unit shall not be recursive; That is, the invocation of a program's organizational unit must not give rise to its own invocation.

# 5.4.1 Functions

A function produces only one data element (considered the function return value) and any number of additional output elements (VAR_OUTPUT and VAR_IN_OUT) when executed. The function return value can be an array or a struct. In a textual language, the call of a function can be used as an operand in an expression.

Functions should not contain internal state information, that is, calls to functions with the same parameters (VAR_INPUT variables and VAR_IN_OUT variables) should always produce the same value (VAR_OUTPUT variable, VAR_IN_OUT variable and function return value). Based on this principle, variables defined in the global GVL cannot be used in functions.

# 5.4.1.1 Function Representation and Declaration

Create a POU by right-clicking on the application-> the POU, selecting the POU type as a function, selecting the programming language used and the return value of the function. For example, the following diagram defines a function named myAdd, which returns the value of the INT data type and writes the function body in ST language.

The function name is the return value of the function, so you need to assign the function value at least once in the function definition. The last assignment result is used as the return value of the function. For example, the following figure shows the implementation of a function that has two input parameters, IN1 and IN2, and the function returns the sum of the two input parameters.

There is no need to define additional EN and ENO parameters in the function definition, and the system will automatically generate the corresponding logic.

Functions and how they are called can be represented graphically or literally. The call of the function should follow the following rules:

  1. The assignment to VAR_OUTPUT variable is either null or variable.
  2. The assignment to the VAR_IN_OUT parameter must be a variable.
  3. Assign values to VAR_INPUT parameters can be null, constant, variable, or function calls. In the latter case, the result of the function is used as the actual parameter.

The following diagram illustrates the graph of a function and the use of its equivalent text to call a function, taking the standard function (ADD) as an example.

Example Explanation
Use a graphical representation of the ADD function
D := ADD(A,B,C); Textual language using ADD functions (informal calls)
D := ADD(IN1:=A, IN2:=B, IN3:=C); Text language using ADD functions (formal call)
Execute control of the ADD function graph used
D := ADD(EN:=bVar, IN1:=A, IN2:=B, IN3:=C); Textual language for the ADD function that executes the control (formally called)

A text call to a function should consist of a function name followed by a list of arguments. In ST, parameters are separated by commas, and the left and right of the list are separated by parentheses "()" . The following requirements must be met:

  1. Informal calls are not supported in function text language calls with execution control, and can only be called formally.
  2. In the official call, use the ":=" operator to assign values to input variables and input-output variables
  3. In the official call, the => operator is used to assign the value of the output variable to the variable
  4. In the official call, the order of the parameters in the list is not important, and the number of parameters passed is not important, and any variable that is not assigned in the list, if any, uses the default value assigned in the function specification, or the default value of the associated data type.
  5. The list of informal call parameters should contain the exact same number of parameters, order, and data type as given in the function definition, and do not contain the execution control parameters EN and ENO.

# 5.4.1.2 Function Execution Control Logic

In the function definition, the system provides an additional Boolean EN (Enable) input or ENO (Enable Out) output based on the function declaration, similar to the following definition:

VAR_INPUT AND: BOOL := 1; END_VAR

VAR_OUTPUT ONE: BOOL; END_VAR

When these two variables are used, the execution of the function definition operation is controlled according to the following rules:

  1. WHEN A FUNCTION IS CALLED, IF THE VALUE OF EN IS FALSE(0), THE OPERATION DEFINED IN THE FUNCTION BODY WILL NOT BE EXECUTED, AND THE ENO WILL BE SET TO FALSE.
  2. If the value of EN is TRUE(1), ENO will be set to TRUE by the system and the logical operation in the function body will be executed.

# 5.4.1.3 Standard Library Functions

Extensible inputs are allowed for a specified function in a standard function, for example, an extensible addition should have the sum of all its inputs as its output. The actual number of inputs that are valid in the formal call of a function that expands parameters is determined by the formal input name with the highest position in the parameter name sequence. For example:

  1. X := ADD(Y1,Y2,Y3); is equivalent to X := ADD(IN1 := Y1, IN2 := Y2, IN3 := Y3);
  2. I := MUX_INT(K:=3, IN0 := 1, IN2 := 2, IN4 := 3); is equivalent to I := 0; Since IN3 has no input, it defaults to 0, and any number multiplied by 0 results in 0.

The function parameters of a standard extensible function follow the following rules:

  • If the name of the input variable is not given in the standard function, the default name is IN1, IN2,..., which should be used in the graph from top to bottom.
  • When a standard function has only one unnamed input, the default name IN should be used.
  • When a standard function has only one unnamed output, the default name OUT should be used.
# 5.4.1.3.1 Type Conversion Functions

The type conversion function should be in the form of *TO , where "*" is the data type of the input variable IN and " " is the data type of the output variable OUT, such as INT_TO_REAL.

Conversions from type REAL or LREAL to type SINT, INT, DINT or LINT should be rounded according to the convention of IEC 60559, according to which the result should be the nearest even number if the two nearest integers are equal, for example:

  • REAL_TO_INT(1.6) has a value of 2
  • REAL_TO_INT(-1.6) has a value of -2
  • REAL_TO_INT(1.5) has a value of 2
  • REAL_TO_INT(-1.5) has a value of -2
  • REAL_TO_INT(1.4) has a value of 1
  • REAL_TO_INT(-1.4) has a value of -1
  • REAL_TO_INT(2.5) has a value of 2,
  • REAL_TO_INT(-2.5) has a value of –2

The function TRUNC is used to convert the integer portion of a floating-point number represented by REAL or LREAL to an integer, for example:

  • TRUNC(1.6) has a value of 1
  • TRUNC(-1.6) has a value of -1
  • TRUNC(1.4) has a value of 1
  • TRUNC(-1.4) has a value of -1

When the corresponding bit-string variables contain data encoded in BCD format, the conversion functions _TO_BCD__BCD_TO_, Dword, and LWORD and USINT, UINT, UDINT, and ULINT variables are executed (respectively). and **). For example, the value of USINT_TO_BCD_BYTE (25) would be 2#0010_0101, while the value of WORD_BCD_TO_UINT (2#0011_0110_1001) would be 369.

# 5.4.1.3.2 Numerical Functions

The following table describes the function name, input and output variable types, and function description of a single numeric variable function. These functions should be overloaded on the defined generic type. These functions, inputs and outputs are of the same type.

Function Input/output type Description
General function
ABS ANY_NUM absolute value
SQRT ANY_REAL square root
Logarithmic function
LN ANY_REAL natural logarithm
LOG ANY_REAL Logarithmic base of 10
EXP ANY_REAL natural index
Trigonometric function
SIN ANY_REAL sine in radians
COS ANY_REAL cosine in radians
TAN ANY_REAL tangent in radians
ASIN ANY_REAL arcsine
ACOS ANY_REAL arc cosine
ATAN ANY_REAL arc tangent

The function name and symbol and description of the arithmetic function of two or more variables are shown in the following table. These functions should be overloaded on all numeric types, and if one of the functions evaluates outside of the range of values specified for the data type output by the function, or tries to divide by zero, a syntax error will occur.

Function Sign Description
Expandable arithmetic function
ADD + OUT:=IN1+IN2+...+INn
MUL * OUT:=IN1 *IN2*...*INn
Non-expandable arithmetic functions
SUB - OUT:=IN1-IN2
DIV / OUT:=IN1/IN2
MOD % OUT:=IN1 moeulo IN2
EXPT ** OUT:=IN1ᴵᴺ²
MOVE := OUT:=IN
# 5.4.1.3.3 Bit String Functions

The function name and description of the shift function of a single bitstring variable are defined in the table. These functions should overload all bitstring types.

Function Description
SHL OUT is equal to the left shift of IN by N bits, and the rightmost part is padded with 0
SHR OUT is equal to IN shifted to the right by N bits, and the leftmost part is padded with 0
ROR OUT is equal to the right shift of the IN cycle by N bits
ROL OUT is equal to the right shift of the IN cycle by N bits

The standard graphical representation of the function name, symbol, and description of a bit Boolean function is defined in the following table. These functions should be extensible (except NOT) and overloaded on all bitstring types.

Function Sign Description
AND & OUT := IN1 & IN2 ... & INn
OR OUT := IN1 OR IN2 ... OR INn
XOR OUT := IN1 XOR IN2 ... XOR INn
NOT OUT := NOT IN1
# 5.4.1.3.4 Select and Compare Functions

The selection and comparison functions should be overloaded on all data types. The following table lists the standard function names and descriptions for selecting a function.

Graphical Representation Description/Example
SEL Binary choice:
if G = 0,then OUT := IN0,
if G = 1,then OUT := IN1,
e.g: A := SEL(G:=0,IN0:=X,IN1:=5) ;
MAX Extensible Maximum Function:
OUT := MAX (IN1,IN2, ...,INn),
e.g: A := MAX(B,C,D) ;
MIN Extensible Minimum Function:
OUT := MIN (IN1,IN2, ...,INn),
e.g: A := MIN(B,C,D) ;
LIMIT Limit Range Functions:
OUT := MIN(MAX(IN,MN),MX),
e.g: A := LIMIT(IN:=B,MN:=0,MX:=5);
MUX Extensible Multiplexer
Select one of N inputs based on input K,
e.g:A := MUX(0, B, C, D);equivalent to A := B

The standard function names and symbols and descriptions of the comparison functions are defined in the following table. All comparison functions (except NE) should be extensible.

The bitstring data is compared bitwise from the most significant bit to the least significant bit, and the shorter bit string is considered to be filled with zeros on the left side compared to the longer bit string. That is, the comparison of bitstring variables should be the same as the comparison of unsigned integer variables.

Function Sign Description
GT > Decreasing sequence:OUT := (IN1>IN2) & (IN2>IN3) & ... & (INn-1 > INn)
GE >= monotonic sequence,descending order:OUT := (IN1>=IN2)&(IN2>=IN3)& ... & (INn-1 >= INn)
EQ = equivalent sequence:OUT := (IN1=IN2) & (IN2=IN3) & ... & (INn-1 = INn)
LE <= increasing sequence:OUT := (IN1<=IN2)&(IN2<=IN3)& ... & (INn-1 <= INn)
LT < monotonic sequence,increasing order:OUT := (IN1<IN2) & (IN2<IN3) & ... & (INn-1 < INn)
NE <> Inequality (non-extensibility):OUT := (IN1 <> IN2)
# 5.4.1.3.5 String Functions

All functions defined in the previous section apply to strings. In order to compare two strings of unequal length, it should be considered that the shorter string is extended to the length of the longer string on the right by a character with a value of 0. Compare from left to right based on the numeric value of the character code in the character set. For example, the string 'Z' must be greater than the string 'AZ' and 'AZ' must be greater than 'ABC'.

The table lists the standard function names and descriptions for string functions. For the purposes of the operation, the character position in the string should be treated as numbered 1, 2、...,L, starting with the leftmost character position, where L is the length of the string.

Function Description/Example
LEN String length function,
e.g:A := LEN('ASTRING');
equivalent to A := 7;
LEFT Get the substring consisting of the leftmost L characters of IN,
e.g:A := LEFT(IN:='ASTR',L:=3);
equivalent to A := 'AST' ;
RIGHT Get the substring consisting of the rightmost L characters of IN,
e.g:A := RIGHT(IN:='ASTR',L:=3);
equivalent to A := 'STR' ;
MID Get the string IN starting at position P and of length L,
e.g:A := MID(IN:='ASTR',L:=2,P:=2);
equivalent to A := 'ST' ;
CONCAT Expandable Connectivity,
e.g:A := CONCAT('AB','CD','E') ;
equivalent to A := 'ABCDE' ;
INSERT Insert IN2 at position P out of IN1 to get the splice string,
e.g:A:=INSERT(IN1:='ABC',IN2:='XY',P=2);
equivalent to A := 'ABXYC' ;
DELETE Remove L characters in IN, starting from the P character position: A := DELETE(IN:='ABXYC',L:=2, P:=3) ;
equivalent to A := 'ABC' ;
REPLACE Replace the L characters in IN1 with IN2, starting from the P character position:
REPLACE(IN1:='ABCDE',IN2:='X',L:=2, P:=3) ;
equivalent to A := 'ABXE' ;
FIND Find the location of the first occurrence of the opening character of IN2 in IN1. If IN2 is not found, OUT:= 0。A := FIND(IN1:='ABCBC',IN2:='BC');
equivalent to A := 2 ;

The following table gives the functions related to the time data type.

If one of the functions evaluates outside the range of the output data type, a syntax error will occur.

Numeric and Connection Functions
Name Sign IN1 IN2 OUT
ADD + TIME TIME TIME
ADD_TIME + TIME TIME TIME
SUB - TIME TIME TIME
SUB_TIME - TIME TIME TIME
CONTACT_DATE_TOD DATE TIME_OF_DAY DATE_AND_TIME
Type Conversion Function
DT_TO_TOD
DT_TO_DATE

The selection and comparison functions listed in the following table can be applied to the input of the enumerated data type.

Name Sign
SEL
MUX
EQ =
NE <>

# 5.4.2 Function Blocks

A function block is a program organizational unit that produces one or more values when executed. You can create multiple named instances of a function block.

Each instance should have an associated identifier (instance name), a data structure containing its output and internal variables. The values of all output variables and necessary internal variables of that data structure will persist from one execution of the function block to the next; As a result, calling a function block with the same arguments (input variables) does not necessarily always produce the same output value.

Only input and output variables can be accessed outside of the function block instance, i.e., the internal variables of the function block should be hidden from the user of the function block.

Any function block that has already been declared can be used in declaring another function block or program type. The scope of a function block instance is local to the program organization unit it is instantiated, unless it is declared global in GVL.

If a function block is declared as an input variable in a VAR_INPUT declaration, or as an input-output variable in a VAR_IN_OUT declaration, the instance name of the function block instance can be used as an input parameter for functions and function blocks.

# 5.4.2.1 Function Block Representation and Declaration

Create a POU by right-clicking on the application-> the POU, selecting the POU type as the function block, and selecting the programming language used. For example, the following diagram defines a function block named myFB and writes the function block in ST language.

It is not allowed to assign values to the output variables of a function block unless it is inside a function block. Assigning values to input variables for function blocks is only allowed as part of function block calls. The unassigned input of a function block should retain its initial value or the last called value, if any. The following table summarizes the allowed usage of the input and output variables for function blocks, and the examples are shown in ST language.

Usage Internal function block External function block
Input read IF IN1 THEN ... Not allowed
Input assignment Not allowed FB_INST(IN1:=A,IN2:=B);
Output read OUT := OUT AND NOT IN2; C := FB_INST.OUT;
Output assignment OUT := 1; Not allowed
In-out read IF INOUT THEN ... IF FB1.INOUT THEN...
In-out assignment INOUT := OUT OR IN1; FB_INST(INOUT:=D);

Global variables defined in GVL can be declared by VAR_EXTERNAL, and the variable values of global variables can be modified within the function block.

There is no need to define additional EN and ENO parameters in the function block definition, and the corresponding logic will be automatically generated by the system.

# 5.4.2.2 The Function Block Executes the Control Logic

In the function block definition, the system provides an additional Boolean EN (Enable) input or ENO (Enable Out) output, similar to the following definition:

VAR_INPUT EN: BOOL := 1; END_VAR

VAR_OUTPUT ENO: BOOL; END_VAR

When using these two variables, the execution of the operation of the function block will be controlled according to the following rules:

  1. When a function block instance is called, if the value of EN is FALSE(0), the operation defined in the function block logic will not be executed, and the ENO will be set to FALSE by the system.
  2. If the value of EN is TRUE(1), ENO will be set to TRUE by the system, and the logical operation in the function block logic body will be executed;

According to the above rules, the FALSE value entered by EN can be used to "freeze" the operation of the relevant function block; That is, the output value does not change regardless of any other input value changes. When the EN input value becomes TRUE, the function block can resume normal operation. Each time a function block with an EN input of FALSE is called, the ENO output value is FALSE. When EN is TRUE, the TRUE value of ENO reflects the normal execution of the function block.

# 5.4.2.3 Standard Library Function Blocks

Standard function blocks can be overloaded and can have extensible input and output.

# 5.4.2.3.1 Bistable Elements

Bistable function blocks include set-priority function blocks (SR) and reset priority function blocks (RS).

# 5.4.2.3.2 Edge Detection

The behavior of the standard rising and falling edge detection function blocks corresponds to the following rules:

  1. After the Q output of the R_TRIG function block is converted from 0 to 1 in the CLK input, the value of BOOL#1 should be maintained from one execution of the function block to the next execution, and 0 should be returned on the next execution.
  2. After the Q output of the F_TRIG function block is converted from 1 to 0 in the CLK input, the Q value should remain at the BOOL#1 value and return 0 on the next execution from one execution to the next execution of the function block.

# 5.4.2.3.3 Counters

# 5.4.2.3.4 Timer

The graphical form of the standard timer function block is shown in the following table.

Description Graphic
***It is expressed as:
TP(Pulse Timer)
TON (Power-On Delay Timer)
TOF (Power-off Timer)

The operation of these function blocks should be defined according to the sequence diagram shown in the following table.

TP pulse timer
Power-on Delay (TON) timer
Power-off delay (TOF) timer

# 5.4.3 Procedure

The declaration and usage of a program is the same as that of a function block.

# 5.5 Configuration Elements

# 5.5.1 Configuration, Resources, and Access Paths

A configuration can be understood as a complete set of control systems for a set of equipment, and a configuration consists of one or more resources.

Resources are used to support the execution of tasks, and resources can contain multiple tasks, program organizational units, global variables, and so on.

Global variables are used to exchange data between program organizational units, and access paths provide an interface for external communication in the current configuration.

# 5.5.2 Tasks

A task is the scheduler of a program that is used to execute one or more programs. There are several types of tasks: loop, event, inertial coasting. Recurring tasks are performed at regular intervals; Event-based tasks start executing on the rising edge of the event variable. Tasks have different priorities, and tasks with higher priority can be interrupted by interrupting tasks with lower priority and preemptively executed.

# 5.6 Text Language

# 5.6.1 Textualization of Structure

Structured text (ST) is a high-level text language that can be used to describe the behavior of functions, function blocks, and programs. It consists of expressions and various statements.

# 5.6.1.1 Expressions

Expressions consist of operators and operands. The following table summarizes the operators for the ST language. The evaluation of the expression applies the operators to the operands in the order in which the operator precedence is defined as shown in the table. The operator with the highest priority in the expression should be evaluated first, followed by the operator with the second priority, and so on until the evaluation is complete. Operators with equal priority should be used in the order from left to right in the expression. For example, if A, B, C, and D are INT types with values of 1, 2, 3, and 4, respectively, then A+B-CABS(D) will be calculated as -9, and (A+B-C)*ABS(D) will be calculated as 0.

When an operator has two operands, the leftmost operand should be calculated first. For example, in the expression SIN(A)*COS(B), the value of SIN(A) will be evaluated first, followed by COS(B), and finally the result of the multiplication will be evaluated.

The following situations are considered syntax errors when performing an operation:

  1. The divisor is 0
  2. The operand is not the correct data type for that operation.
  3. The result of a numerical operation is outside the range of values for its data type.

Boolean expressions can only be evaluated within the range necessary to determine the resulting value. For example, in the expression (A>B) & (C<D), if the preceding condition (A>B) is FALSE, then it can be determined that the value of the entire expression (A>B) & (C<D) is FALSE, and the expression (C<D) is short-circuited and will not be evaluated.

A function should be called as an element of an expression, which consists of a list of arguments followed by parentheses by the function name.

# 5.6.1.2 Operators

Operator Sign Priority
brackets"()" (expression) High
function call Identifier (parameter list)
negative -
NOT
exponentiation **
multiplication
division
summation
*
/
MOD
addition
subtraction
+
-
comparison <,>,<=,>=
equal to
not equal to
=
<>
boolean and
boolean and
&
AND
Boolean XOR XOR
Boolean or OR Low

# 5.6.1.3 Statements

The following table lists the statement formats supported by the ST language, and each statement needs to end with a semicolon.

Statement Example
Assignment A := B; CV := CV+1; C := SIN(X);
+=/-= A += B; equal to A := A + B;
Function block invocation and function block output CMD_TMR(IN:=%IX5, PT:=T#300ms) ;
A := CMD_TMR.Q ;
RETURN RETURN ;
IF D := BB - 4AC ;
IF D < 0.0 THEN NROOTS := 0 ;
ELSIF D = 0.0 THEN
NROOTS := 1 ;
X1 := - B/(2.0
A) ;
ELSE
NROOTS := 2 ;
X1 := (- B + SQRT(D))/(2.0A) ;
X2 := (- B - SQRT(D))/(2.0
A) ;
END_IF ;
CASE TW := BCD_TO_INT(THUMBWHEEL);
TW_ERROR := 0;
CASE TW OF
1,5: DISPLAY := OVEN_TEMP;
2: DISPLAY := MOTOR_SPEED;
3: DISPLAY := GROSS - TARE;
4,6..10: DISPLAY := STATUS(TW - 4);
ELSE DISPLAY := 0 ;
TW_ERROR := 1;
END_CASE;
QW100 := INT_TO_BCD(DISPLAY);
FOR J := 101 ;
FOR I := 1 TO 100 BY 2 DO
IF WORDS[I] = 'KEY' THEN
J := I ;
EXIT ;
END_IF ;
END_FOR ;
WHILE J := 1;WHILE J <= 100 & WORDS[J] <> 'KEY' DO
J := J+2 ;
END_WHILE ;
REPEAT J := -1 ;
REPEAT
J := J+2 ;
UNTIL J = 101 OR WORDS[J] = 'KEY'
END_REPEAT ;
EXIT EXIT ;
Empty ;

Assignment statements

An assignment statement replaces the current value of a single or multiple element variables with the result of an expression evaluation. The assignment statement should contain a variable on the left, followed by the assignment operator ":=", and finally the expression that asks for the value. For example, the statement A:= B; If both are of type INT, the individual data value of variable A will be replaced with the current value of variable B. However, if both A and B are struct types, then the values of all elements of the structured variable A will be replaced by the current values of the corresponding elements of variable B.

Assignment statements can also be used to assign a function return value by placing the function name to the left of the ST statement assignment operator. The return value of the function should be the result of the last assignment. The function definition must contain at least one such assignment to determine the return value, otherwise the function will return the default value of the function return value type.

Functions and function blocks control statements

Function and function block control statements consist of calling functions or function block statements. Return control to the calling entity at the end of the function or function block.

Function evaluation should be used as part of expression evaluation; A function block invocation statement consists of a function block instance name followed by a list of parameters in parentheses.

A RETURN statement can exit a function, function block, or program in advance.

Select statement

The selection statement includes an IF statement and a CASE statement. A selection statement selects a block (or set) of statements that executes it based on the criteria specified. An example of a choice statement is given in the table above.

The IF statement specifies that a set of statements is executed only when the associated Boolean expression evaluates to 1 (TRUE). If the condition is false, no statement is executed, or the block of the statement after the ELSE keyword is executed (or the statement after the ELSIF keyword is executed, if the associated Boolean condition is true).

A CASE statement consists of an expression and a list of statement groups that evaluate to variables of type ANY_INT or enumerated data type, each of which is marked by one or more integers or enumerated values or integer ranges, as the case may be. It specifies the execution of the first set of statements, one of which contains the calculated value of the variable. If the value of the variable does not appear in the range of any CASE, the sequence of statements following the ELSE keyword is executed if it appears in the CASE statement. Otherwise, no statement sequence is executed.

Circular statements

A circular statement is a set of related statements that are to be executed repeatedly. If the number of loops can be determined in advance, it is recommended to use the FOR statement. Otherwise, you can use a WHILE or REPEAT loop statement.

The EXIT statement should be used to end the loop before the loop termination condition is met.

When the EXIT statement is in a nested loop construct, EXIT should terminate the innermost loop where EXIT is located, i.e., EXIT should be passed to the next statement after the first loop terminator (END_FOR, END_WHILE, or END_REPEAT) after the EXIT statement. For example, after executing the statement shown in the following image, if the value of the Boolean variable FLAG is 0, then the value of the variable SUM should be 15, and if FLAG=1, it should be 6.

SUM := 0 ;
FOR I := 1 TO 3 DO
FOR J := 1 TO 2 DO
IF FLAG THEN EXIT ; END_IF
SUM := SUM + J ;
END_FOR ;
SUM := SUM + I ;
END_FOR ;

The FOR statement indicates that a sequence of statements should be executed repeatedly until the keyword is END_FOR, while assigning a series of values to the FOR loop control variable. The control variable, initial value, and final value must be expressions of the same integer type (for example, SINT, INT, or DINT) and cannot be changed by any repetitive statements. The FOR statement increments the control variable from the initial value up or down to the final value, and the increment is determined by the value of the expression; This value defaults to 1. The determination of the termination condition is made before the start of each loop, so if the initial value exceeds the final value, the statement sequence is not executed.

The WHILE statement will repeat the sequence of statements that preceded the END_WHILE keyword until the associated Boolean expression is FALSE. If the initial value of the expression is FALSE, this set of statements is not executed at all.

The REPEAT statement repeats the sequence of statements that preceded the END_REPEAT keyword until the associated Boolean expression is FALSE. If the initial value of the expression is FALSE, this set of statements will also be executed once.

# 5.7 Graphical Programming

# 5.7.1 Ladder Diagram (LD)/Function Block Diagram (FBD)

# 5.7.1.1 Connecting Cables

The connection line is used to connect the input and output ports of the graphic elements and control the execution logic of the PLC program. In the IEC61131-3 XML specification, the array of coordinates of the connection consists of [rear input port coordinates,..., front output port coordinates].

In the IDE, when the input and output types of the connection elements match, the connection line color is "gray". When the types do not match, the connection line is displayed in red.

When dragging an element from the right toolbox onto a port for an element in the canvas, the port is highlighted in purple, releasing the dragged element. When connecting an input port, a line is created by default that connects to the first output port of the dragged element. When connecting an output port, a connection to the first input port of the dragged element is created by default. When you drag and drop variable elements to automatically connect, the variable will automatically be converted into an input or output variable.

# 5.7.1.2 Designation

A designator name consists of an identifier that contains letters, numbers, or an unsigned decimal integer. The network is marked by the label, and the corresponding network label is used to execute the logical jump in the network. By default, a marker element is added to the coordinates of the upper left corner of the network, and the jump is executed from the starting position of the network.

When you drag and drop a grid in the IDE, the coordinates of the marker cannot be modified. You can modify the name of the label by clicking on it.

# 5.7.1.3 Segment (Network)

The net contains network labels, annotations, and graphic elements. By grouping the execution logic, a segment network is formed. Each segment of the network should have a unique designator. Compared with the FBD function block diagram, the LD ladder diagram should also have contacts, contacts, coils, and left and right power lines.

When you add an LD/FBD program to the IDE, a grid is added by default. Drag and drop a new grid from the right toolbox, or add a new grid above or below the current grid via the context menu on the selected grid.

# 5.7.1.4 Contacts

Contacts are used to read Boolean values from variables and are of four types:

  1. Normally Open Contacts: Right End = Left End AND Contact Variable
  2. Normally closed contact: right end = left end AND NOT contact variable
  3. Rising edge contact: if left AND "contact variable was FALSE in last cycle" AND "contact variable is TRUE in current cycle", right = TRUE; else: right = FALSE
  4. Falling edge contact: if left end AND "contact variable was TRUE in last cycle" AND "contact variable is FALSE in current cycle", right end = TRUE ; else: right end = FALSE

# 5.7.1.5 Coils

The coil is used to output Boolean values to writable variables, including 6 types

  1. Normal Coil: Writes a boolean value to the left end
  2. Nevert coil: Write the negation value at the left end
  3. Set coil: write TRUE when the left end is TRUE; When the left end is FALSE, the value of the previous period is maintained
  4. Reset coil: write FALSE when the left end is TRUE; When the left end is FALSE, the value of the previous period is maintained
  5. Rising edge coil:if left end AND "contact variable was FALSE in the previous cycle" AND "contact variable is TRUE in the current cycle": write TRUE; else: stay unchanged.
  6. Falling edge coil: if left end AND "contact variable was TRUE in the previous cycle" AND "contact variable is FALSE in the current cycle": write TRUE; else: stay unchanged

# 5.7.1.6 Left and Right Power Cords

The ladder diagram is very similar to the circuit diagram in the electrical control system, when analyzing the logical relationship of the ladder diagram, in order to borrow the analysis method of the relay circuit diagram, it can be imagined that there is a left positive and right negative DC power supply voltage between the left and right power lines, and there is energy flow between the power lines flowing from left to right, and the right bus can not be drawn.

# 5.7.1.7 Implementation Control(control flow)

When using functions based on LD graphics, you can use EN and ENO control execution. The function will only be executed if EN is TRUE; If the function is executed, the ENO output is TRUE by default, and if the execution process is abnormal, the ENO output is FALSE.

IEC61131-3 prohibits recursive calls, and does not allow the same type of POU to be called in a POU, which will make the PLC system unable to calculate the memory space required for runtime.

# 5.7.1.8 Use of Functions and Function Blocks

Functions have a return value type, and assigning a value to the function name at the time of declaration indicates that the return value is output, and it does not need to be instantiated when used, and can be used directly. Some mathematical operations such as ADD, MAX, etc., can adjust the number of input parameters.

When using a function block, you need to declare a local variable of this type as the instance name. When writing a user-defined function block, add input and output variables as the input and output of the function block.

By modifying the priority, you can adjust the order in which elements are executed.

In the IDE, add the function blocks or functions that need to be used in the toolbox, and modify the properties by double-clicking on the element.

Adjust the number of input parameters for mathematical operations such as ADD and MAX by modifying the input attributes; By modifying the execution control, enable or disable the EN and ENO enable ports of functions and function blocks. Adjust the order in which elements are executed by modifying the priority.

# 5.7.1.9 Jump Execution

Bind the designator of the jump network to the jump symbol, and when the logic is executed, jump to the start of the network to start the execution.

# 5.8 C/CPP

# 5.8.1 POU Specification-2023 Written in C/CPP Language

When creating a POU, select the C/C++ (CPP) option in the programming language options, as shown in the following figure, and then write the main code of the POU in C/CPP language. This is an extension of the five programming languages supported by the IEC61131-3 standard.

Open the POU you just created, as shown in the figure below, unlike POUs created in other IEC programming languages, POUs created in C/CPP programming languages have three editing areas. As shown in the figure below, they are:

# 5.8.2 C/CPP Language POU General Specification

Create a POU in the C/CPP programming language as an extension to the IEC61131-3 standard. POU creators must comply with the following specifications:

# 5.8.3 Defining and Using Temporary Variables in the C/CPP Body Logical Area

C/CPP temporary variables are variables defined in the main logical area, which can be C/CPP data type variables (such as int , bool , or std::string) or IEC basic variable types (such as INT , BOOL), for example, in the logical body area there are the following definitions:

When using variables a and b, it is sufficient to meet the standard C/C++ specification, such as:

# 5.8.4 Use the Variables Defined in the Variable Definition Area in the C/CPP Body Logic Zone

The software provides functions such as writing variables, forcing variables, and monitoring variables. These variables need to be defined in the variable definition area. For ST/LD/FBD programming languages, they do not allow variables to be defined in the main logical area, so for ST/LD/FBD programming languages, all variables can be monitored, written, and enforced. However, the POU written in C/CPP allows temporary variables to be defined in the main logical area, but the variables defined in the main logical area cannot be monitored, written, and coerced, and the variables defined in the main logical area can only be temporary, which will be recreated and initialized every time the execution is completed, and the variable memory is released after the execution. It is recommended that programmers create POUs in C/CPP that are consistent with ST/LD/FBD and do not define IEC temporary variables in the main logic area.

The variables defined in the variable definition area can be divided into the following categories according to their types:

  • IEC base type variables
  • IEC enumeration type variables
  • IEC array type variables
  • IEC structure type variables
  • IEC Function Block Type Variables

# 5.8.4.1 IEC Base Type Variables

IEC base type variables refer to the variables declared in the variable declaration area, and the variable types are all IEC base data types (BOOL, SINT, etc.), except for the four time-related variables (TIME, TIME_OF_DAY, DATE and DATE_AND_TIME) and string (STRING) variables, the other basic types of variables operate the same as temporary variables. The only thing to note is that the POUs created by the C/CPP language are case-sensitive, for example, there is a : INT in the variable definition area; With such a definition, only variables such as a (note case) can be used as variable names in the main logical area. For example, we create a function called cppFunc, where there are two variables of type INT, a and b, and the function returns the absolute value of the difference between the two variables.

For more information about the function definitions in C/CPP language, see Function Definitions. Here is an example of how to use the variables of the IEC base type.

# 5.8.4.2 Time-dependent Data Types

There are four types of time-dependent data for IEC:

  • TIME: Indicates a period of time
  • TIME_OF_DAY:Indicates the time of day
  • DATE:Indicates date
  • DATE_AND_TIME: Indicates date and time

The assignment of time-related types is different from initialization, and the initialization of time-type variables in the variable definition area is consistent with the IEC standard, as shown in the figure below, the variable varTime of type TIME is defined, and the initial value is T#3d2m20s; However, to assign a variable value to the main logical area, you need to use TIME_CPP library functions, such as varTime = TIME_CPP(1, 0, 20, 2, 0, 3);

The following table describes the library functions of the time type:

# 5.8.4.3 The String Type Variables

Different from initializing string types, initializing string types in the variable definition area is consistent with the IEC standard, and all string initial calues are inclosed in single quotes'. However, when using string literals in the C/CPP body logical area, double quotation marks are used, which needs to be noted here. Jishan provides two methods for variables of type string: c_str() and size(), which return a string of type C/CPP and the length of the returned string, respectively. For example, in the following example, first use the string cppStr of type std::string to get the value of str, and then concatenate the string cppStr with "hello, jishan!", and finally assign cppStr to str, where the value of the final str should be "this is a test. hello, jishan!"

# 5.8.4.4 IEC Enumeration Type Variables

For enumerated variables, initializing the enumerated variables in the variable definition area must conform to the ICE standard. The following structure is required to use the value of an enumerated variable in the main logical area:

Enumeration Type: Enumeration value

For example, if you have the following enumeration type myEnum definition, the enumeration has three values aa, bb, and cc.

Then in the variable definition area and the main logic area, you need to use the enumeration type of variable values as follows. You can write myEnum#aa or AA directly when assigning the initial value to the variable definition area (again, the IEC standard is case-insensitive), but when using the enumeration type in the main logical area, you must use the MYENUM::AA form. Both the type and the value need to be capitalized.

# 5.8.4.5 IEC Arry Type Variables

For array-type variables, the variables of the array type must be initialized in the variable definition area to comply with IEC standards, and the following structure needs to be used when using array-type variables in the main logical area:

array variables.table[1D subscript - dimension lower limit value][2D subscript - dimension lower limit value]...

For example:

# 5.8.4.6 IEC Structure Type Variables

For structure variables, the variables that initialize the structure type in the variable definition area must comply with the IEC standard, and the following structures need to be used when using structure variables in the main logical area:

# 5.8.4.7 IEC Function Block Type Variables

For FB variables, the FB variables must be initialized in the variable definition area to comply with IEC standards, and the following structure must be used when using FB variables in the main logical area:

# 5.8.5 Creating and Using C/CPP Function Type POUs

  1. Create a function written in C/CPP

By right-clicking ->POU on the application of the Jishan IDE, the POU creation dialog box will pop up. As shown in the figure below:

Enter the name of the function to be created (cppFunc) in the POU name, select the POU type as function, select C/CPP as the programming language, and select the return value type as needed. Click Confirm to create the function cppFunc, and the return value is INT, define the interface variables required by the function in the variable definition area, and write the logic of the function in the main logic area. It should be noted that, like other programming languages of IEC standards, in functions written in C/CPP language, the function name is the return value of the function, the function name needs to be assigned, and the function name belongs to the IEC element, so it needs to be capitalized.

For example, in the figure below, the function has two input parameters, named a and b, and this function returns the absolute value of the difference between the two input parameters.

  1. Functions are called in a POU written in C/CPP

There are two ways to call a function in the body logic in C/CPP:

For example, if you call the functions created above in other POUs, you need to use the following two forms:

The premise is that in the variable definition area, the variables of type INT, LocalVar1 and LocalVar2, are defined in advance;

In the example given here, the function is created with only input variables. When a function is created, when a function is created, the output variables (parameters) of the function need to be passed to the called function by passing an address.

# 5.8.6 Create a POU With the C/CPP Function Block Type

  1. Create function blocks written in C/CPP

If you want to create a function block in C/CPP, you can create a function block by selecting the POU type as Function Block and entering the name of the function block in the POU Name dialog box. In the following example, the function block cppFB is created, as follows:

In the above example, the function block has two input parameters in1 and in2, and one output parameter out, and the function of the function block is to assign the sum of the two inputs to the output.

  1. Use function blocks in POUs written in C/CPP

When using a function block in a POU written in C/CPP, you first need to define the variables of the function block type. When calling the function block logic, you need to first assign the input variables of the function block, then call the Body() method of the function block, and finally use the output variables of the function block. This is shown in the section "Variables for IEC function block types".

Only the input, output, and input/output variables of a function block can be accessed outside the function block.

If the function block contains input and output variables, when using it, you need to assign the input and output variables first, then call the function block logic, and finally assign the input and output variables to the current variable to implement the input and output logic. For example, if there is an INT input/output variable inouVar in the function block cppFB, then it needs to be called in the following way.

Note: The operation permissions of the variables of the function block are as follows:

Usage Function block internal Function block external
INPUT variable read allowed not allowed
INPUT variable write not allowed allowed
OUTPUT varialbe read allowed allowed
OUTPUT variable write allowed not allowed
INOUT variable read allowed allowed
INOUT variable write allowed allowed

# 5.8.7 Creating and Using of C/CPP Program Type POUs

When creating a program in C/CPP, the only difference is that the POU type is changed to the program.

The use of programs can only instantiate programs in a task, and we do not allow programs to call each other for the time being.

# 5.9 Sequential Function Chart Language (SFC)

The Sequential Function Chart (SFC) is defined in the IEC 61131-3 standard as a common element of the programming language. It is a programming method that describes the processes, functions and characteristics of a sequential control system using a combination of textual descriptions and graphical symbols. It can be used as either a text-based or a graphical programming language, but it is usually categorized as a graphical programming language. Thus, IEC 61131-3 is commonly referred to as having three graphical programming languages.

The SFC editor is shown below

The SFC element provides a means of dividing a programmable controller program organization unit (POU) into a set of steps and transitions interconnected by directional lines. Associated with each step is a set of actions and associated with each transition is a transition condition.

Since SFC elements are required to store state information, the only program organizational units that can be constructed using these elements are function blocks and procedures.

# 5.9.1 SFC Components

The components of SFC include step, transition, action block, jump, divergent branch, and convergent branch.

The shape of each element of the SFC and its characteristics are shown in the table below.

col1 col2
Step
Initial step

Step
Transition alt text
Action Block alt text
Jump alt text
Divergent branch alt text
Selective divergence
alt text
Synchronous divergence
Convergent branch alt text
Selective convergence
alt text
Synchronous convergence

# 5.9.2 Step

Step represents a major function in an overall industrial process. It can be a specific time, a phase or an action performed by several devices. The input and output behavior of the program organization unit follows the execution action determined by the associated execution of the step. Step has only two states: active and inactive. At any moment, the state of the POU is defined by the set of active steps and the values of their internal and output variables.

Initial step

Each SFC language POU starts with an initial step, and the POU run always evolves from the initial step downwards. The initial step is an indispensable component of the SFC language POU and cannot be deleted.

The initial step is shown below. alt text

Step

SFC POU supports the configuration of multiple common steps, which can be added and deleted, and each common step can be added with an entry action, an exit action, an associated step action, and an associated project management tree action.

The common step is shown below. alt text

Activation step

When a step is active, online you can see the color of the step's border change to red and the action associated with the current step is called for execution.

As shown below. alt text

Activation step start time as step name.T(TIME):The current start time acquired by the step when the step was first activated.

Activate step runtime as step name.T(TIME): When the step has just been activated, the step gets the current start time(step name.T). And the running time of the step starts to accumulate, and the running time of the step is reset to T#0s when it runs until the step is de-activated.As shown above, step1 is active and ran T#2s, then Step1.T:=T#2s.

The next state of the step is the step name.X(BOOL): step activity flag, when the value is TRUE, it indicates that the next scheduling cycle of the step is active, when the value is FALSE, it indicates that the next scheduling cycle of the step is inactive.

The current state of the step is step name.X(BOOL): step activity flag, when the value is TRUE, it indicates that the current scheduling cycle of the step is active, and when the value is FALSE, it indicates that the current scheduling cycle of the step is inactive, as shown in the above figure Step1.X:=TRUE.

Step name, step runtime, and step status are only valid in the current POU and cannot be referenced in other POUs.

Step name constraint rules:

  1. the step name must satisfy the definition rules for variable names
  2. the step name cannot be the same as the variable name in this SFC POU variable area.
  3. the step name must not be a duplicate of the action.

# 5.9.3 Transition

There are so-called conversions between steps. The value of the conversion condition must be a BOOL value (TRUE or FALSE). Thus, it can be a BOOL variable, a BOOL address, or a BOOL constant. A step conversion is performed only if the step's conversion condition is TRUE.

The individual transfer conditions are shown below. alt text

Transfer constraint rules:

  1. If the conversion is associated with a reference POU, the variable area defined by the SFC conversion reference POU cannot define a variable with the transferred name.
  2. If the conversion is already associated with a POU, the SFC POU cannot add an action with the same transfer name to the project management tree.
  3. If the SFC POU adds an action with the same conversion name to the project management tree, the conversion cannot be associated with a POU, and the SFC POU cannot define a variable with the same conversion name.
  4. If multiple conversions have the same name (case insensitive), the same POU is associated with the conversion.

# 5.9.4 Action Block

The action block consists of a qualifier and an action name, the qualifier includes a time limiter and a non-time limiter, the qualifier determines the execution mode of the action associated with this action name, and the action associated with the action name is the action added to the SFC POU tree.

The action block is shown below. alt text

The SFC qualifiers are shown in the following table:

Qualifiers Meaning Description
- Non-stored (null qualifier) Activate as long as the step activates the action, deactivate if the step deactivates
N Non-stored Activate as long as the step activates the action, deactivate as long as the step deactivates the action
R Overriding Reset Reset as long as the step is active, the step disabled state remains until the next activation
S Set (Stored) Set as long as the step is active, the step failed state is held until the next activation
L Time Limited The action is initiated when the step is active, and the action will continue until the step is inactive or the set time has expired
D time Delayed The delayer starts after activation. If the step is still active after the delay, the action starts until the step is deactivated
P Pulse When the step is activated for the first time, only one cycle is executed and then it is turned off
SD Stored and time Delayed After the delay the action starts and it will continue to hold until restarted
DS Delayed and Stored If the step is still active after the specified event delay, the action starts and continues to hold until restarted
SL Stored and time Limited The action starts after the step is activated and continues for a certain amount of time or restarts
P1 Pulse (rising edge) Execute on entry step and only once
P0 Pulse (falling edge) Execute at exit step and only once

NOTE: The qualifiers L, D, SD, DS, and SL shall have an associated duration of type TIME.

The action is named Project Management Tree the action hanging underneath this SFC POU, as shown below. alt text

The SFC POU downstream action can be realized by the following steps

  1. Right click on the POU in SFC language.
  2. Select [Add Action] from the pop-up right-click menu.
  3. The Add Action dialog box will pop up.
  4. Name the action and click [OK].

The action supports ST, FBD, LD, SFC, and CPP languages.

# 5.9.5 Jump

Jump is actually an operation that connects to a step with a jump symbol or to a parallel branch with a label, and can be used to make the SFC cyclic by means of this component; the POU edited in the SFC language contains at least one jump. Jump is a program execution that can unconditionally go to the label associated with the jump for execution, and can transfer directly from a step to another step inside or outside the current branch or to a parallel branch with a label. Jump is used in place of a step and is executed by the transfer at its location; Jump is executed when the transfer condition is satisfied.

The jump element is shown below. alt text

# 5.9.6 Divergent Branch

SFC divergence branch synchronized divergence branch and selective divergence branch.

Selective divergent branch

alt text When the action output A of step n is executed, the step (n+1 or n+2) in which the first of the conversion conditions b or c is established is selected, and the action of the changed step is executed. When both conversion conditions are established, the left conversion condition takes priority and step n is invalidated. After conversion, each step of the selected column is executed in turn until the merged position is reached.

Synchronous divergent branch

alt text When the action output A of step n is executed, step n+1 and step n+3 are activated at the same time if the transition condition b is valid, and step n is deactivated. Activate step n+2 when conversion condition c is valid, and activate step n+4 when conversion condition d is valid.

# 5.9.7 Convergent Branch

SFC Convergence Branch Parallels Convergence Branch and Selective Convergence Branch.

Selective Convergence Branch

alt text If the transition condition b or c holds for the execution column in the branch, then invalidate execution step n or n+1 and activate step n+2.

synchronous convergence branch

alt text When the action output A of step n and the action output B of step n+1 are executed, if the transition condition b and the transition condition c both hold, the wait step is activated and step n and step n+1 are invalidated. A wait step is a step used to synchronize the steps of parallel processing by converting all the steps of parallel processing to a wait step, checking the conversion condition d, and activating step n+2 if the conversion condition d holds. The wait step is treated as a virtual step, so it doesn't matter if no action is output.

# 5.9.8 Rules for The Evolution of Step

Step progression in the SFC programming language is related to the execution of actions and the realization of transformations. The rules for step evolution (progression) are as follows:

  1. The initial state is determined by the initialization of the program or function block containing the network at the initial step of the active state.
  2. The transition is an enabling transition when all preceding steps of that state are active steps. The transition occurs only when the transition condition of the is-enabled transition is TRUE, thus enabling step evolution
  3. Realization of a transition that makes inactive the predecessor step connected to the transition and makes active all subsequent steps connected to the transition
  4. Sequences in which multiple steps are made active at the same time are called synchronization sequences. Each of their summations is independent, and for this reason it is common to use horizontal lines to represent branches and mergers of synchronized sequences.
  5. Step/transition and transition/step shall always be maintained in the SFC element connection, i.e.:
  • Two steps can never be directly connected; they are always separated by a transformation.
  • Two conversions can never be directly connected; they are always separated by steps.
  1. The evolution of steps begins with the initial step. Therefore, the initial step should be the active step at the beginning of program execution.
  2. The action control function block connected to the step is executed only at the active step of the step, and the execution of the actions is determined according to the output Q of the action control block; when Q is TRUE, these actions are executed; when Q is FALSE, these actions are not executed.
  3. During the execution of an action, subsequent conversions are evaluated, and when the conversion conditions are met, the realization of the conversion occurs and the evolution of the step is realized, so that the step evolves according to the SFC program.
  4. Selecting a branch of the sequence, there are multiple conversion conditions, and they are prioritized. When no priority is set, the conversion conditions are judged from left to right. When the priority is set, the number indicates the priority, and the smaller the data, the higher the priority.
  5. Step activation takes some time, likewise the realization of the conversion takes some time. The time required varies from PLC product to PLC product. Therefore, when the action connected to the active step is limited to the delay function, the process of realizing the conversion may occur when the active step is about to activate the action, and thus the phenomenon that there is still an action being executed in the inactive step should be considered in the design.