PLC automapping

Introduction

Special comments that are added after the PLC variable declaration can be used for automated configuration of BACnet objects from the PLC program. The procedure can be used to configure BACnet objects, link BACnet property variables with PLC variables and initialize BACnet properties.

PLC automapping can be carried out via the BACnet server in the Settings tab, once the PLC project has been added to the hardware configuration. Automapping is triggered by pressing the Map button once the required PLC program has been selected:

PLC automapping 1:

PLC automapping for BACnet servers

The following source code extract illustrates the application of automapping comments. An allocated variable "av0" of type REAL created. The used comments define BACnet properties for use with automapping. The general comment syntax is defined by the PLC. Comments start with "(*" and end with "*)". Comments with the special prefix "~" are transferred by the PLC compiler into the TPY file for the respective symbols. These special comments, referred to as property, always have the following structure: "( NAME : VALUE : COMMENT )". For BACnet automapping the name is composed of "BACnet_[BACnet-Property-Name]". "VALUE" depends on the BACnet property and is explained accordingly.

In the sample the symbol "av0" is annotated with 3 BACnet properties. It is specified that the object is an AnalogValue object (AV). The object instance is 100. For the property ObjectIdentifier it should be noted that in the PLC comment it only contains the instance number, not the coded object type, as in BACnet. In the sample, automapping creates a BACnet object of type AnalogValue with the instance number 100. For each symbol a link can be made with a cyclic BACnet property variable. For variables that are not to be linked the comment "NOLINK" (see note in the appendix) can be used. For each symbol only one property may exist for linking. In the sample the property PresentValue of the AnalogValue object is linked with the PLC variable "av0".

av0 AT %I* : REAL;         (* ~ (BACnet_ObjectType     :  AV        : NOLINK)
                    (BACnet_ObjectIdentifier   :  100       : NOLINK)
                    (BACnet_PresentValue       :        : )
                *)

A further sample is provided below. In this case a BACnet object of type BinaryInput is created. No object instance is defined. During automapping an available object instance number is generated automatically. The sample demonstrates how the values of certain BACnet properties can be pre-initialized. The BACnet properties Description and ObjectName are initialized with the values "Hello, BACnet" and "BinaryInput_1". After automapping the corresponding values appear in the generated BACnet object (Settings tab) when the configuration is activated "Online". In addition the object name is used in the System Manager tree. In the sample a variable of type BOOL is linked with the property PresentValueBool. Although the BACnet data type of the PresentValues of binary objects is an enumeration type, the auxiliary property PresentValueBool was introduced for efficient handling of the PLC, in order to be able to link Boolean variables. For further details please refer to chapter "Process data".

bi0 AT %I* : BOOL;         (* ~ (BACnet_ObjectType     : BI         : NOLINK)          
                    (BACnet_Description    : Hello, BACnet  : NOLINK)
                    (BACnet_ObjectName     : BinaryInput_1  : NOLINK)
                    (BACnet_PresentValueBool   :        : )
                *)

Even if variables of primitive type are used, several variables can be linked with a BACnet object. To this end identical object type and object instance parameters should be specified for two variables. In the sample the BACnet properties PresentValue and StatusFlags are linked with AnalogValue object "101". In order to be able to report object instance numbers that have been assigned twice by mistake as errors, the comment "OBJREF" must be added to the 2nd symbol that refers to a previously created BACnet object. "OBJREF" must always be declared for the BACnet property "ObjectIdentified". If an object is to be accessed by name via 2 symbols, "OBJREF" must be used when declaring the property ObjectName.

av0 AT %I* : REAL;         (* ~ (BACnet_ObjectType     : AV         : NOLINK)
                    (BACnet_ObjectIdentifier   : 101        : NOLINK)
                    (BACnet_PresentValue       :        :)
                *)
av0_StatusFlags AT %I* : WORD; (* ~ (BACnet_ObjectType     : AV         : NOLINK)
                    (BACnet_ObjectIdentifier   : 101        : OBJREF,NOLINK)
                    (BACnet_StatusFlags    :        :)
                *)

Commandable properties

