TwinCat 3 PLCOpen Opc-UA - Structure Problem

nik385

Level-1
Beiträge
1
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo ich bin sowohl hier im Forum, als auch in der Programmierung von SPSen neu. Ich hoffe ihr helft mir trotzdem. :D

Ich nutze die PLCOpen Funktionsbausteine um Daten via OPC-UA zu empfangen. Diese Daten liegen als Structur vor. Das Struct besteht aus verschiedenen Datentypen wie Int, Real, Bool, ... außerdem sind Arrays vorhanden. Soweit funktioniert das ganze auch super. Sobald jedoch in dem Struct ein String ist, kann ich den entsprechenden Knoten nicht mehr auslesen. Ich erhalten dann folgend Fehlermeldung (aus Zustand iState = 50):
0x745 1861 ADSERR_CLIENT_SYNCTIMEOUT Timeout ist aufgetreten

Im UAExpert kommen die Daten alle (auch der problematische String) an. Mit Hilfe des virtuellen OPC-Geräts in TwinCat kann ich die Daten auch empfangen, das möchte ich aber nicht.

Ich habe sowohl TwinCat als auch das TF6100 OPC-UA Paket auf die neuste Version geupdatet.

Meinen Code findet ihr hier:

Code:
{attribute 'pack_mode' := '1'}
{attribute 'OPC.UA.DA.StructuredType' := '1'}
TYPE ST_Values :
STRUCT
  test:    ARRAY [1..10] OF ST_2;
  
  // Hier ist der problematische String
  //{attribute 'TcEncoding' := 'UTF-8'}
  //test_name : STRING(80);
  
  name: INT;
  
  Sensor : REAL;
  
  Sensorsatz2 : ST_2;
END_STRUCT
END_TYPE

Code:
{attribute 'pack_mode' := '1'}
{attribute 'OPC.UA.DA.StructuredType' := '1'}
TYPE ST_2:
STRUCT
    Sensor1 : REAL;
END_STRUCT
END_TYPE

Code:
PROGRAM MAIN
VAR
    x : INT;
    {attribute 'OPC.UA.DA' := '1'}
    st_Values : ST_Values;
END_VAR

Code:
x := x +1;
st_Values.test[1].Sensor1 := 0.5 * x;
st_Values.test[7].Sensor1 := 3 * x;
st_Values.Sensor := x;
OPC_via_PLCopen();

