Mapping
The TwinCAT Target Browser is available for linking OPC UA nodes to PLC symbols, which will add the address information of a PLC symbol to an OPC UA node. The nodeset can then be made available on the TwinCAT OPC UA Server. The mapping basically works by dragging a symbol from the target browser onto an OPC UA instance (drag and drop):

Objects
Objects cannot be linked to PLC symbols since they do not have a value that could be linked.
Variables
Variables (and properties) can be linked to PLC variables using the TwinCAT Target Browser.
Requirements
- The data type of the PLC variables corresponds to the data type of the OPC UA node.
Depending on the setting (Tools -> Options -> Advanced -> Allow mapping despite validation errors & Disable warning dialog), you will be prevented from mapping or notified if a mapping does not fit (perfectly).
Further information regarding the assignment can be found at Data type assignment TwinCAT <=> OPC UA.
Structures
Structures can be linked to a PLC structure using the TwinCAT Target Browser.
Requirements
- The data structure in the PLC matches the OPC UA data structure. In particular:
- Sequence of fields
- Data types
- The PLC type definition contains the OPC UA type information as attributes.
The TwinCAT OPC UA Server requires these attributes in order to assign the PLC data type to the correct OPC UA data type. Simple PLC data types do not require these attributes.
The required attributes can be written manually above the instance or type declaration or retrieved for copying via the TwinCAT OPC UA Nodeset Editor.
Step-by-step with the Nodeset Editor:
1 - Finding and opening the structure type.
5 - Creating the DUT in TwinCAT.
2 – Selection and copying of all names and DataType BrowseNames of the fields
5 - Insert in TwinCAT between STRUCT and END_STRUCT
3 - Opening of the pragmas for the type
4 - Copying the pragmas
5 - Inserting in TwinCAT above TYPE
6 - Replacing the DataType BrowseNames with the appropriate PLC types
(e.g. Boolean => "Tc3_OpcUa.UA_Boolean" or "BOOL").
Missing (structure) types may also need to be created.


Meaning of the attributes:
- OPC.UA.DA
Activates the provision of the data type and any sub-elements via OPC UA. - OPC.UA.DA.StructuredType
Identifies the type as a structured OPC UA data type. - OPC.UA.AdditionalStructuredType.NamespaceName
Specifies the NamespaceUri of the data type from the nodeset. - OPC.UA.AdditionalStructuredType.Id
Contains the NodeId of the OPC UA data type, in this case i=3007. - pack_mode := '1'
Ensures that the memory layout of the structure is defined and compatible.
As soon as an instance of the PLC structure type has been declared, it can be linked in the same way as a variable.
Methods
Methods can be linked to a PLC function block via the TwinCAT Target Browser.
Requirements
- The PLC function block has the structure of a so-called job method. This is explained in Job methods in the TwinCAT OPC UA Server documentation.
- The input and output parameters of the PLC function block correspond to the OPC UA method.
Example
As the example OPC UA method is extensively defined, only the key data of the OPC UA method is given here:
Four InputParameters: Boolean, Int16, String, Enum (INT16)
Four OutputParameters: Boolean, Int16, String, Enum (INT16)
The PLC function block looks like this:
//Funktionsbaustein Deklaration:
{attribute 'OPC.UA.DA.JobMethod' := 'Method2_WithSimpleArguments'}
FUNCTION_BLOCK PUBLIC FB_Method2_WithSimpleArguments
VAR
// Timer to simulate job execution
timer : TON := (PT:=T#4S);
// Variables to determine if a job has been started (Start() method has been called) or finished
jobRunning : BOOL;
jobFinished : BOOL;
// State machine variable
state : UDINT;
//Values of method specific input parameters:
bArgIn : BOOL;
nArgIn : INT;
sArgIn : STRING;
eArgIn : E_Enum_1;
//Values of method specific output parameters:
bArgOut : BOOL;
nArgOut : INT;
sArgOut : STRING;
eArgOut : E_Enum_1;
END_VAR
//Funktionsbaustein Implementierung
CASE state OF
0:
IF jobRunning THEN
state := state + 1;
END_IF
1: //Logic of method in here:
timer(IN:=TRUE);
IF timer.Q THEN
//Set Inputs To Outputs
bArgOut := bArgIn;
nArgOut := nArgIn;
sArgOut := sArgIn;
eArgOut := eArgIn;
timer(IN:=FALSE);
jobRunning := FALSE;
jobFinished := TRUE;
state := 0;
END_IF
END_CASEAs required by every job method, the function block has three PLC methods:
//Start Deklaration:
{attribute 'TcRpcEnable' := '1'}
METHOD PUBLIC Start : HRESULT
VAR_INPUT
SimpleArgIn1 : BOOL;
SimpleArgIn2 : INT;
SimpleArgIn3 : STRING;
SimpleArgIn4 : E_Enum_1;
END_VAR
VAR_OUTPUT
hdl : UDINT; // handle, can be used for concurrent calls
END_VAR
//Start Implementierung:
IF jobRunning THEN
Start := Tc3_Module.E_FAIL;
ELSE
//Give inputs to functionblock body
bArgIn := SimpleArgIn1;
nArgIn := SimpleArgIn2;
sArgIn := SimpleArgIn3;
eArgIn := SimpleArgIn4;
hdl := 16#BE6780FF; //static because concurrent calls are disabled by checking jobRunning
jobRunning := TRUE;
Start := OpcUaStatusCodes.Good; //Set return value of method
END_IF
//CheckState Deklaration:
{attribute 'TcRpcEnable' := '1'}
METHOD PUBLIC CheckState : HRESULT
VAR_INPUT
hdl : UDINT; // handle, can be used for concurrent calls
END_VAR
VAR_OUTPUT
bBusy : BOOL; // Do not change. Used by server to find out if the job is finished
SimpleArgOut1 : BOOL;
SimpleArgOut2 : INT;
SimpleArgOut3 : STRING;
SimpleArgOut4 : E_Enum_1;
END_VAR
//CheckState Implementierung:
IF hdl <> 16#BE6780FF THEN
CheckState := OpcUaStatusCodes.BadInternalError; //Set return value of method
ELSIF NOT jobFinished THEN
bBusy := TRUE; // job is not finished yet
CheckState := OpcUaStatusCodes.Good; // done, no error occured during execution (OPC UA StatusCode "GOOD")
ELSE
//Give values to outputs
SimpleArgOut1 := bArgOut;
SimpleArgOut2 := nArgOut;
SimpleArgOut3 := sArgOut;
SimpleArgOut4 := eArgOut;
bBusy := FALSE; // job is finished
CheckState := OpcUaStatusCodes.Good; // done, no error occured during execution (OPC UA StatusCode "GOOD")
END_IF
//Abort Deklaration:
{attribute 'TcRpcEnable' := '1'}
METHOD PUBLIC Abort : HRESULT
VAR_INPUT
hdl : UDINT; // handle, can be used for concurrent calls
END_VARAs soon as an instance of the PLC function block has been created, it can be mapped in the same way as a variable. After the mapping…

...the parameters can be checked via the TwinCAT Symbol Mapping using the following buttons and adjusted if necessary. OPC UA and PLC must be compatible! There is (still) no validation of method links.
