Step 7 Vergleichen von Strukturen

IN SCL können Strukturen direkt miteinander verglichen werden Classic und TIA

IF Struct1 = Struct2
then
:
 
Hallo Ihr,

gehe ich richtig in der Annahme, dass es die Vergleichs-Funktion wirklich nicht gibt?

Andere Funktionen habe ich gefunden:

MEMCPY -> SFC 20 BLKMOV Variable kopieren
MEMSET -> SFC 21 FILL Feld vorbesetzen
MEMCMP -> ??? Variablen Vergleichen

Kann Doch nicht sein, dass es nicht mal einen Behelf für MEMCMP gibt!? :icon_confused:

Gruß
Chräshe
 
Andere Funktionen habe ich gefunden:

MEMCPY -> SFC 20 BLKMOV Variable kopieren
MEMSET -> SFC 21 FILL Feld vorbesetzen
MEMCMP -> ??? Variablen Vergleichen

Zum Kopieren von Strukturen braucht man in SCL keine SFC20.
Hier genügt eine normale Zuweisung.

Zum Vorbesetzen einer Struktur dürfte SCF21 auch nicht sonderlich geeignet sein.

Beim Vergleich von Strukturen stellen sich einige Fragen:
- geht es um eine bestimmte Struktur oder um viele verschiedene Strukturen
- wie groß ist die Struktur (Vergleich in einen Zyklus möglich oder über mehrere Zyklen verteilen)
- wie viele Elemente enthält die Struktur
- usw.

Ich würde nicht lange nach fertigen/Fremd-Lösungen suchen, sondern einfach einen passenden Vergleicher programmieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zum Kopieren von Strukturen braucht man in SCL keine SFC20.
Hier genügt eine normale Zuweisung.

Zum Vorbesetzen einer Struktur dürfte SCF21 auch nicht sonderlich geeignet sein.

Beim Vergleich von Strukturen stellen sich einige Fragen:
- geht es um eine bestimmte Struktur oder um viele verschiedene Strukturen
- wie groß ist die Struktur (Vergleich in einen Zyklus möglich oder über mehrere Zyklen verteilen)
- wie viele Elemente enthält die Struktur
- usw.

Ich würde nicht lange nach fertigen/Fremd-Lösungen suchen, sondern einfach einen passenden Vergleicher programmieren.

Bestimmt wäre ich im aktuellen Anwendungsfall schneller, wenn ich meine 20 Worte stupide einzeln vergleiche, als nach Lösungen zu suchen, die es nicht gibt.

Von einem „modernen“ Werkzeug könnte man aber erwarten, dass es einem bei der Arbeit etwas unterstützt.

Mein Wunsch wäre gewesen, dass ich bei Änderungen in der Struktur, das restliche Programm nicht anfassen muss.
 
Mein Wunsch wäre gewesen, dass ich bei Änderungen in der Struktur, das restliche Programm nicht anfassen muss.
Dein Programm soll erkennen ob sich der Aufbau der Struktur geändert hat? Das ist nicht möglich, das wäre auch mit MEMCMP nicht möglich.


Von einem „modernen“ Werkzeug könnte man aber erwarten, dass es einem bei der Arbeit etwas unterstützt.
Wenn SPS-Programmieren modern und einfach aussieht, dann traut sich auch jedermann die Programmierung zu. Siehe das häufige ST- und SCL-Gestümpere.

Im übrigen sind SPS-Programme in der Regel so stabil, weil sie eben nicht versuchen, sich automatisch auf Änderungen der Laufzeitumgebung anzupassen. Fast alles was schon der Compiler berechnen kann, das sollte nicht zur Laufzeit berechnet werden. Außerdem haben SPS-Programme nur sehr begrenzt Rechenzeit zur Verfügung und müssen anders programmiert werden als ein Wald- und Wiesen-Programmierer denkt. Wenn man versucht "moderne" Methoden einzuführen, dann bekommt man auch die anderen modernen Softwareeffekte wie massig Bugs und Abstürze und hochfrequent nötige Updates.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dein Programm soll erkennen ob sich der Aufbau der Struktur geändert hat?
Nein, ich will nur in einem Array of Struct den Inhalt von zwei Elementen miteinander vergleichen. Ich brauche nur die Information „gleich“ oder „ungleich“.

