Defining and configuring an application object database of controlled station

Application objects = single points, double points, measured values, short floating point values, etc.

In this sample the commands were configured such that the process data for the commands are located in the same memory area as the information data in monitoring direction, although in a different byte and bit offset. If required the commands may have the same byte/bit offset as the information in monitoring direction.

Sample:

C_SC_NA_1 with IOA = 10 on the same byte/bit offset as M_SP_NA_1 with IOA = 100 (both byte offset = 100 and bit offset = 0). In this case a value change due to a command from the control station will result in a transmission of the M_SP_NA_1 with the object address 100 and cause of transfer <11> (returned by remote command).

As an example we will configure the following application objects as part of the introductory project:

Array element

ASDU identifier

Object address
IOA

Group configuration parameter

Base time multiplier

PLC process data area

Offset
Byte

Offset
Bit

Process data width

in the TwinCAT PLC

0

M_SP_NA_1

100

General interrogation

0

Flags

100

0

1-bit

1

M_SP_NA_1

101

General interrogation

0

Flags

100

1

1-bit

2

M_SP_TB_1

102

General interrogation

0

Flags

100

2

1-bit

3

M_DP_NA_1

200

General interrogation

0

Flags

200

0

2 bits

4

M_DP_NA_1

201

General interrogation

0

Flags

200

2

2 bits

5

M_DP_TB_1

202

General interrogation

0

Flags

200

4

2 bits

6

M_ST_NA_1

300

General interrogation

0

Flags

300

0

1 byte

7

M_ST_NA_1

301

General interrogation

0

Flags

301

0

1 byte

8

M_ST_TB_1

302

General interrogation

0

Flags

302

0

1 byte

9

M_BO_NA_1

400

General interrogation

0

Flags

400

0

4 bytes

10

M_BO_NA_1

401

General interrogation

0

Flags

404

0

4 bytes

11

M_BO_TB_1

402

General interrogation

0

Flags

408

0

4 bytes

12

M_ME_NA_1

500

General interrogation

0

Flags

500

0

2 bytes

13

M_ME_NA_1

501

General interrogation

0

Flags

502

0

2 bytes

14

M_ME_TD_1

502

General interrogation

0

Flags

504

0

2 bytes

15

M_ME_NB_1

600

General interrogation

0

Flags

600

0

2 bytes

16

M_ME_NB_1

601

General interrogation

0

Flags

602

0

2 bytes

17

M_ME_TE_1

602

General interrogation

0

Flags

604

0

2 bytes

18

M_ME_NC_1

700

General interrogation

0

Flags

700

0

4 bytes

19

M_ME_NC_1

701

General interrogation

0

Flags

704

0

4 bytes

20

M_ME_TF_1

702

General interrogation

0

Flags

708

0

4 bytes

21

M_IT_NA_1

800

General counter interrogation and Mode A (local freeze with spontaneous transmission every 15 s)

0

Flags

800

0

4 bytes

22

M_IT_NA_1

801

General counter interrogation and Mode A

(local freeze with spontaneous transmission every 15 s)

0

Flags

804

0

4 bytes

23

M_IT_TB_1

802

General counter interrogation and Mode A

(local freeze with spontaneous transmission every 15 s)

0

Flags

808

0

4 bytes

Commands

 

 

 

 

 

 

 

 

24

C_SC_NA_1

10

-

0

Flags

2100

0

1-bit

25

C_SC_NA_1

11

-

0

Flags

2100

1

1-bit

26

C_SC_TA_1

12

-

0

Flags

2100

2

1-bit

27

C_DC_NA_1

20

-

0

Flags

2200

0

2-bit

28

C_DC_NA_1

21

-

0

Flags

2200

2

2-bit

29

C_DC_TA_1

22

-

0

Flags

2200

4

2-bit

30

C_RC_NA_1

30

-

0

Flags

2300

0

1 byte

31

C_RC_NA_1

31

-

0

Flags

2301

0

1 byte

32

C_RC_TA_1

32

-

0

Flags

2302

0

1 byte

33

C_BO_NA_1

40

-

0

Flags

2400

0

4 bytes

34

C_BO_NA_1

41

-

0

Flags

2404

0

4 bytes

35

C_BO_TA_1

42

-

0

Flags

2408

0

4 bytes

36

C_SE_NA_1

50

-

0

Flags

2500

0

2 bytes

37

C_SE_NA_1

51

-

0

Flags

2502

0

2 bytes

38

C_SE_TA_1

52

-

0

Flags

2504

0

2 bytes

39

C_SE_NB_1

60

-

0

Flags

2600

0

2 bytes

40

C_SE_NB_1

61

-

0

Flags

2602

0

2 bytes

41

C_SE_TB_1

62

-

0

Flags

2604

0

2 bytes

42

C_SE_NC_1

70

-

0

Flags

2700

0

4 bytes

43

C_SE_NC_1

71

-

0

Flags

2704

0

