SCL -Arrays mit einander vergleichen

ja es geht ja auch darum das es ich es net nur wort weiße auf ungleich untersuchen will. Bekomme echt noch die Krise solange halt das zeug nicht angeschlossen ist von denen ich die Arrays bekomme kann ich es nur über umwege testen und das kostet voll viel zeit...

Es wird aber nicht einfacher, wenn du mit den "echten" Daten herummachst ...

Ich finde den schon gemachten Vorschlag mit dem "flexiblen" Auswerten gar nicht schlecht. Versuch doch mal eine Funktion (FC) zu bauen, der du per ANY-Pointer die beiden Quell-Datenblöcke übergibst. Der ANY-Pointer beinhaltet dann auch (zumindestens bei richtiger Handhabung) den Datentyp der Quelle(n) und du kannst das flexibel auswerten.
Dieser Vorschlag ist allerdings eine ganze Ecke aufwendiger als alles bisherige.

Zu deinem Script in Beitrag #32 noch einmal:
Die beiden Array's wert1 und wert2 werden auch nicht korrekt indexiert werden. Das eine (wert1) hast du nur 2 Elemente groß dimensioniert und das Zweite hat zwar die richtige Größe, die Schleife (iy) beginnt aber mit "0" und diesen Index hast du auch in keinem Array ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So nach dem das mit den vergleichen jetzt eigentlich fast passt... soll ich es doch anderster machen man die haben vllt nerven.

Die einfachste Änderung ist die, das der vergleich nur solange stattfinden soll bis er einen Änderung findet und dann abbrechen bzw mittels EXIT die Schleife verlassen.

Was den schwierigen teil an geht ist das ich mit einem pointer die Startadresse und endadresse des Arrays rauslesen soll und dann mittels der sozusagen gezählten Bites die forschleife starten soll.

Das problem ist nur das ich mit den pointer in SCl nicht klar komme.

Mit AWl ist es ja um die startadress rauszubekommen so:

L P#Name;
LAR1 P#Name;
LAr2 p#name;

zumindest steht es so in meinem buch aber leider halt nur in awl im internet habe ich bis jetzt auch nichts gefunden was es mir einfacher macht! hat da von euch jemand ne idee

Also wie gesagt AWl kann ich mir was außem internet zusammen suchen aber leider nicht in SCL!

Grüßle
 
Scl

Hi,
ich wollte mal was über die o.g. Schleife sagen:
Code:
......
iz: [B]ARRAY [1..5][/B] OF INT;
iu : INT;
END_VAR
VAR_INPUT
    start: BOOL;
END_VAR
    
VAR_OUTPUT
    
    ergebnis: BOOL;
END_VAR
 

BEGIN
IF start then    
  FOR ix := [B]0[/B] TO 5 DO
  iz[B][ix][/B]:= Wert1[1];           // hier wird iz[[B]0[/B]] angesprochen..gibt es aber nicht!

Vladi
 
ja die art kann ich ja jetzt eh nimma nehmen ahhte es aber gestern abend noch zum laufen mittels debug modus gebracht. ich musste aber zuerst in der hilfe suchen bei siemens das ich überhaupt wusste wie ich den debugger starte...

Habe noch ein beispiel mit zeiger in der hilfe gefunden nur steht da leider net dabei was das für variablen sind

Code:
BEGIN
IF neuwert <> altwert THEN
    zeiger := zeiger MOD Anzahl;
    messwert[zeiger] := messwert_ein;
    zeiger .= zeiger + 1;
END_IF;
altwert := neuwert;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Scl..