BACnet objects can also be accessed in write mode from the PLC. Commandable BACnet properties are linked with a PriorityArray and support write access with priorities 1 to 16. By using priorities, other system components can override signals from the PLC. The general rule for write access from the PLC to BACnet is that a value is only applied from BACnet when the program is started or changed. If the BACnet network writes competitively to the same priority level, the PLC-generated value may differ from the BACnet value. However, for prioritized accesses, a priority level should be used exclusively in most cases. In the case of several potential same-priority change sources, the BACnet property RelinquishDefault can also be used.

In the sample a "Q"-allocated variable is defined, which is linked with the PresentValue of an AnalogOutput object. Writing from the PLC results in an entry with priority level "8" in the PriorityArray. The PresentValue properties of BinaryValue, BinaryOutput, AnalogValue, AnalagOutput, MultistateValue and MultistateOutput objects are commandable. The highest active priority (1=highest, 16=lowest) is set as PresentValue. A priority in the PriorityArray is active if it is not NULL. If all elements in the PriorityArray are NULL PresentValue takes the value of the BACnet property RelinquishDefault.

ao0_PresentValue8 AT %Q* : REAL;(*~ (BACnet_ObjectType     : AO         : NOLINK)
                    (BACnet_PresentValue_Priority8 :        :)
                *)

A special feature of commandable properties is the entry NULL in the PriorityArray, which is a separate data type in BACnet - in contrast to the respective value data types (REAL, BINARY_PV, UNSIGNED). The value NULL, which deactivates a priority level in the PriorityArray, can be written for the respective objects via the linked variable as follows:

Structured programming

Function blocks (FBs) are also supported for structured linking of BACnet objects during automapping. The source code extract shown below illustrates the declaration of a BACnet function block. In order to be considered in automapping, these function blocks must begin with the prefix "FB_BACnet". The sample defines an FB for an AnalogOutput object, which is available as a template in the BACnet PLC library "TcBACnet.lib". The properties PresentValue, StatusFlags, Reliability and OutOfService are linked as input variables to the PLC, the property PresentValue with write-access, priority 8.

FUNCTION_BLOCK FB_BACnet_AnalogOutput
VAR_OUTPUT
    ObjectType: E_BACNETOBJECTTYPE;       (* ~ (BACnet_ObjectType       : AO   : NOLINK) *)
    PresentValue AT%I*: REAL;         (* ~ (BACnet_PresentValue     :      :) *)
    StatusFlags AT%I*: UINT;          (* ~ (BACnet_StatusFlags      :      :) *)
    Reliability AT%I*: E_BACNETRELIABILITY;   (* ~ (BACnet_Reliability      :      :) *)
    OutOfService AT%I*: BOOL;         (* ~ (BACnet_OutOfService     :      :) *)END_VAR
VAR_INPUT
    PresentValue_Priority8 AT%Q*: REAL;       (* ~ (BACnet_PresentValue_Priority8 ::) *)END_VAR

This FB can be instantiated in the main program (or another FB, program). Additional comments can be specified during instantiation. Comments at the instantiation level have higher priority than comments at FB declaration level. In the sample an AnalogOutput object is created, and the object instance and the BACnet property Description are initialized at instantiation level. Through the FB declaration the properties PresentValue, StatusFlags, Reliability, OutOfService and PresentValue_Priority8 are linked in the generated BACnet object.

ao1 : FB_BACnet_AnalogOutput;         (* ~ (BACnet_ObjectIdentifier : 100 :NOLINK)   
                           (BACnet_Description      : FB-basiertes AO: NOLINK)
                          *)

BACnet FBs can be used hierarchically, i.e. an "FB_BACnet_Pump" containing several FB_BACnet_AnalogOutput instances can be defined, for example. For nesting depths greater than one a StructuredView object is created in the System Manager. BACnet comments are not handed down to several hierarchical levels. Only the instantiation and declaration levels are supported. An exception is the BACnet comment BACnet_ObjectIdentifier, which is resolved over several hierarchical levels, in order to support ID allocation for nested FBs.

PLC automapping 2:

If an object instance is specified at a higher level, it may potentially affect many objects of the same type. The generation of an object ID is based on the specified ID (e.g. if an object instance of 1000 is specified, a new free ID is searched for from 1000). An FB_BACnet_Room with 2 AV and 2 BV objects and a start ID of 1000 will therefore generate BACnet objects AV:1000, AV1001, BV:1000 and BV:1001. The resulting object IDs are calculated before the actual mapping operation. If objects with the determined IDs already exist, e.g. from an IO mapping, the existing objects are used/linked, and no new objects are created.