Wenn ich, weil ich im Voraus nicht an alles gedacht habe, nachträglich diese Struktur ändere, weiß ich, dass ich die Änderung besser nicht online bei laufender Maschine aufspielen sollte, weil sich Datenbereich verschieben.

Bei der aktuellen TwinCAT- Version wäre meines Wissens sogar ein Online-Chance von geänderten Strukturen möglich. Wenn es vermeidbar ist, lasse ich aber solche Experimente lieber sein. ;)
 
Von einem „modernen“ Werkzeug könnte man aber erwarten, dass es einem bei der Arbeit etwas unterstützt.

Bei diesem Wunsch würde ich generell von Siemens-Produkten abraten.
Sind einfach nicht anwenderfreundlich.
z. B. gibt es noch immer Editoren, die Probleme mit Standardfunktionen wie Ctrl+C / Ctrl+V haben.

Zu deinem Problem:
Wenn sich die Struktur ändert, wirst du so oder so auch dein restliches Programm anpassen müssen.
Oder ändert sich deine Struktur ohne irgendeine Auswirkung auf dein Programm?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Woran hapert es denn?

Hallo Onkel,

es hapert daran, dass ich keine Funktion finde, der ich zwei ANY übergeben kann und die mir diese auf Ungleichheit überprüft. Das bringt mich gerade auf die Idee, dass ich mir was basteln könnte, was die übergebenen Daten byteweise vergleicht. Bei der ersten Ungleichheit kann abgebrochen und TRUE ausgegeben werden.

Mal schauen, ob ich morgen das Gegenstück zur Funktion ADR und SIZEOF finde, oder es da die nächste Einschränkung gibt...

Gruß
Chräshe
 
SIZEOF bzw. alle Infos die Du brauchst findest Du im ANY. Du kannst auch Word-weise vergleichen, das ist schneller.

Harald
 
Achja, Du mußt Deine Struktur so aufbauen/deklarieren, daß sie keine unsichtbaren Padding-Bits oder Padding-Bytes enthält, weil eine Byteweise/Wordweise Vergleichsfunktion nicht nur die Struktur-Member vergleicht, sondern den gesamten von der Struktur belegten Speicherbereich. Es wäre fatal, wenn da evtl. uninitialisierter Speicher mit zufälligem Inhalt mit-verglichen würde.

Vielleicht ist das auch der Grund, warum es eine solche fertige Vergleichsfunktion bei Siemens nicht gibt, weil es für jede Struktur bzw. jeden Datentyp eine eigene Vergleichsfunktion geben müsste. Ähnlich den überladenen Vergleichsoperatoren in anderen Programmiersprachen.

Harald
 
.. weil es für jede Struktur bzw. jeden Datentyp eine eigene Vergleichsfunktion geben müsste..
Aus diesem Grund ist es empfehlenswert, die Struktur symbolisch zu übergeben. Geht das bei einem STRUCT eigentlich anders? Bei symbolischer Übergabe wird immer im Datenformat "Byte" übergeben. Vor der Bearbeitung sollte man Das Datenformat sicherheitshalber noch einmal überprüfen.

Ich gebe mal etwas Starthilfe, falls es recht ist. Nichts Fertiges, nur das "Drumherum". Das Beispiel ist aus einem ähnlichem Sachverhalt. Wichtig, so wie hier programmiert muss es eine Funktion sein, kein Funktionsbaustein!
Code:
VAR_INPUT
  DATENBEREICH : ANY ;    //Datenbereich der auf Änderungen überwacht werden soll
  FLANKENMERKER : ANY ;    //Flankenmerker für Überwachung Datenbereich
