Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 3 von 3

Thema: Lösung: 2 Structs miteinander vergleichen ohne vorher die Struktur zu kennen.

  1. #1
    Registriert seit
    04.03.2015
    Beiträge
    52
    Danke
    9
    Erhielt 13 Danke für 5 Beiträge

    Idee


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo zusammen,
    ich habe eine Lösung gefunden um 2 Structs miteinander zu vergleichen. Es gab dabei mehrere Probleme vorallem mit Strings die ihre vorherigen Einträge nicht löschen wenn dieser mit einem Kürzerer String überschrieben wurde

    Ich benutze eine S7 1513-1 PN

    Es wird ein "nicht bausteinoptimierter" DB benötigt der 2 Arrays mit jeweils einem Array[0..300] of Byte enthält ( die 300 kann natürlich variieren)

    Code:
    IN:
    IN_1           : Variant
    IN_2           : Variant
    
    OUT :
    Unterschied_erkannt : Bool
    
    Temp:
    i               : int
    LEN_1        : dint
    LEN_2        : dint
    RET_VAL_1 : int
    RET_VAL_1 : int
    Unterschied : bool
    
    //Structs in Array of byte kopieren
    #RET_VAL_1 := Serialize(SRC_VARIABLE := #IN_A, DEST_ARRAY=>"GLB_HW_Vergleichs_DB".A , POS:= #LEN_1);
    #RET_VAL_2 := Serialize(SRC_VARIABLE := #IN_B, DEST_ARRAY=>"GLB_HW_Vergleichs_DB".B, POS:= #LEN_2);
    
    
    #Unterschied := false;
    
    // arrays bytweise vergleichen und Array anschließend auf 0 setzen !Wichtig!
    IF #LEN_1 = #LEN_2 THEN
        FOR #i := 0 TO #LEN_1 DO
            IF "GLB_HW_Vergleichs_DB".A[#i] <> "GLB_HW_Vergleichs_DB".B[#i] THEN
                #Unterschied := true;
                 EXIT;
            END_IF;
            "GLB_HW_Vergleichs_DB".A[#i] := 0;
            "GLB_HW_Vergleichs_DB".B[#i] := 0;
        END_FOR;
    ELSE
    // wenn Längen unterschiedlich dann sind die Structs eh unterschiedlich
        #Unterschied := true;
    END_IF;
    
    Unterschied_erkannt := Unterschied;
    ich hoffe es nützt euch

    Balu

    *edit Anmerkungen von Harald eingebaut
    Geändert von Balu_der_Bär (25.08.2016 um 13:26 Uhr)
    Zitieren Zitieren Lösung: 2 Structs miteinander vergleichen ohne vorher die Struktur zu kennen.  

  2. Folgender Benutzer sagt Danke zu Balu_der_Bär für den nützlichen Beitrag:

    vollmi (25.08.2016)

  3. #2
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    9.550
    Danke
    823
    Erhielt 2.821 Danke für 2.272 Beiträge

    Standard

    Hallo Balu,

    zunächst mal Danke für die Veröffentlichung Deiner Idee. Unter TIA funktioniert ja vieles nicht mehr so einfach.
    Trotzdem ein paar Fragen und Kritiken.

    1) Warum vergleichst Du die Arrays erst ab dem zweiten Byte?
    2) Warum ist es wichtig, die Array-Bytes nach dem Vergleich auf 0 zu setzen?
    3) Sobald der erste Unterschied gefunden wurde kann man den Vergleich (Schleife) abbrechen.
    4) Es ist ungünstig, dem OUT "Unterschied" mehrmals Werte zuzuweisen. Besser eine interne Variable benutzen und am Ende die interne Variable auf den OUT kopieren.
    5) Wo/Wie ist das Problem mit dem STRING-Vergleich gelöst?

    Weil ich gerade kein TIA zur Verfügung habe:
    6) Wie geht "Serialize" mit vom TIA versteckten Struct-Membern und mit Padding-Bytes und Padding-Bits um?
    7) Wie ist die Repräsentation von Bools nach dem Serialize?

    PS: Du könntest noch erwähnen, für welche SPS der Code gedacht ist.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  4. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Balu_der_Bär (25.08.2016)

  5. #3
    Registriert seit
    04.03.2015
    Beiträge
    52
    Danke
    9
    Erhielt 13 Danke für 5 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Harald,
    danke für deine Anmerkungen

    1) Warum vergleichst Du die Arrays erst ab dem zweiten Byte?

    Danke das war ein Fehler meinerseits.

    2) Warum ist es wichtig, die Array-Bytes nach dem Vergleich auf 0 zu setzen?

    Da muss ich ein wenig weiter ausholen auch in der Vermutung das ich viel bekanntes erzähle.

    Wenn ein Variable of String in eine andere Variable kopiert wird, wird nur der "sichtbare" Teil kopiert + die Maximale und die genutzte länge.

    Bsp:
    Variable A und B sind vom Typ String[10]
    A := 'test'
    B := '1234567890'

    Trotz der nur [10] Zeichen hat die Variable aber 12 Byte Länge, da vorweg noch die Maximale länge (10) und die tatsächlich genutzten Zeichen ( für A 4) stehen.

    Kopiert man nun A nach B steht dort zwar Symbolisch B ='test' , schaut man sich jedoch den String als Array an sieht man das dort 'test567890' steht und nur durch den nicht sichtbaren "genutzte Länge" Teil der Rest nicht berücksichtigt wird.

    Problematisch wird es wenn man einen Umweg über eine weitere Variable geht
    A := 'test'
    B := 'XXXXXX'
    C := '1234567890'
    D := ''
    E := ''

    Wenn wir nun folgende schritte abarbeiten:
    D := C
    D := B
    D := A
    E := C
    E := A

    Haben wir durch das mehrfache überschreiben zwar symbolisch in E und D 'test' stehen, aber wenn man sich das ganze Absolut anschaut steht in E 'test567890' und in D 'testXX7890'

    Da man Strukturen nicht miteinander vergleichen kann muss man diese Byte weise vergleichen und dann haben wir das eben gezeigte Problem das trotz der Symbolischen Gleichheit es einen Unterschied gibt.

    Man müsste also vor jedem Kopiervorgang die variable D und E initialisieren.

    Wenn man auf die absolute Adressierung verzichten will, fallen die normalen Move befehle
    ( ":=" , "Move_blk_variant") weg, da diese nur 2 gleichen Datentypen zum kopieren akzeptieren und ich nicht weiß wo sich der String befindet den ich löschen will.

    Daher nutze ich den "Serialize" Befehl, der die ganze Struktur in ein Array of Byte kopiert und überschreibe nach jedem vergleichen das Byte mit 0, damit beim nächsten kopieren die "Phantomzeichen" gelöscht sind.


    3) Sobald der erste Unterschied gefunden wurde kann man den Vergleich (Schleife) abbrechen.

    in meinem Fall überprüfe ich zyklisch ob sich die Eingabe im Editorfenster gegenüber dem gespeichertem im Array geändert hat. Dies wird in 99,9% der Fälle nicht der Fall sein , daher habe ich darauf verzichtet da es auf das eine Mal dann auch nicht mehr drauf an kommt. In anderen Bereichen kann das aber durchaus Sinn machen ja.


    4) Es ist ungünstig, dem OUT "Unterschied" mehrmals Werte zuzuweisen. Besser eine interne Variable benutzen und am Ende die interne Variable auf den OUT kopieren.
    Hast du recht, ändere ich ab.

    5)Wo/Wie ist das Problem mit dem STRING-Vergleich gelöst?

    siehe 2

    6) Wie geht "Serialize" mit vom TIA versteckten Struct-Membern und mit Padding-Bytes und Padding-Bits um?

    Ich denke das alle Informationen dort abgebildet werden.In meinem Beispiel hatte ein String der Länge[10] 22 Byte belegt.Da ich davon nur 12 Byte zuordnen kann muss da noch einiges verstecktes drin sein.
    Serialize ist dafür gemacht um ein Struct über einen Seriellen Bus auf eine andere SPS zu übertragen. Das Gegenstück nennt sich dann Deserialize. Um das Struct exakt kopieren zu können müssen ja alle Informationen vorhanden sein.
    Aber mehr kann ich dir dazu nicht sagen.

    7) Wie ist die Repräsentation von Bools nach dem Serialize?
    müsste ich ausprobieren, komme ich aber heute nicht mehr zu

Ähnliche Themen

  1. Antworten: 6
    Letzter Beitrag: 25.02.2016, 16:05
  2. 2 Datenbausteine miteinander vergleichen
    Von SPS-Fuchs im Forum Simatic
    Antworten: 18
    Letzter Beitrag: 10.12.2015, 08:44
  3. TIA Zeiten miteinander vergleichen
    Von kuti im Forum Simatic
    Antworten: 17
    Letzter Beitrag: 22.09.2013, 19:44
  4. UDTs miteinander vergleichen
    Von Freakazoid im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 25.03.2011, 10:08
  5. 3 Char miteinander vergleichen
    Von MK_Auto im Forum Simatic
    Antworten: 17
    Letzter Beitrag: 13.11.2010, 09:42

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •