Einzelnen Beitrag anzeigen

Moien

Registriert seit: 20. Feb 2020
6 Beiträge
 
#1

Typecasting eines Arrays von Byte und Schreiben in verschiedene Variablen in Delphi

  Alt 24. Feb 2020, 09:02
Delphi-Version: 10.2 Tokyo
Hallo Zusammen,

ich versuche, ein Array von Byte aus einer S7-SPS über eine OPC-UA-Verbindung aus meinem Delphi-Programm zu lesen. Dieses Byte-Array besteht aus allen möglichen Variablen wie Bool, Real, DateTime, Integer und ... aus der SPS (aber alle als ein kompaktes Byte-Array). Ich muss die Einträge dieses Arrays in interne Delphi-Variablen konvertieren. Das bedeutet, dass z.B. die ersten vier Bytes (0..3) des SPS Byte-Arrays zur ersten Integer-Variable in Delphi gehören und die nächsten acht Bytes (4..11) zur zweiten Variable in Delphi, nämlich TDateTime. Gibt es eine Idee, wie dieses Typecasting effizient durchgeführt werden kann? Ich kenne die Reihenfolge und den Typ der internen Variablen in delphi. Ich habe ein dynamisches Array in delphi "OPCServerItemArray" und habe alle Variablen mit den entsprechenden Namen und Typen darin abgelegt.
Delphi-Quellcode:
Procedure TOPCClient.ReadAllItems;
 var
 ReadVar_vonSPS : Array of Byte;
 AttributeSPSData : UAAttributeData;
 I: Integer;
 ItemRead : Boolean;
 Name : String;
 OPCUAResult: _UAAttributeDataResult;
 OPCUAResults: OleVariant;
 J,K: Cardinal;
 
 begin
   SetLength(ReadOPCUAArguments,Length(OPCServerItemArray)-NoV_DB100);
   try
 
     if (Connected) then begin
        AttributeSPSData := OPCUAClientSPS.Read(Url_String,'nsu=Siemens1' + ';s=' + S0);
        ReadVar_vonSPS := AttributeSPSData.Value;
        for I := 0 to NoV_DB100-1 do begin
           OPCServerItemArray[I].Value := //??? Typecasting --> ReadVar_vonSPS
           OPCServerItemArray[I].ItemQuality := AttributeSPSData.StatusCode;
           OPCServerItemArray[I].TimeStamp := AttributeSPSData.ServerTimestamplocal;
        end;
 
        if (FirstCylyle) then begin
 
          for J := NoV_DB100 to Length(OPCServerItemArray)-1 do begin
             Name := OPCServerItemArray[J].Source + '.' + OPCServerItemArray[J].ItemName;
             ReadOPCUAArguments[J-NoV_DB100] := CoUAReadArguments.Create;
             ReadOPCUAArguments[J-NoV_DB100].ReadParameters.MaximumAge := 100;
             ReadOPCUAArguments[J-NoV_DB100].EndpointDescriptor.UrlString := Url_String;
             ReadOPCUAArguments[J-NoV_DB100].NodeDescriptor.NodeId.ExpandedText := 'nsu='+ nsu + ';s=Local Items.' + Name;
          end;
 
          OPCUAArguments := VarArrayCreate([0, Length(OPCServerItemArray)-NoV_DB100-1], varVariant);
          for I := 0 to Length(OPCServerItemArray)-NoV_DB100-1 do begin
             OPCUAArguments[I] := ReadOPCUAArguments[I];
          end;
          FirstCylyle := False;
        end;
        // Perform the operation
        TVarData(OPCUAResults).VType := varArray or varVariant;
        TVarData(OPCUAResults).VArray := PVarArray(OPCUAClientRead.ReadMultiple( //OPVLabs 2019.1 Version
        PSafeArray(TVarData(OPCUAArguments).VArray)));
 
        // Writing the results in Delphi internal Array
        for K := VarArrayLowBound(OPCUAResults, 1) to VarArrayHighBound(OPCUAResults, 1) do
        begin
           OPCUAResult := IInterface(OPCUAResults[K]) as _UAAttributeDataResult;
           OPCServerItemArray[NoV_DB100+K].Value := OPCUAResult.AttributeData.value;
           OPCServerItemArray[NoV_DB100+K].ItemQuality := OPCUAResult.AttributeData.StatusCode;
           OPCServerItemArray[NoV_DB100+K].TimeStamp := OPCUAResult.AttributeData.ServerTimestamplocal;
        end;
 
     end else begin
         Meldung(0,'TOPCClient.ReadAllItems: (Not connected to the OPC UA Server!)');
     end;
 
   except
     on E: Exception do begin
       Meldung(0,'TOPCClient.ReadAllItems - Exception: ' + E.Message);
     end;
 
   end;
 
 end;
mfg,
Moien
  Mit Zitat antworten Zitat