END_VAR
VAR_OUTPUT
  POS_IMP : BOOL ;    //pos. Flanke im Datenbereich gefunden
  NEG_IMP : BOOL ;    //neg. Flanke im Datenbereich gefunden
  ENTRY : BOOL ;    //statisch: mind. ein Eintrag ist im Datenbereich vorhanden
  ERROR : INT ;    //0-kein Fehler, 1-Typ 1 nicht Byte, 2-Typ 2 nicht Byte, 3-Bereiche verschieden groß
END_VAR
VAR_TEMP
  AR1_TEMP : DWORD ;    
  TEMP_INT : WORD ;    
  TEMP_DINT : DWORD ;    
  LOOP : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =

//*** AR1 sichern
      TAR1  #AR1_TEMP; 
      SET   ; 
      SAVE  ; 

//*** Ergebnisse initialisieren
      L     B#16#0; 
      T     #ERROR; 
      SET   ; 
      R     #POS_IMP; 
      R     #NEG_IMP; 
      R     #RET_VAL; 
      R     #ENTRY; 

//*** AR2 auf Datenbereich
      L     P##DATENBEREICH; 
      LAR2  ; 

//*** AR1 auf Flankenmerker
      L     P##FLANKENMERKER; 
      LAR1  ; 

//*** Prüfe, ob DATENBEREICH vom Typ=Byte
      L     W [AR2,P#0.0]; // Typ 
      L     W#16#1002; 
      ==I   ; 
      L     1; // Fehler 1: DATENBEREICH nicht vom Typ Byte
      SPBN  ERR; 

//*** Prüfe, ob FLANKENMERKER vom Typ=Byte
      L     W [AR1,P#0.0]; // Typ 
      L     W#16#1002; 
      ==I   ; 
      L     2; // Fehler 2: FLANKENMERKER nicht vom Typ Byte
      SPBN  ERR; 

//*** Prüfe, ob Datenbereiche gleich groß
      L     W [AR2,P#2.0]; // Anzahl Typ im DATENBEREICH
      L     W [AR1,P#2.0]; // Anzahl Typ im FLANKENMERKER
      T     #LOOP; // Schleifenzähler initialisieren
      ==I   ; 
      L     3; // Fehler 3: Bereiche unterschiedlich groß
      SPBN  ERR; 

//*** DB's öffnen und Adressregister auf Bereichszeiger
      L     W [AR2,P#4.0]; 
      T     #TEMP_INT; 
      AUF   DB [#TEMP_INT]; 
      L     D [AR2,P#6.0]; 
      LAR2  ; // DATENBEREICH

      L     W [AR1,P#4.0]; 
      T     #TEMP_INT; 
      AUF   DI [#TEMP_INT]; 
      L     D [AR1,P#6.0]; 
      LAR1  ; // FLANKENMERKER

//*** Schleife für was auch immer
      L     #LOOP; 
LOOP: T     #LOOP; 
                                
[COLOR=#0000ff]         .=======================ooooooo
 ___   ,'    \_________________________________________
/   /-/   dP  /                           ////////////  ''--..._
\___\-\  dP   \  hier schreibst du        \\\\\\\\\\\\  __..--'
       `---------------------------------''''''''''''''[/COLOR]

      +AR1  P#1.0; // Pointer erhöhen
      +AR2  P#1.0; // Pointer erhöhen
      L     #LOOP; 
      LOOP  LOOP; 

//*** AR1-Register wiederherstellen
      LAR1  #AR1_TEMP; 
      BEA   ; 

//*** Fehler
ERR:  T     #ERROR; 

//*** AR1-Register wiederherstellen
      LAR1  #AR1_TEMP; 
      BE    ; 

END_FUNCTION
 
Zuletzt bearbeitet:
Zurück
Oben