4 bytes

44

C_SE_TC_1

72

-

0

Flags

2708

0

4 bytes

 

Declaring a database variable

The application object database is an array variable of type ST_IEC870_5_101AODBEntry

Each array element corresponds to an application object. The maximum number of application objects is freely selectable and is only limited by the available memory. During PLC programming you have to specify a constant maximum number. The maximum number of application objects cannot be changed at runtime.

In our sample 50 application objects are declared. This number is sufficient for most applications. Please note that many application objects require adequate memory and runtime resources.

Define the following variable in MAIN:

PROGRAM MAIN
VAR
     AODB : ARRAY[0..49] OF ST_IEC870_5_101AODBEntry; 
END_VAR

Configuring application objects

The object type (M_SP_NA_1, M_DP_NA_1, M_ST_NA_1 etc.), the object address and further object parameters are specified during configuration of the individual application objects.

The required application objects are configured during program runtime. Each application object (database array element) is configured by calling the F_iecInitAOEntry function once. The array element to be configured is transferred to the function via VAR_IN_OUT. Configuration is usually carried out once during PLC program start-up via an Init routine. The F_iecInitAOEntry function expects the following function parameters (from left to right):

FUNCTION F_iecInitAOEntry : UDINT
VAR_INPUT
    eType       : E_IEC870_5_101TcTypeID;
    objAddr     : DWORD := 0;
    group       : DWORD := 0;
    multiplier  : BYTE := 0;
    ioMapType   : E_IEC870_5_;
    byteOffs    : UDINT := 0;
    bitOffs     : UDINT := 0;
END_VAR
VAR_IN_OUT
    dbEntry     : ST_IEC870_5_101AODBEntry;
END_VAR

eType: application object type (ASDU identifier, e.g.: M_SP_NA_1 for single point or M_DP_NA_1 for double point). Please note that only the ASDU types listed in the compatibility list can be used. Invalid types are ignored.

objAddr: object address, e.g. 100. Each application object should be configured with a unique address.

group: group configuration parameters. The available group parameters are defined as constants and can be combined with an OR operator. E.g.: IEC870_GRP_INROGEN OR IEC870_GRP_PERCYC.

A description of all group configuration parameters can be found here

mutiplier: base time multiplier for cyclic/periodic data transfer (0=deactivated). The base time is configured via the system parameters. If the base time was set to T#10 s, and the multiplier to 2, for example, the periodic/cyclic data of the application object are sent every 20 seconds.

ioMapType: This parameter defines from or in which process data area of the TwinCAT PLC the IEC process data are to be mapped at runtime (inputs, outputs, memory, data).

byteOffs: process data area byte offset;

bitOffs: process data area bit offset;

dbEntry: application object to be configured (a database variable array element that is transferred to the function via VAR_IN_OUT).

In order to configure the application objects during program start-up, add the following PLC code in MAIN:

PROGRAM MAIN
VAR
    AODB            : ARRAY[0..49] OF ST_IEC870_5_101AODBEntry; 
     init           : BOOL := TRUE;
    initError       : UDINT;