Hi,
Larry hat oben ein Vorschlag für eine FC mit Pointerübergabe..das solltest du dir anschauen, suche im Forum z.B. nach ANY Pointer..
Ablauf:
-die FC bekommt als Input die Pointer der Arrays: (P#DB100.dbx60.0 DWORD 32 und P#DB100.dbx100.0 DWORD 32 z.B.)
- diese Pointer werden mittels AT Schablone zerlegt, dann weisst du die Anfangsadresse, die Länge und was für Datentyp es ist.
- dann mittels Temp Variablen diese Arrays vergleichen(es sind mehrere Schleifen zu vorbereiten, je für ein Datentyp, und eben die richtige ausführen..) und Ergebnis ausgeben.

Vladi
 
@Vladi:
Schön, dass du den Ball noch einmal wieder ins Spiel gebracht hast ...

@Matthias:
Wenn du dir das zutraust - ist allerdings ein bißchen Arbeit damit verbunden - dann kannst du auf diesem Wege eine Funktion (FC) mit SCL erstellen, die im Prinzip so arbeitet, wie das ursprünglich von dir genannte Beispiel.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also war das nur ein Vorschlag von einer funktion oder hast du die gemacht? falls nicht muss ich mir da sowieso irgednwas einfallen lasse.

ich bin jetzt immerhin soweit das ich jetzt einen pointer habe denke ich zumindest...:confused:

Code:
FUNCTION_BLOCK FB25
VAR_TEMP
   zeiger: STRUCT
   ANY_Wert: BYTE;
   quelle_Typ: BYTE;
   quelle_Laenge: WORD;
   quelle_DB_Nr: WORD;
   quelle_byte_Zeiger: DWORD;
END_STRUCT;
pAny_quelle AT zeiger: ANY;
erg: INT;
END_VAR
zeiger.ANY_Wert := 16#10;
zeiger.quelle_Typ := 16#02;
zeiger.quelle_Laenge :=16#04;
zeiger.quelle_DB_NR := 16#06;
zeiger.quelle_byte_zeiger :=16#84;
 
END_FUNCTION_BLOCK

nur das problem ist das ich jetzt nicht weiß wie ich den weiter verwenden kann also in einem konkreten programm.
 
Ich habe etwas ähnliches schon einmal gemacht. Für die Zerlegung des Any-Pointers habe ich auch ein schönes Beispiel. Ein fertiges Programm wirst du von mir nicht erhalten - ich helfe aber gerne dabei, eins zu entwickeln. Wenn du von mir eine fertige Arbeit erhalten würdest, dann wäre dir im Endeffekt damit nicht geholfen - nur was man selber gemacht hat, das versteht man auch ...
 
Hier übrigens das Beispiel :
Code:
FUNCTION FC399 : VOID
Title   = 'UP Any-Pointer zerlegen'  // UP Any-Pointer zerlegen
 
//     Bausteinparameter
 
VAR_INPUT
   // Eingangsparameter
   DatenQuelle : ANY ;
END_VAR
 
VAR_OUTPUT
   // Ausgangsparameter
   Daten_Mem : STRING [4] ;
   Daten_Typ : STRING [4] ;
   Daten_DB  : WORD ;
   Daten_Ptr : DWORD ;
   Daten_1W  : INT ;
   Daten_Len : INT ; 
//   Inhalt : INT ;
END_VAR
 
VAR_TEMP
   // temporäre Variablen
   hDatenQuelle : ANY ;
   xDatenQuelle AT hDatenQuelle : STRUCT
              ID_Code   : BYTE ;  // 10h für S7
              DataTyp   : BYTE ;
              Anzahl    : WORD ;
              DB_Nr     : WORD ;
              SpeicherPtr : DWORD ;
              END_STRUCT ;
   yDatenQuelle AT hDatenQuelle : STRUCT
              ID_Code   : BYTE ;  // 10h für S7
              DataTyp   : BYTE ;
              Anzahl    : WORD ;
              DB_Nr     : WORD ;
              Speicherbereich : ARRAY [0..3] OF BYTE ;
              END_STRUCT ;
END_VAR
 
 
//     Anweisungsteil 
 
BEGIN
   hDatenQuelle := DatenQuelle ;
 
   IF    xDatenQuelle.DataTyp = w#16#00 THEN Daten_Typ := 'Nil' ;   // Nil
   ELSIF xDatenQuelle.DataTyp = w#16#01 THEN Daten_Typ := 'X' ;     // Bool
   ELSIF xDatenQuelle.DataTyp = w#16#02 THEN Daten_Typ := 'B' ;     // Byte
   ELSIF xDatenQuelle.DataTyp = w#16#03 THEN Daten_Typ := 'Char' ;  // Char
   ELSIF xDatenQuelle.DataTyp = w#16#04 THEN Daten_Typ := 'W' ;     // Word
   ELSIF xDatenQuelle.DataTyp = w#16#05 THEN Daten_Typ := 'Int' ;   // Integer
   ELSIF xDatenQuelle.DataTyp = w#16#06 THEN Daten_Typ := 'DW' ;    // Double-Word
   ELSIF xDatenQuelle.DataTyp = w#16#07 THEN Daten_Typ := 'DInt' ;  // Double-Integer
   ELSIF xDatenQuelle.DataTyp = w#16#08 THEN Daten_Typ := 'Real' ;  // Real
   ELSIF xDatenQuelle.DataTyp = w#16#09 THEN Daten_Typ := 'Date' ;  // Date
   ELSIF xDatenQuelle.DataTyp = w#16#0A THEN Daten_Typ := 'TOD' ;   // Time-of-Day
   ELSIF xDatenQuelle.DataTyp = w#16#0B THEN Daten_Typ := 'Time' ;  // Time
   ELSIF xDatenQuelle.DataTyp = w#16#0C THEN Daten_Typ := 'S5T' ;   // S5Time
   ELSIF xDatenQuelle.DataTyp = w#16#0E THEN Daten_Typ := 'DT' ;    // Date-and-Time
   ELSIF xDatenQuelle.DataTyp = w#16#13 THEN Daten_Typ := 'Str' ;   // String
   END_IF ;
   IF    yDatenQuelle.Speicherbereich[0] = w#16#81 THEN Daten_Mem := 'E' ;   //Eingänge
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#82 THEN Daten_Mem := 'A' ;   // Ausgänge
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#83 THEN Daten_Mem := 'M' ;   // Merker
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#84 THEN Daten_Mem := 'DB' ;  // DB
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#85 THEN Daten_Mem := 'DI' ;  // Instanz-DB
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#86 THEN Daten_Mem := 'L' ;   // Lokaldaten
   ELSIF yDatenQuelle.Speicherbereich[0] = w#16#87 THEN Daten_Mem := 'LV' ;  // vorherige Lokaldaten
   END_IF ;
   Daten_DB  := xDatenQuelle.DB_Nr ;  
   Daten_Len := WORD_TO_INT (xDatenQuelle.Anzahl) ;
   Daten_Ptr := xDatenQuelle.SpeicherPtr AND dw#16#00FF_FFFF ;
   Daten_1W  := DWORD_TO_INT(SHR (IN:=Daten_Ptr , n:=3)) ;
 
END_FUNCTION
Das Ding ist nur als Beispiel gedacht ... ich nehme es aber gern hin und wieder für Erklärungen heran.
Weiteres zum ANY-Pointer gibt es in der Rubrik FAQ.

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja das sehe ich ein. dann bist du herzlich eingeldane mir dabei zu helfen
:)!

