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

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: UDT Länge mit SCL auslesen

  1. #1
    Registriert seit
    05.03.2007
    Ort
    Lindlar
    Beiträge
    112
    Danke
    19
    Erhielt 20 Danke für 18 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo zusammen,
    ich suche eine Möglichkeit per SCL die Länge eines UDT's auszulesen. Habe hier schon reichlich Threads zu diesem Thema abgeklappert, jedoch noch keine Lösung gefunden, da meistens nicht die Länge des UDT's ausgelesen werden soll sondern der Struktur im DB wo der UDT verwendet wird.

    Beispiel:
    UDT1:
    Code:
    a   WORD    W#16#0
    b   WORD    W#16#0
    Also ist mein UDT 4 Byte lang

    DB:
    Code:
    x    ARRAY[1..100]
          UDT1
    Der DB hingegen ist nun 400 Byte lang

    An meinem FC binde ich einen ANY-Pointer al VAR_INPUT an über den ich ja die DB Nummer, die Länge der Struktur etc. alles verarbeiten kann. Aber wie funktioniert es, das ich nur die Länge des UDT's erhalte?

    Viele Grüße
    Matthias
    IF Time < '09:00:00' THEN
    SELECT finger from right hand where ID=3
    END IF
    Zitieren Zitieren UDT Länge mit SCL auslesen  

  2. #2
    Registriert seit
    15.01.2005
    Ort
    In der Mitte zwischen Bayreuth/Weiden
    Beiträge
    6.732
    Danke
    314
    Erhielt 1.520 Danke für 1.282 Beiträge

    Standard

    Also meiner Meinung nach:
    Überhaupt nicht.

    Der UDT ist in der SPS in keinster Weise vorhanden, und somit auch nicht irgendwie dynamisch auswertbar.
    Ein UDT definiert ja lediglich eine Reihe von Daten/Datentypen im DB, oder wo auch immer.

    Mfg
    Manuel
    Warum denn einfach, wenn man auch Siemens einsetzen kann!

    Wer die grundlegenden Freiheiten aufgibt, um vorübergehend ein wenig Sicherheit zu bekommen, verdient weder Freiheit noch Sicherheit (B. Franklin).

  3. #3
    Panzerknacker ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.03.2007
    Ort
    Lindlar
    Beiträge
    112
    Danke
    19
    Erhielt 20 Danke für 18 Beiträge

    Standard

    Da hast du natürlich recht das er in der SPS nicht vorhanden ist,
    allerdings kann ich ihn in SCL ja auch als eine Variable anlegen. Daher dachte ich eigentlich das es wohl Mittel und Wege geben müsste die Länge von dieser
    "UDT Variable" ermitteln können.

    Gruß
    Matthias
    IF Time < '09:00:00' THEN
    SELECT finger from right hand where ID=3
    END IF

  4. #4
    Registriert seit
    05.06.2006
    Ort
    PLZ 97xxx
    Beiträge
    274
    Danke
    31
    Erhielt 44 Danke für 36 Beiträge

    Standard

    blöde Frage:
    Warum willst du das wissen bzw. auswerten?
    Vielleicht gibts nen eleganteren Weg

    Zitat Zitat von Panzerknacker Beitrag anzeigen
    Da hast du natürlich recht das er in der SPS nicht vorhanden ist,
    allerdings kann ich ihn in SCL ja auch als eine Variable anlegen. Daher dachte ich eigentlich das es wohl Mittel und Wege geben müsste die Länge von dieser
    "UDT Variable" ermitteln können.

    Gruß
    Matthias

  5. #5
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.718
    Danke
    398
    Erhielt 2.400 Danke für 2.000 Beiträge

    Standard

    Nein ... geht nicht ...
    SCL kann nur mit Variablen oder Typen arbeiten, die es schon kennt. Die Länge eines ihm unbekannten UDT's oder die Struktur eines ihm unbekannten DB's kann es nicht erfassen.

    Grundsätzlich kannst du die Länge eines UDT's oder ähnlich aber erfassen/errechnen in dem du Differenz des Anfangs-Pointers der Struktur zu dem Pointer auf die danach folgende Variable/Struktur bildest ...

    Gruß
    LL

  6. #6
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.685 Danke für 1.225 Beiträge

    Standard

    Zitat Zitat von Larry Laffer Beitrag anzeigen
    Nein ... geht nicht ...
    Doch, geht doch!

    Dass es keine sizeof Funktion gibt ist der tollen Pascal Sprache geschuldet.

    Ich habe dafür einen sizeof AWL-Baustein geschrieben, müsste sich aber auch in mittels der AT-Sicht in SCL schreiben lassen:

    Code:
    FUNCTION "sizeof" : INT
    TITLE =Gibt die Länge in Bytes eines ANY-Pointers zurück
    //nur für BYTE, CHAR, WORD, INT, DWORD, DINT, REAL
    //Return: 0 wenn OK, -1 bei Fehler
    VERSION : 0.1
    
    
    VAR_INPUT
      pUDT : ANY ;    //nur für BYTE, CHAR, WORD, INT, DWORD, DINT, REAL
    END_VAR
    VAR_OUTPUT
      LEN : INT ;    
    END_VAR
    VAR_TEMP
      SyntaxID : BYTE ;    
      DataType : BYTE ;    
      DataCount : INT ;    
      DB_Number : WORD ;    
      BytePointer : WORD ;    
    END_VAR
    BEGIN
    NETWORK
    TITLE =
    //
    //
          L     P##pUDT; 
          LAR1  ; 
          L     B [AR1,P#0.0]; 
          T     #SyntaxID; 
          L     B [AR1,P#1.0]; 
          T     #DataType; 
          L     W [AR1,P#2.0]; 
          T     #DataCount; 
    // Länge soll in Bytes ausgegeben werden
          L     #DataType; 
          SPL   err; 
          SPA   err; // 0= NIL
          SPA   err; // 1= BOOL
          SPA   byte; // 2= BYTE (Bytes 8 Bits)
          SPA   byte; // 3= CHAR (Zeichen 8 Bits)
          SPA   word; // 4= WORD (Wörter 16 Bits)
          SPA   word; // 5= INT (Ganzzahlen 16 Bits)
          SPA   dwor; // 6= DWORD (Wörter 32 Bits)
          SPA   dwor; // 7 = DINT Ganzzahlen (32 Bits)
          SPA   dwor; // 8= REAL (Gleitpunktzahlen 32 Bits)
    err:  L     0; 
          T     #LEN; 
          L     -1; 
          T     #RET_VAL; 
          BEA   ; 
    // BYTE
    byte: L     #DataCount; 
          T     #LEN; 
          L     0; 
          T     #RET_VAL; 
          BEA   ; 
    // WORD
    word: L     #DataCount; 
          L     2; 
          *I    ; 
          T     #LEN; 
          L     0; 
          T     #RET_VAL; 
          BEA   ; 
    // DWORD
    dwor: L     #DataCount; 
          L     4; 
          *I    ; 
          T     #LEN; 
          L     0; 
          T     #RET_VAL; 
          BEA   ; 
    END_FUNCTION
    Aufzurufen dann in SCL z.B. so:
    Code:
    TYPE UDT1111
        STRUCT
            b0 : BYTE;
            b1 : BYTE;
            b2 : BYTE;
        END_STRUCT
    END_TYPE
    
    TYPE UDT1112
        STRUCT
            w0 : WORD;
            w1 : WORD;
            w2 : WORD;
        END_STRUCT
    END_TYPE
    
    FUNCTION_BLOCK FB1100
    
    VAR_TEMP
        len1 : INT;
        len2 : INT;
        ret : INT;
    END_VAR
    VAR
        dat3byte : UDT1111;
        dat3word : UDT1112;
    END_VAR
     
    ret := sizeof(pUDT :=  dat3byte
                 ,LEN :=  len1
                 ); 
    ret := sizeof(pUDT :=  dat3word
                 ,LEN :=  len2
                 ); 
    END_FUNCTION_BLOCK

  7. #7
    Registriert seit
    29.03.2004
    Beiträge
    5.735
    Danke
    143
    Erhielt 1.685 Danke für 1.225 Beiträge

    Standard

    Zu beachten ist dass bei Strukturen, UDTs und Arrays Padding Bytes eingefügt werden.
    Die 3 Byte Struktur oben ist als in Wirklichkeit 4 Byte lang.

  8. #8
    Panzerknacker ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.03.2007
    Ort
    Lindlar
    Beiträge
    112
    Danke
    19
    Erhielt 20 Danke für 18 Beiträge

    Standard

    Erstmal vielen Dank für eure Beiträge zu dem Thema.

    @Thomas_v2.1 Ich denke nicht das das funktionieren würde. Denn wenn ich den ANY auf den DB anlege wo ich den UDT als Array verwende, dann bekomme ich vom ANY ja auch wieder die Länge des gesamten Arrays und nicht des einzelnen UDT's

    Besispiel:
    Code:
    TYPE "UDTabc"
    VERSION : 0.1
    
    
      STRUCT     
       a : INT ;    
       b : INT ;    
      END_STRUCT ;    
    END_TYPE
    
    DATA_BLOCK DB 1
    VERSION : 0.1
    
    
      STRUCT     
       x : ARRAY  [1 .. 10 ] OF "UDTabc";    
      END_STRUCT ;    
    BEGIN
       x[1].a := 0; 
       x[1].b := 0; 
       x[2].a := 0; 
       x[2].b := 0; 
       x[3].a := 0; 
       x[3].b := 0; 
       x[4].a := 0; 
       x[4].b := 0; 
       x[5].a := 0; 
       x[5].b := 0; 
       x[6].a := 0; 
       x[6].b := 0; 
       x[7].a := 0; 
       x[7].b := 0; 
       x[8].a := 0; 
       x[8].b := 0; 
       x[9].a := 0; 
       x[9].b := 0; 
       x[10].a := 0; 
       x[10].b := 0; 
    END_DATA_BLOCK
    Wenn ich jetzt das array an einen FC anbinden will würde ich ja den P#DB1.DBX0.0 BYTE 40 anbinden (symbolisch "DB1".x)

    Da ich aber gerne von einem Array-Element in das andere immer die komplette Struktur umkopieren will muss ich ja die Länge des UDT's kennen.
    Sprich ich möchte z.B. im FC gerne folgendes kopieren:
    x[9].a nach x[10].a
    x[9].b nach x[10].b

    Soweit ja keine Problem, aber wenn ich jetzt den UDT erweitern möchte um die Variable .c, dann habe ich das Problem das im DB sich alles verschiebt weil der UDT sich ja geändert hat. Denn dann möchte ich kopieren:
    x[9].a nach x[10].a
    x[9].b nach x[10].b
    x[9].c nach x[10].c

    So wie ich das im Moment sehe fallen mir 3 Ansätze an:
    1. Einen VAR_INPUT (z.B. UDTLen : INT; ) erstellen wo ich manuell die UDT Länge angeben muß
    2. Im DB vor den UDT eine Kopfvariable zu setzen wo die UDT Länge schon drin steht.
    3. Einen weiteren VAR_INPUT als ANY erstellen, dann im DB vor dem array einen einzelnen UDT anlegen (natürlich der gleiche der auch für das array genutzt wird) und mit diesem weiteren ANY auf den einzelnen UDT zu schauen und daher die Länge zu beziehen

    Was denkt ihr was wohl die beste Lösung ist?

    Gruß
    Matthias
    IF Time < '09:00:00' THEN
    SELECT finger from right hand where ID=3
    END IF

  9. #9
    Registriert seit
    05.06.2006
    Ort
    PLZ 97xxx
    Beiträge
    274
    Danke
    31
    Erhielt 44 Danke für 36 Beiträge

    Standard

    Das geht mit SCL viel einfacher.

    X[10] := X[9];

    oder auch in Verbindung einer Schleife oder ähnliches indirekt adressiert

    X[n+1] := X[N];

    Der Compiler macht Dir daraus einen SFC20-Aufruf und du brauchst dich
    um nix weiter zu kümmern.

    Wenn Du das UDT dann später erweiterst, einfach die Quelle neu übersetzen => das wars

  10. #10
    Panzerknacker ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.03.2007
    Ort
    Lindlar
    Beiträge
    112
    Danke
    19
    Erhielt 20 Danke für 18 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Das mache ich ja auch mit SCL.
    Die ganze Geschichte ist auch um einiges komplexer, das war jetzt nur ein einfaches Beispiel.

    Der Punkt ist halt das der Kunde es erweitern können soll OHNE in der Quelle zu wühlen
    IF Time < '09:00:00' THEN
    SELECT finger from right hand where ID=3
    END IF

Ähnliche Themen

  1. Länge/Größe eines Bausteins auslesen?
    Von Oele im Forum Simatic
    Antworten: 16
    Letzter Beitrag: 13.08.2011, 15:29
  2. LibNoDave DB Länge
    Von The-Cook im Forum PC- und Netzwerktechnik
    Antworten: 6
    Letzter Beitrag: 03.06.2009, 15:11
  3. Länge eines String mit der LEN-Funktion auslesen
    Von baggerandy im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 10.04.2009, 16:13
  4. DB-Länge und Größe in SCL
    Von Pikador im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 09.03.2008, 15:31
  5. Maximale DB Länge bei S7 31x 2DP
    Von Markus im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 16.04.2004, 20:19

Lesezeichen

Berechtigungen

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