In addition to nested FBs, one-dimensional arrays are also supported. The following sample shows the declaration of an array raeume of type FB_BACnet_Raum that contains further BACnet objects. In this way systematic units with identical functionality can be managed. Arrays at different nesting levels are also supported. For example, a BACnet object fbHaus[1].EtageU.Raum[10].tmpSoll can be generated.

raeume : ARRAY[0..10] OF FB_BACnet_Raum;

Structured programming: configuration of FB instances

BACnet comments at FB declaration level apply equally to all instances of the FB. For certain BACnet properties, an instance-level definition may apply. For example, instance-based ObjectIdentifiers can be defined or the hardware connection can be configured to Io modules per instance. The following is a sample where BACnet properties are set at the instance level.

FUNCTION_BLOCK FB_BACnet_SubSub
VAR
  bi  : FB_BACnet_BinaryInput; (*~(BACnet_OutOfService : TRUE: NOLINK)*)
  bi2 : FB_BACnet_BinaryInput;
END_VAR
FUNCTION_BLOCK FB_BACnet_Sub
VAR
  sub1   : FB_BACnet_SubSub;
  sub2   : FB_BACnet_SubSub; 
  subArr : ARRAY[0..1] OF FB_BACnet_SubSub;
END_VAR
PROGRAM SIMPLE
VAR
s1 :FB_BACnet_Sub; (* ~ { BACnet_ObjectIdentifier<sub1/bi>    : 1017   : }
            { BACnet_ObjectIdentifier<sub2>       : 1028   : }
            { BACnet_ObjectIdentifier<subArr[0]/bi>   : 5555   : }
            { BACnet_ObjectName<sub2/bi>          : biname : NOLINK }
           *)
END_VAR

By defining an instance path after the BACnet property name, BACnet property definitions can be applied to sub-elements of an FB. For this purpose, the instance path can be specified in "<" and ">". In the above sample, for example, the BACnet object bi of the instance sub1 is given an ObjectIdentifier 1017. Individual sub-levels are separated by "/". BACnet property definitions can also be configured at intermediate levels. In the sample the ObjectIdentifier 1028 is transferred to the FB instance sub2. In this sample, this causes the BACnet objects s1.sub2.bi to be given Object ID 1028 and s1.sub1.bi2 to be given Object ID 1029. The instance path specification can also contain array elements.

ARRAY[01..03] OF FB_BACnet_AnalogValue; (* ~
   (BACnet_Description<[1]>:1. OG Raum 1 Temp: NOLINK)
   (BACnet_Description<[2]>:1. OG Raum 2 Temp: NOLINK)
   (BACnet_Description<[3]>:1. OG Raum 3 Temp: NOLINK)
*)

Direct parameterization of array elements at program or global level is also supported. In the sample, the BACnet property Description of three array elements is initialized.

Structured programming: View configuration

During PLC automapping, StructuredView objects are created for each nesting depth in the form of programs and function blocks, in order to map the PLC structure to BACnet. Depending on the data point addressing description used, it may be necessary to adapt the names BACnet objects and their structure with a name prefix. The PLC comment "BACnet_StructuredViewPath" can be used to define dedicated name prefixes for PLC automapping. "BACnet_StructuredViewPath" can be used to annotate any variable at the required structuring levels.

PROGRAM MAIN
VAR
  viewDummy : BOOL; (* ~     ( BACnet_StructuredViewPath        : \/Building1\/Floor2 : ) 
( BACnet_StructuredViewPathDescription : \/Haus 1\/Flur 2 : )
            ( BACnet_StructuredViewPathObjectId    : \/1000\/9: )
             *)
  room1 : FB_BACnet_Room; (* ~( BACnet_Description : Description of structured view object room1: ) *)
  room2 : FB_BACnet_Room;
END_VAR

In the sample the name Building1.Floor2.room1.XXX is used for all BACnet objects within the function block FB_BACnet_Room, instead of the name MAIN.room1.XXX. In addition to the use for the names of BACnet objects, a StructuredView object is also created for each hierarchical level. Hierarchical levels are defined by the string "\/".