Wie sieht es mit meinem Programm oben aus habe ich damit nur ein parameter oder einen pointer? das würde mir zuerst schon mal helfen
 
Du hättest 2 Eingangsparameter vom Typ ANY (Quell-Array 1 und 2). Des weiteren dann deine Ausgangsparameter, die den Status des Vergleichs ausgeben und ggf. was dir sonst noch so dazu einfällt ...

Die IN's könnten dann so aussehen :
Code:
Quelle_1 : p#DB1.DBX0.0 REAL 32
Quelle_2 : p#DB2.DBX0.0 REAL 32
 
Redest du jetzt von deinem beispiel oder von meinem?

Die Abfrage auf welchen datentyp finde ich gut das könnte ich nämlich sehr gut bei mir einbinden.

Aber wie du schon richtig gesagt hast würde ich das schon gerne selber schreiben mit dem pointer dann kann aihc es auch brauche nur noch den richtigen Anstoss.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was heißt denn hier kopfschütteln? habe in meiner Wohnung kein Internet und auch nicht die software!

Jetzt bin ich aber wieder dran und stehe immer noch mit den Pointer auf Kriegsfuss...

Kann mir vllt irgendjemand nur ein kleines beispiel schicken das ich mal sehe wie das genau aufgebaut ist die Funktion? Wäre nett.

Und @larry das mit den Quellen so als VAR_Input def geht nicht auch net mit Strichpunkt.
 
Zuletzt bearbeitet:
Hinweis "String"

Moin,

ich hab den FC jetzt nicht getestet, aber es könnte sein, dass Byte 0 und 1 der Strings noch die maximal-Länge und die tatsächliche Länge zugewiesen werden muss. Strings sind in S7 etwas umständlich zu händeln :rolleyes:

hth
 
ich verstehe zwar grad net was mir damit sagen willst aber ok :)

So ich habe jetzt mal etwas rumprobiert und aus nem anderem beispiel was eingefügt aber es geht nicht so wirklich.
hier mal der Code

Code:
FUNCTION FC10:INT
VAR_INPUT
    
    pVariablename: ANY;
END_VAR
VAR_TEMP
   pZeiger: ANY;
   MyZeiger AT pzeiger:STRUCT
   ID: BYTE;
   TYP: BYTE;
   NUM: WORD;
   DBN: WORD;
   PTR: DWORD;
END_STRUCT;
dwOffset:DWORD;
END_VAR
BEGIN
pZeiger:= pVariablename;
dwOffset := MyZeiger.PTR;

(*zeiger.ANY_Wert := 16#10;
zeiger.quelle_Typ := 16#02;
zeiger.quelle_Laenge :=16#04;
zeiger.quelle_DB_NR := 16#06;
zeiger.quelle_byte_zeiger :=16#84;*)
FC10 := WORD_TO_INT(DWORD_TO_WORD(dwOffset));   
    
END_FUNCTION
FUNCTION_BLOCK Fb50
VAR
    Wert : ARRAY [1..32] OF INT;
    isizeofWert: INT;
    ibyteOffset: INT;
END_VAR
VAR_TEMP
    ibyteoffsetFromStratOfDB:INT;
END_VAR
BEGIN
isizeofWert:= FC10(pArrayName:=Wert);
ibyteOffset:= FC11(pArrayName:= Wert ,pArrayElement:= Wert[13]);
ibyteoffsetFromStratOfDB:= FC12(pVariablename:= DB10.idata13);
END_FUNCTION_block

So mein problem ist jetzt das er beim FB rum motzt wegen den pArray Variablen und ich nicht weiß ob ich vorher schon was in den DB schreiben muss das er es erkennt.

mein Ob sieht bis jetzt so aus

Code:
 CALL  FC    10
       pVariablename:=DB10.DBW2
       RET_VAL      :=MW100
      CALL  FC    11
      CALL  FC    12

      BE
 
Zuletzt bearbeitet:
Zurück
Oben