Mapping
Für die Verknüpfung von OPC UA Nodes mit SPS-Symbolen steht der TwinCAT Target Browser zur Verfügung, der die Adressinformationen eines SPS-Symbols zu einem OPC UA Node hinzufügt. Das Nodeset kann dann auf den TwinCAT OPC UA Server zur Verfügung gestellt werden.
Objects
Objects können nicht mit SPS-Symbolen verknüpft werden, da sie keine Value haben, die verknüpft werden könnte.
Variablen und Properties
Das Mapping von Variablen und Properties kann mit Hilfe des TwinCAT Target Browsers durchgeführt werden. Bitte beachten Sie, dass der Datentyp der SPS-Variablen mit dem Datentyp des OPC UA Nodes "übereinstimmen" muss. Je nach Einstellung (Tools -> Options -> Advanced -> Disable mapping validation & Show hint if mapping may not be valid) werden Sie am Mapping gehindert oder darauf hingewiesen, falls ein Mapping nicht passt.
Weitere Informationen bezüglich der Zuordnung finden sie unter Datentypzuordnung TwinCAT <=> OPC UA.

Strukturen
Strukturierte Typen können auch über den TwinCAT Target Browser mit einer SPS-Struktur verknüpft werden. Allerdings gibt es hier einige Besonderheiten zu beachten. Zum einen muss die Datenstruktur in der SPS zur OPC UA Datenstruktur "passen" und zum anderen benötigt die Datenstruktur in der SPS noch die OPC UA Typinformation als SPS-Attribut. Diese Attribute können komfortabel bei Strukturtypen und Instanzen eines Strukturtypen über folgenden Button abgerufen werden:

Die folgende OPC-UA-Struktur ist als Beispiel angegeben.
<UADataType NodeId="ns=1;i=3015" BrowseName="1:ModelDataType">
  <DisplayName>ModelDataType</DisplayName>
  <References>
    <Reference ReferenceType="HasEncoding">ns=1;i=5048</Reference>
    <Reference ReferenceType="HasEncoding">ns=1;i=5050</Reference>
    <Reference ReferenceType="HasEncoding">ns=1;i=5049</Reference>
    <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
  </References>
  <Definition Name="1:ModelDataType">
    <Field DataType="Byte" Name="SwitchingObjectIdentification"/>
    <Field DataType="Byte" Name="SwitchingObjectNumber"/>
    <Field DataType="Date" Name="CurrentDate"/>
    <Field DataType="Int32" ValueRank="1" ArrayDimensions="1" Name="SwitchingTimes"/>
  </Definition>
</UADataType>
Die Struktur in der SPS muss dann wie folgt aufgebaut sein:
PROGRAM MAIN
VAR
  MyModel : ST_ModelDataType;
END_VAR
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.StructuredType' := '1'}
{attribute 'pack_mode' := '1'} 
{attribute 'OPC.UA.AdditionalStructuredType.NamespaceName' := 'nameSpaceNameNodeset'}
{attribute 'OPC.UA.AdditionalStructuredType.Id' := 'i=3015'}
TYPE ST_ModelDataType :
STRUCT
  SwitchingObjectIdentification : BYTE;
  SwitchingObjectNumber : BYTE;
  CurrentDate : DT;
  SwitchingTimes : ARRAY[0..2] OF DINT;
END_STRUCT
END_TYPEDie zusätzlichen Attribute OPC.UA.AdditionalStructuredType.NamespaceName und OPC.UA.AdditionalStructuredType.id sind notwendig, damit der TwinCAT OPC UA Server die Typinformationen zuordnen kann. Sie stellen den Namespace und die NodeID des Datentyps des StructuredType dar.
Mit dem TwinCAT Target Browser kann dann MyModelInstance mit der SPS-Variable MAIN.MyModelDataType gemappt werden.


Methoden
Methoden können über den TwinCAT Target Browser mit einem SPS-Funktionsbaustein verknüpft werden. Allerdings gibt es hier einige Besonderheiten zu beachten. Zum einen muss der Funktionsbaustein in der SPS zur OPC UA Methode "passen" und zum anderen benötigt der Funktionsbaustein in der SPS den Aufbau einer sogenannten Job-Methode. Dies ist in Job-Methoden in der Dokumentation des TwinCAT OPC UA Servers erklärt.
Da die OPC UA Methode umfangreich definiert ist, sind hier nur die Eckdaten der OPC UA Methode angegeben:
Vier InputParameter: Boolean, Int16, String, Enum (INT16)
Vier OutputParameter: Boolean, Int16, String, Enum (INT16)
Die PLC Methode sieht aus wie folgt:
//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_CASEDer Funktionsbaustein hat wie von jeder Job-Methode erfordert drei PLC-Methoden:
//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_VARSobald die Methode in der PLC erstellt ist, kann diese nach dem gleichen Prinzip wie eine Variable gemappt werden. Das Mappen einer Methode sieht so aus:

Über das TwinCAT Symbol Mapping können über folgende Buttons die Parameter überprüft werden und bei Bedarf angepasst werden. OPC UA und PLC müssen zueinander passen!