The PLC comments "BACnet_StructuredViewPathDescription" and "BACnet_StructuredViewPathObjectId" can be used to specify the BACnet property Description and the ObjectIdentifiers of the generated StructuredView objects. StructuredView objects that are generated through complex function blocks; in sample room1 and room2 can be configured via the PLC comments BACnet_Description and BACnet_ObjectIdentifier.

Data point addressing description

Depending on the required data point addressing description, it may be necessary to adapt the generated BACnet object names. By default, points (".") are used to separate structural levels. By specifying a "StructureSeparator" another symbol can be used instead of the point or the separator symbol can be removed completely. The following sample shows the definition of the separator symbol "_". The separator symbol should be defined once per project, e.g. at a global variable.

akzDummy : BOOL; (* ~( BACnet_StructureSeparator :_: ) *) 

Write protection and optional properties

Special comment options were introduced for controlling write protection and optional properties. Additional options can be specified in the form of a comma-separated list in the comment part of the PLC comments. DISABLE deactivates an optional property. WRITEPROTECT activates write protection for a writeable property. Make sure that the option NOLINK is specified when configuring multiple properties. The following sample shows the configuration of write protection and optional properties.

bo1: FB_BACnet_BinaryOutput; (* ~(BACnet_NotifyType         :    : DISABLE,NOLINK)
                 (BACnet_ChangeOfStateTime      :    : DISABLE,NOLINK)
                 (BACnet_ChangeOfStateCount     :    : DISABLE,NOLINK)
                 (BACnet_ActiveText         : AN     : WRITEPROTECT,NOLINK)
                 (BACnet_InactiveText       : AUS    : WRITEPROTECT,NOLINK)  
                  *)

The comment ENABLE can be used for BACnet properties with inverted optional logic, i.e. BACnet properties that are initially disabled when a BACnet object is created. An example of this is activation of a mean value-forming filter in the AnalogInput object by means of the vendor-specific BACnet property AvgFilterCycles:

fbAI : FB_BACnet_AnalogInput; (* ~(BACnet_AvgFilterCycles     : 20    : ENABLE,NOLINK ) *)

Initialization of complex property values

The initialization of property values via PLC automapping is limited by the PLC comment syntax. The reserved characters "(", ")", ":", "*" and " cannot be used. In addition, for BACnet properties with selection type (Choice) or optional fields it is not always possible to unambiguously analyze each string, if an optimized display form is used, as in the System Manager.

For certain properties special parsers were implemented, which enable simplified configuration of property values. The following sample shows how the StateText property of a MultiStateValue object can be initialized.

mv : FB_BACnet_MultiStateValue;  (* ~(BACnet_StateText   : {Low;Medium;High}       : NOLINK )*)

BitField properties (EventEnable, AckRequired) can be initialized by specifying a hexadecimal number. In this case it is advisable to use the corresponding value from the System Manager:

bi : FB_BACnet_BinaryInput;      (* ~(BACnet_EventEnable : 0xE005          : NOLINK )*)

The Priority property of the NotificationClass object can also be initialized in abbreviated form. In the sample this array property is initialized with the values 12, 12 and 122. For the initialization of BitField properties the more transparent form of array-like initialization was implemented. In the sample the bits for "to_offnormal" and "to_fault" are set in the property AckRequired. A BitField property without set bit can be initialized with the string "{}".

nc : FB_BACnet_NotificationClass;(* ~(BACnet_Priority    : {12;12;222}         : NOLINK)
                     (BACnet_AckRequired : {to_offnormal;to_fault} : NOLINK)
                  *)

Since it is not possible to implement dedicated parsers for all complex properties, the option of initialization with the aid of XML was introduced. XML has the advantage that it is not necessary to use the reserved comment syntax characters, so that there are no restrictions for initialization of the property values. The XML values for the property initialization can simply be created via the Copy&Paste function for the property values. A property can be created in the System Manager using wizards. Via the context menu in the property view ("Online" or "Settings") the current value of a property can be added to the clipboard via "Copy Value" (or via the shortcut CTRL-C) and used in PLC Control via "Paste" or CTRL-V.

PLC automapping 3:

Is the SHIFT key is pressed while using the "Copy Value" function, the XML string is copied as a line. Otherwise a structured variant is generated in multi-line mode. Using single-line mode makes the variable declaration in the PLC program more transparent. The following sample illustrates how the property StartTime of a TrendLog object is initialized via the XML syntax:

tl : FB_BACnet_TrendLog; (* ~(BACnet_StartTime : 
<BACnetDateTime>
  <date>
    <year>112</year>
    <month>7</month>
    <day>16</day>
    <dayOfWeek>1</dayOfWeek>
  </date>
  <time>
    <hour>12</hour>
    <minute>30</minute>
    <second>0</second>
    <hundredths>0</hundredths>
  </time>
</BACnetDateTime>
: NOLINK )*)

Property references

The REFERENCE option was introduced for the initialization of reference properties. Automatic generation of object IDs means that direct value initialization of properties cannot be used for referencing properties of other PLC BACnet objects, since the object IDs are unknown when the PLC program is implemented. Specification of the REFERENCE option and property name as a suffix enables referencing of automatically generated objects. A simple heating system is described below as an example. Set values, actual values and control values are specified via analog* BACnet objects, which are linked with a Loop object via references.

fbSollwert   : FB_BACnet_AnalogValue;
fbStellwert  : FB_BACnet_AnalogOutput;
fbIstwert    : FB_BACnet_AnalogInput;
fbTempRegler : FB_BACnet_Loop; (* ~(BACnet_ManipulatedVariableReference : ./fbStellwert : REFERENCE_PresentValue) 
                   (BACnet_SetpointReference        : ./fbSollwert  : REFERENCE_PresentValue)
                   (BACnet_ControlledVariableReference  : ./fbIstwert   : REFERENCE_PresentValue) 
                *)

In terms of REFERENCE functionality, a distinction is made between absolute and relative referencing. Relative references always refer to the current context and start with "./". The current context always refers to the current declaration level in the program or function block. Using relative referencing, objects can also be used in other programs or function blocks. One example is the declaration of a LOOP object in the "MAIN" program; to reference an object in the program "IO_OBJECTS", the syntax "./../IO_OBJECTS/fbAO" can be used. Absolute references always start directly with the program name (e.g. MAIN.fbBvI or MAIN.haus1.raum1.uv24Vok). For global variables, the "." must be removed at the beginning.

PLC automapping 4:

Generally, all references refer to symbol names in the PLC, not to the BACnet object name!

In general, references that may potentially contain BACnet objects in other devices (BACnetDeviceObjectPropertyReference), can also be initialized with the REFERENCE function. If the target symbol is a FB_BACnet_Remote_* function block, the target device ID is entered automatically.

The REFERENCE option also works for Schedule and TrendLog objects:

bi      : FB_BACnet_BinaryInput;
bv      : FB_BACnet_BinaryValue;
tl      : FB_BACnet_TrendLog; (* ~(BACnet_LogDeviceObjectProperty       : ./bi      : REFERENCE_PresentValue) *)
sched   : FB_BACnet_Schedule; (* ~(BACnet_ListOfObjectPropertyRefs      : ./bv      : REFERENCE_PresentValue) *)

The following section shows a sample for remote objects. The sample uses an absolute reference within the MAIN program.

bvRemote : FB_BACnet_RemoteBinaryValue; (* ~ (BACnet_ObjectType       : BV : NOLINK)
                         (BACnet_DeviceID     : 32 : NOLINK)
                         (BACnet_ObjectIdentifier : 2 : NOLINK) *)
fbTLog   : FB_BACnet_TrendLog;      (* ~ (BACnet_LogDeviceObjectProperty : MAIN.bvRemote : REFERENCE_PresentValue) *)

 

Several references in the property ListOfObjectPropertyRefs of the Schedule object can be specified via the following syntax:

 schedMultiRef : FB_BACnet_Schedule;     (* ~ (BACnet_ListOfObjectPropertyRefs : Object=COOLING.bPrgCool;Property=PresentValue;
                                        Object=fbGlob;Property=PresentValue; : REFERENCE) *)

A special initialization is also available for other complex BACnet properties with references. These are described below, based on brief samples. Initially, the initialization follows the Action property of the Command object, which can be used for controlling process-based procedures.

fbCmdBo  : FB_BACnet_BinaryOutput;
fbCmdBV19: FB_BACnet_BinaryValue; (* ~(BACnet_ObjectIdentifier : 19 : ) *)fbCmdAv  : FB_BACnet_AnalogValue;
fbCmdMv  : FB_BACnet_MultiStateValue;
fbCmd    : FB_BACnet_Command; (* ~(BACnet_Action :          
   Action=1;Command=1;Object=./fbCmdBo;Property=PresentValue;Value=ACTIVE;Priority=16;Delay=0;Quit=TRUE;
   Action=1;Command=2;Object=./fbCmdBo;Property=PresentValue;Value=NULL;Delay=1;Quit=FALSE;
   Action=1;Command=3;Object=BinaryValue_19;Property=PresentValue;Value=NULL;Delay=1;Quit=FALSE;
   Action=1;Command=4;Object=./fbCmdAv;Property=PresentValue;Value=NULL;
   Action=1;Command=5;Object=./fbCmdAv;Property=PresentValue;Value=12.3;Delay=1;Quit=FALSE; 
   Action=2;Command=1;Object=./fbCmdMv;Property=PresentValue;Value=2;Delay=1;Quit=FALSE; 
: REFERENCE )*)

The following sample illustrates the initialization of the ListOfGroupMembers Property of the Group object.

fbGroupAv:  FB_BACnet_AnalogValue;
fbGroupBv : FB_BACnet_BinaryValue;
fbGroup   : FB_BACnet_Group;(* ~(BACnet_ListOfGroupMembers :
   Object=./fbGroupAv;Property=PresentValue;Property=StatusFlags;Property=HighLimit;Property=LowLimit;
   Object=./fbGroupBv;Property=PresentValue;Property=StatusFlags;Property=OutOfService 
: REFERENCE ) *)


The EventEnrollment object can be used to define alarm conditions that go beyond the conditions covered by Intrinsic Reporting. The following section demonstrates the initialization of the EventEnrollment objects with the aid of an abbreviated syntax:

fbEEAv   : FB_BACnet_AnalogValue;
fbEEWarn : FB_BACnet_EventEnrollment;(* ~
   (BACnet_ObjectPropertyReference : ./fbEEAv : REFERENCE_PresentValue)
   (BACnet_EventParameters     : EventType=out_of_range;timeDelay=5;lowLimit=0;highlimit=10;deadband=0;:REFERENCE )
   (BACnet_NotificationClass       : 10 : nolink )
   (BACnet_EventMessageTexts       : {Warning;Sensorfault;Normal operation} : nolink )
*)  
fbEEBo   : FB_BACnet_BinaryOutput;
bEEHours : FB_BACnet_EventEnrollment; (* ~
   (BACnet_ObjectPropertyReference : ./fbEEBo : REFERENCE_ElapsedActiveTime)
   (BACnet_EventParameters     : EventType=unsigned_range;highlimit=60; :REFERENCE )
   (BACnet_NotificationClass       : 10 : nolink )
   (BACnet_EventMessageTexts       : {Maximum operating hours exceeded; ; } : nolink )
*)

Integration of hardware modules

The connection of hardware modules can basically be done via IO automapping and the assignment to PLC objects by specifying ObjectIdentifiers in the PLC code. To enable efficient code generation of BACnet projects, it is also possible to configure the hardware connection directly behind the declaration of BACnet objects in the PLC. The LINKPATH option exists for this purpose. With this option it is possible to link a BACnet property variable of a BACnet object directly to an IO module. In this case, no link to a PLC variable is created, but a pure device-device link.

The following sample shows the linking of a BACnet object BinaryInput with the 3rd terminal (of a KL1002) on the 1st channel. The hardware value can then be accessed directly in the PLC program via the PresentValue of the FB_BACnet_BinaryInput.

bi : FB_BACnet_BinaryInput;(* ~{ BACnet_RawIoBinaryBoolValue : TIID^Rt-Ethernet^BK9000^Term 3 KL1002^Channel 1^Input : LINKPATH } *)