Code:
PROGRAM OPC_via_PLCopen
VAR
    iState : INT := 0;
    iStatePrevious : INT := 0;
    bStart : BOOL := FALSE;
    bError : BOOL := FALSE;
    
    {attribute 'displaymode':='hex'}
    nErrorID : DWORD;
    
    (* Declarations for UA_Connect *)
    fb_UA_Connect : UA_Connect;
    sOpcUaServerUrl : STRING(MAX_STRING_LENGTH) := 'opc.tcp://localhost:4840';
    
    stUASessionConnectInfo : ST_UASessionConnectInfo := (    eSecurityMode:= eUASecurityMsgMode_None,
                                                            eSecurityPolicyUri:= eUASecurityPolicy_None,
                                                            eTransportProfileUri:= eUATransportProfileUri_UATcp,
                                                            sApplicationName:= '',
                                                            tConnectTimeout:= T#1M,
                                                            tSessionTimeout:= T#1M);
    
    nConnectionHdl : DWORD;
    
    (* Declarations for UA_GetNamespaceIndex *)
    fbUA_GetNamespaceIndex : UA_GetNamespaceIndex;
    nNamespaceIndex : UINT;
    
    // Für die Siemens anpassen! Im UAExpert: Server/NameSpaceArray hier unter Value/Value die Uri auswählen
    sNamespaceUri : STRING(MAX_STRING_LENGTH) := 'urn:BeckhoffAutomation:Ua:PLC1';
    
    (* Declarations for UA_NodeGetHandle *)
    fbUA_NodeGetHandle : UA_NodeGetHandle;
    
    // IdentifierType und Identifier anpassen! Im UAExpert: Objects/PLC1/... (Signal suchen), dann unter NodeID
    sNodeIdentifier : STRING(Max_STRING_LENGTH) := 'MAIN.st_Values';
    NodeID : ST_UANodeID := (    eIdentifierType := eUAIdentifierType_String,
                                nNamespaceIndex := nNamespaceIndex,
                                sIdentifier := sNodeIdentifier);
    nNodeHdl : DWORD;
    
    (* Declarations for UA_Read *)
    fbUA_Read : UA_Read;
    stIndexRange : ARRAY [1..nMaxIndexRange] OF ST_UAIndexRange;
    nIndexRangeCount : UINT;
    stNodeAddInfo : ST_UANodeAdditionalInfo;
    
    {attribute 'pack_mode' := '1'}
    {attribute 'OPC.UA.DA.StructuredType' := '1'}
    nReadData : ST_Values;
    cbDataRead : UDINT;
    
    (* Declarations for UA_NodeReleaseHandle *)
    fbUA_NodeReleaseHandle : UA_NodeReleaseHandle;
    
    (* Declarations for UA_Disconnect *)
    fbUA_Disconnect : UA_Disconnect;
    bDisconnect : BOOL := FALSE;
    
    bClearError : BOOL := FALSE;
END_VAR

Code:
CASE iState OF 

0: (* Idle *)
IF bStart THEN // Waiting for Rising Edge in bStart
    bStart := FALSE;
    bError := FALSE;
    nErrorID := 0;
    
    iStatePrevious := iState;
    iState := 10; // Open UA sessrion
END_IF

10: (* Open UA session *)
fb_UA_Connect(    Execute := TRUE,
                ServerURL := sOpcUaServerUrl,
                SessionConnectInfo := stUASessionConnectInfo,
                Timeout := T#5S,
                ConnectionHdl => nConnectionHdl);

IF NOT fb_UA_Connect.Busy THEN
    fb_UA_Connect(Execute := FALSE);
    iStatePrevious := iState;
    IF NOT fb_UA_Connect.Error THEN
        iState := 20; // Get Nampe-Space-Index
    ELSE
        bError := TRUE;
        nErrorID := fb_UA_Connect.ErrorID;
        nConnectionHdl := 0;
        iState := 100; // Error State
    END_IF
END_IF

20: (* Get Nampe-Space-Index *)
fbUA_GetNamespaceIndex(    Execute := TRUE,
                        ConnectionHdl := nConnectionHdl,
                        NamespaceUri := sNamespaceUri,
                        NamespaceIndex => nNamespaceIndex);
                        
IF NOT fbUA_GetNamespaceIndex.Busy THEN
    fbUA_GetNamespaceIndex(Execute := FALSE);
    iStatePrevious := iState;
    IF NOT fbUA_GetNamespaceIndex.Error THEN
        iState := 30; // Get Node-Handle
    ELSE
        bError := TRUE;
        nErrorID := fbUA_GetNamespaceIndex.ErrorID;
        iState := 100; // Error State
    END_IF
END_IF

30: (* Get Node-Handle *)
NodeID.nNamespaceIndex := nNamespaceIndex; // update NameSpaceIndex

fbUA_NodeGetHandle(    Execute := TRUE,
                    ConnectionHdl := nConnectionHdl,
                    NodeID := NodeID,
                    NodeHdl => nNodeHdl);
                    
IF NOT fbUA_NodeGetHandle.Busy THEN
    fbUA_NodeGetHandle(Execute := FALSE);
    iStatePrevious := iState;
    IF NOT fbUA_NodeGetHandle.Error THEN
        iState := 40; // Read Data
    ELSE
        bError := TRUE;
        nErrorID := fbUA_NodeGetHandle.ErrorID;
        iState := 100; // Error State
    END_IF
END_IF

40: (* Read Data *)
fbUA_Read(    Execute := TRUE,
            ConnectionHdl := nConnectionHdl,
            NodeHdl := nNodeHdl,
            cbData := SIZEOF(nReadData),
            stNodeAddInfo := stNodeAddInfo,
            pVariable := ADR(nReadData));

IF NOT fbUA_Read.Busy THEN
    fbUA_Read( Execute := FALSE, cbData_R => cbDataRead);
    iStatePrevious := iState;
    IF (NOT fbUA_Read.Error) AND (NOT bDisconnect) THEN
        iState := 40; // Read Data
    ELSIF (NOT fbUA_Read.Error) AND bDisconnect THEN
        bDisconnect := FALSE;
        iState := 50; // Release Node Handle
    ELSE
        bError := TRUE;
        nErrorID := fbUA_Read.ErrorID;
        iState := 100; // Error State
    END_IF
END_IF

50: (* Release Node Handle *)
fbUA_NodeReleaseHandle(    Execute := TRUE,
                        ConnectionHdl := nConnectionHdl,
                        NodeHdl := nNodeHdl);
IF NOT fbUA_NodeReleaseHandle.Busy THEN
    fbUA_NodeReleaseHandle(Execute := FALSE);
    iStatePrevious := iState;
    IF NOT fbUA_NodeReleaseHandle.Error THEN
        iState := 60; // Disconnect UA Session
    ELSE
        bError := TRUE;
        nErrorID := fbUA_NodeReleaseHandle.ErrorID;
        iState := 100; // Error State
    END_IF
END_IF

60: (* Disconnect UA Session *)
fbUA_Disconnect(    Execute := TRUE,
                    ConnectionHdl   := nConnectionHdl);

IF NOT fbUA_Disconnect.Busy THEN
    fbUA_Disconnect(Execute := FALSE);
    iStatePrevious := iState;
    IF NOT fbUA_Disconnect.Error THEN
        iState := 0; // Idle
    ELSE
        bError := TRUE;
        nErrorID := fbUA_Disconnect.ErrorID;
        iState := 100; // Error State
        nConnectionHdl := 0;
    END_IF
END_IF

100: (* Error State *)
IF bClearError THEN
    bClearError := FALSE;
    bError := FALSE;
    nErrorID := 0;
    iState := 0; // Idle
END_IF

END_CASE
 
Zuletzt bearbeitet:
Zurück
Oben