C#, viele verscheidene Strukturierte Daten schnell auslesen, Traeger IP S7 LINK PLC

mbi

Level-2
Beiträge
96
Reaktionspunkte
14
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo
Sollte mit dem Treiber von Traeger verschiedene Daten schnell auslesen.
Hab jetzt die UDT's auf der SPS als Klasse abgebildet.
Wenn ich jetzt meine Daten so auslese
C#:
A3_Vor_KZ plcdata_A3_Vor_KZ = connection.ReadObject<A3_Vor_KZ>();
A4_Vor_KZ plcdata_A4_Vor_KZ = connection.ReadObject<A4_Vor_KZ>();
A5_Vor_KZ plcdata_A5_Vor_KZ = connection.ReadObject<A5_Vor_KZ>();
Braucht es verglichen mit einem Array auslesen der gleichen grösse viel Länger.
Wie könnte ich die Funktion optimieren?
Wie so oft gibt es kein Beispiel für ein gutes Design wenn es über 'Hello World' hinausgeht.
Wahrscheinlich sind auch meine C# Kenntnisse mangelhaft und nicht der Treiber das Problem.
Wer kann mir helfen.
Danke
 
Du könntest theoretisch ein Array of Bytes auslesen, damit würde das Auslesen schneller funktionieren.

Deine erstellte Klasse bzw. die Objekte für deine Strukturen könntest du dann dementsprechend deserialisieren aus den gegebenen Bytes.
Habe etwas derartiges schon einmal gemacht:

1728812504454.png
 
Hallo Rabi
Vielen Dank für dein Vorschlag.
Hab das mal getestet und es ist viel schneller.
Jedoch hatte ich dann das Problem mit dem Datentyp Bool.
Gemäss mir ist Bool auf der SPS kein Byte gross (S7-300) in C# schon.
Hatte noch keine Zeit das zu korrigieren. Falls ich dazu komme werde ich den Code posten.
Danke
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Super.

Das mit dem Bool stimmt nicht ganz. Ein Bool ist natürlich für alle Steuerungen nur ein Binärer Vergleich.
Aber falls du schon einmal darauf geachtet hast, werden die Adressen in der S7-300, falls du ein einzelnes Bool anlegst ebenfalls für 2 Byte reserviert. Bedeutet wenn du nach dem Bool z.B.: ein Word definierst, beginnt das erst ab Adresse 2.0.

Wenn du mit Träger ausliest, denke ich, wirst du weiterhin den Byte-Stream kriegen.
Hast du nun in einem Byte mehrere Bits, dann kannst du die noch mit so einer Funktion zerlegen.

Würde die empfehlen, das ganze dann in die Deserialisierungs-Methode gleich einzubetten.

1729148560316.png
 
Ich kann ja wunderbar mein Objekt der Deserialisierungs-Methode von dir übergeben.
Nur leider (so verstehe ich es) macht der BinaryReader sobald Bools kommen die Adresse um 1 Byte höher.
Der SPS Programmierer hat schon sauber darauf geachtet das keine 'Lücken' sind
Auszug unten. Ein paar Bits und dann mal wieder ein int. Aber keine Adress 'Lücken'.

C#:
            [PlcMember("DB110.DBX1865.3")]
            public bool DBX1_3 { get; set; } = false;

            [PlcMember("DB110.DBX1865.4")]
            public bool Einlaufbelegt { get; set; } = false;

            [PlcMember("DB110.DBX1865.5")]
            public bool DBX1_5 { get; set; } = false;

            [PlcMember("DB110.DBX1865.6")]
            public bool Auslaufbelegt { get; set; } = false;

            [PlcMember("DB110.DBX1865.7")]
            public bool Maschinbelegt { get; set; } = false;

            [PlcMember("DB110.DBB1866")]
            public byte DBB2 { get; set; } = 0;

            [PlcMember("DB110.DBX1867.0")]
            public bool DBX3_0 { get; set; } = false;

            [PlcMember("DB110.DBX1867.1")]
            public bool DBX3_1 { get; set; } = false;

            [PlcMember("DB110.DBX1867.2")]
            public bool DBX3_2 { get; set; } = false;
 
Alles klar, jetzt weiß ich was du meinst.

Ich weiß leider nicht wie dein Treiber das handelt, aber im ByteStream den du empfängst ist definitiv jedes Bool dass du angefragt hast, auch in einem eigenen Byte gespeichert, kannst du mit Wireshark prüfen, dort siehst du unter dem S7COMM im Body sozusagen die Bytes die dein Bool enthalten.

Vermutlich wird der Träger Treiber dir das dann auf einzelne Bool Variablen zerlegen, indem er prüft welches Bit du aus diesem Byte abgefragt hast.

Da ich meinen Treiber selbst geschrieben habe, erhalte ich beim Auslesen immer einen Byte-Stream zurück.
Dadurch treten bei mir diese Probleme auch nicht auf, da jedes Bool im Stream ein eigenes Byte hat und ich daher keine Bool überspringe.

Sozusagen deserialisiere ich meinen empfangenen Stream bereits, bevor ich ihn noch weiter an meine Klassen-Deserialisierung übergebe, damit alles seine Form hat.

Ein Ausschnitt, wie der Stream bereits interpretiert wird - das ganze ist doch schon ein paar Jahre her....

1729168348553.png
 
Zurück
Oben