By specifying an additional parameter of the LINKPATH option, Offset1, Offset2 and the bit size for the link can also be specified directly (LINKPATH<[Offset1],[Offset2],[Bit size]>)... If the bit size is set to the value 0, the maximum possible number of bits is automatically linked. Without specifying the additional parameters, the value 0 is used for Offset1 and Offset2. Offset1 refers to the BACnet property variable and Offset2 to the external link.

bx : FB_BACnet_BinaryInput;(* ~{ BACnet_RawIoBinaryBoolValue : TIID^Rt-Ethernet^BK9000^Term 3 KL1002^Channel 1^Input : LINKPATH<0,0,1> } *)

In connection with function blocks, sub-elements of FB instances can also be directly connected to a hardware module. The instance path syntax "<[]>" after the BACnet property to be linked can be used for this.

PROGRAM SIMPLE
VAR
s1 :FB_BACnet_Sub; (* ~ { BACnet_RawIoBinaryBoolValue<sub1/bi>  : TIID^Rt-Ethernet^BK9000^Term 3 KL1002^Channel 1^Input : LINKPATH }
            { BACnet_RawIoBinaryBoolValue<sub2/bi>  : TIID^Rt-Ethernet^BK9000^Term 3 KL1002^Channel 2^Input : LINKPATH }
            { BACnet_RawIoBinaryBoolValue<sub1/bi2> : TIID^Rt-Ethernet^BK9000^Term 2 KL1002^Channel 2^Input : LINKPATH }      
            *)
END_VAR

In addition, PLC auto-mapping also allows variables to be linked outside of BACnet. With the option "ExtLink" any local PLC symbol can be linked to an external variable e.g. a hardware module. With the option "ExtLink2" 2 PLC-external variables can be linked together. Additional parameters (as with LINKPATH) can be used to specify Offset1, Offset2 and the bit size for the link. Below is a sample of how to use each of these options.

b1 AT%I*: BOOL;   (* ~{ ExtLink  : TIID^Rt-Ethernet^BK9000^Term 2 (KL1002)^Channel 2^Input  : } *)
bDummy  : BOOL;   (* ~{ ExtLink2 : TIID^Rt-Ethernet^BK9000^Term 5 (KL2012)^Channel 1^Output : 
                   TIID^Rt-Ethernet^BK9000^Term 2 (KL1002)^Channel 2^Input } 
           *)
b1 AT%I*: BOOL;   (* ~{ ExtLink<0;0;1>  : TIID^Rt-Ethernet^BK9000^Term 2 (KL1002)^Channel 2^Input  : } *)
bDummy  : BOOL;   (* ~{ ExtLink2<0;0;1> : TIID^Rt-Ethernet^BK9000^Term 5 (KL2012)^Channel 1^Output : 
                      TIID^Rt-Ethernet^BK9000^Term 2 (KL1002)^Channel 2^Input } 
           *)

The EXP export can be used as a starting point for linking hardware modules. In the EXP export configuration dialog, the "Export I/O configuration" option can be used to generate the BACnet object configuration for the TcBACnet.lib. Here, a corresponding program with the hardware BACnet objects and their link is created for each IO bus present in the project. The procedure EXP-Export, PLC Automapping then generates the same BACnet configuration that generates an IO automapping. The advantage of the PLC variant is that hardware objects can be integrated into structured function blocks of the PLC or hardware channels that are not to be visible via BACnet can be deleted.

PLC automapping 5:

PLC automapping for BACnet clients

To link PLC variables with process data properties of remote BACnet objects, Device ID can be specified as a comment, in addition to the object type and instance. In this case the PLC variables are linked with previously created BACnet objects (e.g. through scanning of clients). If a client does not yet exist, it will be created automatically. Objects that do not exist are also created. The hierarchy created is flat. StructuredView object for clients are currently not supported by PLC automapping.

In the following source text extract a variable of type REAL is created. During automapping it is linked with the property PresentValue of object AnalogValue:100 under the client with the BACnet-ID "42". The process data variable of the remote BACnet object is activated automatically.

av0 AT %I* : REAL;         (* ~ (BACnet_ObjectType         : AV    : NOLINK) 
                    (BACnet_DeviceID           : 42    : NOLINK)
                    (BACnet_ObjectIdentifier       : 100   : NOLINK)
                    (BACnet_PresentValue       :       :)
                *)