END_VAR
IF init THEN
    init := FALSE;

  (* Monitored Single Points *)
 initError := F_iecInitAOEntry( M_SP_NA_1, 100, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 0, AODB[0] );
    initError := F_iecInitAOEntry( M_SP_NA_1, 101, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 1, AODB[1] );
    initError := F_iecInitAOEntry( M_SP_TB_1, 102, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 100, 2, AODB[2]);
  (* Double Points*)
 initError := F_iecInitAOEntry( M_DP_NA_1, 200, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 0, AODB[3] );
    initError := F_iecInitAOEntry( M_DP_NA_1, 201, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 2, AODB[4] );
    initError := F_iecInitAOEntry( M_DP_TB_1, 202, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 200, 4, AODB[5] );
  (* Regulating step value *)
 initError := F_iecInitAOEntry( M_ST_NA_1, 300, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 300, 0, AODB[6] );
    initError := F_iecInitAOEntry( M_ST_NA_1, 301, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 301, 0, AODB[7] );
    initError := F_iecInitAOEntry( M_ST_TB_1, 302, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 302, 0, AODB[8] );
  (* 32 bit string*)
 initError := F_iecInitAOEntry( M_BO_NA_1, 400, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 400, 0, AODB[9] );
    initError := F_iecInitAOEntry( M_BO_NA_1, 401, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 404, 0, AODB[10] );
    initError := F_iecInitAOEntry( M_BO_TB_1, 402, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 408, 0, AODB[11] );
  (* Measured value, normalized value *)
 initError := F_iecInitAOEntry( M_ME_NA_1, 500, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 500, 0, AODB[12] );
    initError := F_iecInitAOEntry( M_ME_NA_1, 501, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 502, 0, AODB[13] );
    initError := F_iecInitAOEntry( M_ME_TD_1, 502, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 504, 0, AODB[14] );
  (* Mesured value, scaled value *)
 initError := F_iecInitAOEntry( M_ME_NB_1, 600, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 600, 0, AODB[15] );
    initError := F_iecInitAOEntry( M_ME_NB_1, 601, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 602, 0, AODB[16] );
    initError := F_iecInitAOEntry( M_ME_TE_1, 602, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 604, 0, AODB[17] );
  (* Measured value , short floating point value *)
 initError := F_iecInitAOEntry( M_ME_NC_1, 700, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 700, 0, AODB[18] );
    initError := F_iecInitAOEntry( M_ME_NC_1, 701, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 704, 0, AODB[19] );
    initError := F_iecInitAOEntry( M_ME_TF_1, 702, IEC870_GRP_INROGEN, 0, MAP_AREA_MEMORY, 708, 0, AODB[20] );
  (* Integrated totals *)
 initError := F_iecInitAOEntry( M_IT_NA_1, 800, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 800, 0, AODB[21] );
    initError := F_iecInitAOEntry( M_IT_NA_1, 801, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 804, 0, AODB[22] );
    initError := F_iecInitAOEntry( M_IT_TB_1, 802, IEC870_GRP_REQCOGEN OR IEC870_GRP_LOCFREEZE, 0, MAP_AREA_MEMORY, 808, 0, AODB[23] );

  (* Single commands *)
 initError := F_iecInitAOEntry( C_SC_NA_1, 10, 0, 0, MAP_AREA_MEMORY, 2100, 0, AODB[24] );
    initError := F_iecInitAOEntry( C_SC_NA_1, 11, 0, 0, MAP_AREA_MEMORY, 2100, 1, AODB[25] );
    initError := F_iecInitAOEntry( C_SC_TA_1, 12, 0, 0, MAP_AREA_MEMORY, 2100, 2, AODB[26] );
  (* Double commands *)
 initError := F_iecInitAOEntry( C_DC_NA_1, 20, 0, 0, MAP_AREA_MEMORY, 2200, 0, AODB[27] );
    initError := F_iecInitAOEntry( C_DC_NA_1, 21, 0, 0, MAP_AREA_MEMORY, 2200, 2, AODB[28] );
    initError := F_iecInitAOEntry( C_DC_TA_1, 22, 0, 0, MAP_AREA_MEMORY, 2200, 4, AODB[29] );
  (* Regulating step commands *)
 initError := F_iecInitAOEntry( C_RC_NA_1, 30, 0, 0, MAP_AREA_MEMORY, 2300, 0, AODB[30] );
    initError := F_iecInitAOEntry( C_RC_NA_1, 31, 0, 0, MAP_AREA_MEMORY, 2301, 0, AODB[31] );
    initError := F_iecInitAOEntry( C_RC_TA_1, 32, 0, 0, MAP_AREA_MEMORY, 2302, 0, AODB[32] );
  (* 32 bit string commands *)
 initError := F_iecInitAOEntry( C_BO_NA_1, 40, 0, 0, MAP_AREA_MEMORY, 2400, 0, AODB[33] );
    initError := F_iecInitAOEntry( C_BO_NA_1, 41, 0, 0, MAP_AREA_MEMORY, 2404, 0, AODB[34] );
    initError := F_iecInitAOEntry( C_BO_TA_1, 42, 0, 0, MAP_AREA_MEMORY, 2408, 0, AODB[35] );
  (* Set point, normalized values*)
 initError := F_iecInitAOEntry( C_SE_NA_1, 50, 0, 0, MAP_AREA_MEMORY, 2500, 0, AODB[36] );
    initError := F_iecInitAOEntry( C_SE_NA_1, 51, 0, 0, MAP_AREA_MEMORY, 2502, 0, AODB[37] );
    initError := F_iecInitAOEntry( C_SE_TA_1, 52, 0, 0, MAP_AREA_MEMORY, 2504, 0, AODB[38] );
  (* Set point, scaled valuess *)
 initError := F_iecInitAOEntry( C_SE_NB_1, 60, 0, 0, MAP_AREA_MEMORY, 2600, 0, AODB[39] );
    initError := F_iecInitAOEntry( C_SE_NB_1, 61, 0, 0, MAP_AREA_MEMORY, 2602, 0, AODB[40] );
    initError := F_iecInitAOEntry( C_SE_TB_1, 62, 0, 0, MAP_AREA_MEMORY, 2604, 0, AODB[41] );
  (* Set point, short floating point values *)
 initError := F_iecInitAOEntry( C_SE_NC_1, 70, 0, 0, MAP_AREA_MEMORY, 2700, 0, AODB[42] );
    initError := F_iecInitAOEntry( C_SE_NC_1, 71, 0, 0, MAP_AREA_MEMORY, 2704, 0, AODB[43] );
    initError := F_iecInitAOEntry( C_SE_TC_1, 72, 0, 0, MAP_AREA_MEMORY, 2708, 0, AODB[44] );

END_IF