Auxiliary properties exist for the configuration of the process data-specific parameters of client properties in order to be able to automatically configure all options that can be set in the System Manager. These are write priority for PresentValue properties, cycle time, COV increment, COV resubscription interval for COV subscriptions and flags for configuring whether data are to be processed cyclically or via COV or OnChange. The following source code extract illustrates the application of these auxiliary properties.

ao0 AT %Q* : REAL;         (* ~ (BACnet_ObjectType         : AO     : NOLINK)
                    (BACnet_DeviceID           : 42     : NOLINK)
                    (BACnet_ObjectIdentifier       : 0      : NOLINK)
                    (BACnet_RemotePriority     : 8      : )
                    (BACnet_RemoteCycleTimeWrite   : 1000   : )
                    (BACnet_RemoteFlagsWrite       : WRITEONCHANGE : )
                    (BACnet_PresentValue       :    : )
                *)

ao1 AT %I* : REAL;         (* ~ (BACnet_ObjectType         : AO     : NOLINK)
                    (BACnet_DeviceID           : 42     : NOLINK)
                    (BACnet_ObjectIdentifier       : 0      : NOLINK)
                    (BACnet_PresentValue       :    : )
                    (BACnet_RemoteCycleTimeRead    : 1000   : )
                    (BACnet_RemoteFlagsRead    : COV    : )
                    (BACnet_RemoteCovincrement     : 0,5    : )              
                    (BACnet_RemoteResubscriptionInterval: 60: )
                *)

For RemoteFlagsWrite, the following values can be used for output variable (%Q), i.e. from the configured controller to the remote device:

For RemoteFlagsRead - input variable (%I) - reading from a remote device the following applies:

If no auxiliary properties are specified for remote objects, the default settings of the System Manager are used:

If the remote-blocks of TcBACnet.lib are used, the process data transfer type can also be specified during FB instantiation. The remote configuration parameters refer to all activated BACnet properties. In the following sample, the transmission type of the process data is set to ConfirmedCOV for the properties of the *EX function block: StateOfChangeCount, PresentValue, StatusFlags, EventState and Reliability.

 bvRemote : FB_BACnet_RemoteBinaryValue_EX; (* ~ (BACnet_ObjectType : BV : NOLINK)
                        (BACnet_DeviceID   : 32 : NOLINK)
                        (BACnet_ObjectIdentifier : 20 : NOLINK)
                        (BACnet_RemoteFlagsRead : ConfirmedCOV : )
                        (BACnet_RemoteResubscriptionInterval : 3600 : )  
                        *)


For priority-based properties (PresentValue) a write priority can be configured, in order to enable access to higher priorities of the PriorityArray. As for servers, the value NULL can be written to the associated PriorityArray in order to disable this priority level. For analog and binary objects this is done in the same way as for servers (value > 1 for binary objects; NaN for analog objects). For AnalogOutput objects the Min/MaxPresValue range is not monitored, which means that NULL can only be generated via NaN. In contrast to servers, for multistate objects only writing of 0 results in NULL in the PriorityArray. For performance reasons the property NumberOfStates is not read by the remote device.

In conjunction with the TwinCAT BACnet PLC library "TcBACnet.lib" an efficient option for using "scanned" client configurations in the PLC is available. Once the clients to be used have been added to the System Manager (e.g. through scanning of a BACnet network), the variable declaration and associated annotation with automapping comments can be generated by specifying a destination file with the extension "EXP" in the Export option of the Settings tab in the BACnet device. This can then be imported in a PLC project in PLC Control. The basis BACnet FBs of the library are used (e.g. "FB_BACnet_RemoteAnalogInput").

Remap

When using persistent data, subsequent extensions pose a challenge in terms of establishing an unambiguous relationship between the persistent data and their counterparts in the PLC program. Persistent data are unambiguously assigned via the ObjectIdentifier. If an extension involves adding an object in a program, subsequently generated BACnet ObjectIdentifiers may be shifted, thereby corrupting the allocation of the persistent data. The Remap function was implemented to resolve this issue. Remap can be run on an already mapped PLC project that is subject to modifications/extensions.

The PLC project is examined for modifications and:

Appendix