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

Results 1 to 8 of 8

Thread: Wandeln Double/Float in S7- dword

  1. #1
    Join Date
    06.09.2008
    Posts
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo!

    Habe folgendes Problem:

    Ich muß von KBR ein Multimess über Profibus an eine S7-315-2 PN/DP
    einbinden! Ist auch weiter kein Problem nur die Ausgelesenen Daten liegen nur in Float und Double vor! Float müsste noch mit S7 real übereinstimmen indem ich die HW-Konfig bearbeite, doch was/wie mache ich mit double???

    Hier die Info's von KBR:

    float:
    Format korrespondiert mit dem IEEE 754 Standard
    Darstellung 4 Byte
    Genauigkeit 24 Bit (􀂾 repräsentieren >7 Dezimalstellen)
    Zusammensetzung 24 Bit-Mantisse; 8 Bit Exponent
    Mantisse 23 Bit (M) + 1 Bit (S)
    Das MSB der Mantisse beträgt immer 1 => wird nicht extra gespeichert!
    S = Vorzeichen der Mantisse: S = 1 􀂾 negative Zahl; S = 0 􀂾 positive Zahl
    Exponent 8 Bit (0-255); wird relativ zu 127 gespeichert, d.h. der aktuelle Wert destion der Zahl 127 vom
    abgespeicherten Wert.
    Akt. Exp. = gesp. Wert des Exp. – 127 => Zahlenbereich von 128 bis -127!
    Darstellbarer Zahlenbereich:
    1.18E-38 bis 3.40E+38
    Exponenten ergibt sich aus der Subtrak



    double:
    Format korrespondiert mit dem IEEE 754 Standard
    Darstellung 8 Byte
    Genauigkeit 52 Bit (􀂾 repräsentieren >15 Dezimalstellen)
    Zusammensetzung 52 Bit-Mantisse; 11 Bit Exponent
    Mantisse 52 Bit (M) + 1 Bit (S)
    Das MSB der Mantisse beträgt immer 1 => wird nicht extra gespeichert!
    S = Vorzeichen der Mantisse: S = 1 􀂾 negative Zahl; S = 0 􀂾 positive Zahl
    Exponent 11 Bit (0-2047);
    wird relativ zu 1023 gespeichert, d.h. der aktuelle Wert des Exponenten
    ergibt sich aus der Subtraktion der Zahl 1023 vom abgespeicherten Wert.
    Darstellbarer Zahlenbereich:
    2.23E-308 bis 1.80E+308}


    Kann mir dabei jemand helfen?
    Kann leider noch nichts testen da die Anlage erst kurz vor Inbetriebnahme kommt! und dann muß ich mit der Programmierung schon fertig sein!
    Reply With Quote Reply With Quote Wandeln Double/Float in S7- dword  

  2. #2
    Join Date
    27.05.2004
    Location
    Thüringen/Berlin
    Posts
    13,806
    Danke
    746
    Erhielt 3,127 Danke für 2,231 Beiträge

    Default

    Ich hab das ja noch nie machen müssen.
    Zuerst sei dies hier empfohlen: http://de.wikipedia.org/wiki/IEEE_754
    Die S7 (300-er) kann ja nicht mit Double rechnen. Also würde ich versuchen, die nötigen Kennziffern

    Die Darstellung einer Gleitkommazahl

    besteht aus:
    Vorzeichen s (fast ausnahmslos 1 Bit)
    Basis b (bei normalisierten Gleitkommazahlen nach IEEE 754 ist b = 2)
    Exponent e (r Bits), nicht zu verwechseln mit dem „biased exponent“ bzw. der Charakteristik
    Mantisse m (p Bits), manchmal als Signifikant bezeichnet
    zu extrahieren, dann entsprechend zu runden und ins Float-Format umzurechnen. Wenn denn die Double in die Float von der Größe her hineinpaßt. Denke aber, hauptsächlich wegen der höheren Genaugkeit wurde die Double verwendet.
    Last edited by Ralle; 05.12.2008 at 23:58.
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  3. #3
    the.insider is offline Neuer Benutzer
    Themenstarter
    Join Date
    06.09.2008
    Posts
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Default

    Die Theorie ist mir soweit auch klar, nur wie setzt man dies Programmierungstechnisch(AWL/FUP/KOP) um???

  4. #4
    Join Date
    01.11.2007
    Posts
    1,332
    Danke
    99
    Erhielt 441 Danke für 398 Beiträge

    Default

    Ist das denn wirklich nötig ? Hier ging es schon mal um die Anbindung von KBR an S7, insbesondere der Beitrag #20 dürfte interessant sein (Danke an msb dafür).
    Wenn ich die GSD-Datei richtig deute, dann gibt es zu jedem double-modul ein korrespondierendes float-modul.

    Grüße von HaDi

  5. Folgender Benutzer sagt Danke zu HaDi für den nützlichen Beitrag:

    the.insider (06.12.2008)

  6. #5
    the.insider is offline Neuer Benutzer
    Themenstarter
    Join Date
    06.09.2008
    Posts
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Default

    Habt vielen Dank!

    Hab ich völlig übersehen, dass es den benötigten Wert auch noch als float gibt und das reicht mir natürlich!!!

  7. #6
    Join Date
    29.03.2004
    Posts
    7,271
    Danke
    165
    Erhielt 2,182 Danke für 1,563 Beiträge

    Default

    Ich habe mal eine Konvertierungsfunktion für IEEE 754 64-Bit double nach 32-Bit Real geschrieben.
    Es werden allerdings nur normalisierte Werte (Normalfall) konvertiert. Kommt beim Double ein denormalisierter Wert rein wird Null ausgegeben.

    Wenn die Sonderfälle nicht beachtet werden müssten könnte man den Baustein wesentlich verkürzen.

    Hier mal der SCL-Code:
    Code:
    (* DOUBLE_TO_REAL
     * Konvertiert eine IEEE754 64-Bit Gleitpunktzahl in eine IEEE 32-Bit Gleitpunktzahl
     * Liegt der Double-Wert außerhalb des Wertebereiches der 32-Bit Zahl, so
     * wird der entsprechende Max/Min-Wert sowie ein Wert != 0 an Error ausgegeben.
     * 
     * Denormalisierte Werte werden nicht! umgerechnet, sondern es wird 0.0 ausgegeben!
     *
     * Darstellung 64-Bit IEEE754:
     * -------------------------------------------------------------------------------------------
     * S |         Exponent               |            Mantisse
     * -------------------------------------------------------------------------------------------
     * 63|62 61 60 59 58 57 56^55 54 53 52|51 50 49 48^47 46 45 44 43 42 41
     *         BYTE7          ^         BYTE6         ^
     *) 
    
    TYPE DOUBLE :
    STRUCT
        byte0 : BYTE;
        byte1 : BYTE;
        byte2 : BYTE;
        byte3 : BYTE;
        byte4 : BYTE;
        byte5 : BYTE;
        byte6 : BYTE;
        byte7 : BYTE;
    END_STRUCT
    END_TYPE
     
    FUNCTION DOUBLE_TO_REAL : REAL
    TITLE = 'DOUBLE_TO_REAL'
    
    VERSION : '0.1'
    AUTHOR  : TWI
    NAME    : DBL_REAL
    FAMILY  : CONVERT
    
    CONST 
        FLT_MAX := REAL#3.402823e+38;
        FLT_MIN := REAL#1.175495e-38;     
        S_INF := 16#1;
        S_NAN := 16#2;
        S_MAX := 16#3;
        S_MIN := 16#4;
        S_DEN := 16#5;
    END_CONST
    
    VAR_INPUT
        dbl         : DOUBLE;   // (* Byte-Array mit 64-Bit IEEE754 Zahl *)
    END_VAR
    
    VAR_OUTPUT             
        wStatus     : WORD;     // (* Statusausgabe *)
    END_VAR
    
    VAR_TEMP
        xMant_Null  : BOOL;         (* Mantisse des Double-Wertes ist Null *)
        iExponent   : INT;          (* Exponent Double *)
        bFlt_exp    : BYTE;         (* Exponent Real *)
        rFlt_val    : REAL;         (* Real-Wert *)
        dw_AT_rFlt_val AT rFlt_val: DWORD; (* Hilfssicht auf Real-Wert *) 
    END_VAR
    (******************************************************************************)
        wStatus := 16#0; 
        (* Exponent bestimmen (11 Bit) Bits 52-63; Vorzeichenbit ausmaskieren und Mantissenbits rausschieben*)
        iExponent := WORD_TO_INT(SHL(IN := BYTE_TO_WORD(dbl.byte7 AND 16#7F), N := 4) OR 
                                 SHR(IN := BYTE_TO_WORD(dbl.byte6), N := 4));
        
        (* Für Sonderfälle: Prüfen ob Mantisse Null ist *)    
        xMant_Null := ((dbl.byte6 AND 16#0F) OR dbl.byte5 OR dbl.byte4 OR dbl.byte3 OR dbl.byte2 OR dbl.byte1 OR dbl.byte0) = 0;    
        
        (* Sonderfälle abfragen *)
        IF (iExponent = 0) THEN       
            IF (xMant_Null = TRUE) THEN        (* Null *)
                DOUBLE_TO_REAL := 0.0;
                RETURN;
            ELSE                                (* denormalisierter Wert, wird hier nicht ausgewertet sondern 0 ausgegeben! *)
                wStatus := S_DEN;
                bFlt_exp := 0;
                DOUBLE_TO_REAL := 0.0;
                RETURN;
            END_IF;
        ELSIF (iExponent = 2047) THEN 
            IF (xMant_Null = TRUE) THEN         (* Infinity *)
                wStatus := S_INF;
                bFlt_exp := 16#FF;
            ELSE                                (* NaN, Not a Number *)
                wStatus := S_NAN;
                bFlt_exp := 16#FF;
            END_IF;    
        ELSE    
            iExponent := iExponent - 1023;       (* Bias des Exponenten wieder abziehen *)                                                                                                           
            IF (iExponent < -126) THEN           (* Bereich unterschritten *)
                wStatus := S_MIN;
                DOUBLE_TO_REAL := FLT_MIN;
                RETURN;
            ELSIF (iExponent > 127) THEN         (* Bereich überschritten *)
                wStatus := S_MAX;
                DOUBLE_TO_REAL := FLT_MAX;
                RETURN;       
            END_IF;
            
            (* Neuen Exponenten mit Bias bestimmen *)
            bFlt_exp := INT_TO_BYTE(iExponent + 127);
        END_IF;   
        
        (* Vorzeichenbit *)
        dw_AT_rFlt_val := SHL(IN := BYTE_TO_DWORD(dbl.byte7 AND 16#80), N := 24);
        (* Exponent 8 Bit *)
        dw_AT_rFlt_val := dw_AT_rFlt_val OR SHL(IN := BYTE_TO_DWORD(bFlt_exp), N := 23);
        (* Mantisse 23 Bit *)
        dw_AT_rFlt_val := dw_AT_rFlt_val OR SHL(IN := BYTE_TO_DWORD(dbl.byte6 AND 16#0F), N := 19)
                                         OR SHL(IN := BYTE_TO_DWORD(dbl.byte5), N := 11)
                                         OR SHL(IN := BYTE_TO_DWORD(dbl.byte4), N := 3)
                                         OR SHR(IN := BYTE_TO_DWORD(dbl.byte3), N := 5);
        
        DOUBLE_TO_REAL := rFlt_val;   
    END_FUNCTION
    Ich finde ja dass das Bitgeschubse in SCL etwas unkomfortabel ist, in AWL wäre das wesentlich einfacher.
    Oder kennt jemand eine Möglichkeit das einfacher zu schreiben? Evtl. mit einer zusätzlichen AT-Sicht?

    Mich stören vor allem die ganzen x_TO_y, aber sonst meckert der Compiler...

  8. Folgender Benutzer sagt Danke zu Thomas_v2.1 für den nützlichen Beitrag:

    uz71 (11.09.2009)

  9. #7
    Join Date
    14.10.2009
    Posts
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Default

    Hallo zusammen,
    ich hole den alten Thread mal wieder vor.

    Ich möchte den Baustein von Thomas_v2.1 benutzen, bekomme aber den UDT nicht vernünftig als Parameter übergeben. Es gibt immer einen Fehler.

    Meine bisherige Vorgehensweise:
    Quelle erzeugt.
    Baustein (FC100) aus Quelle erzeugt.
    UDT100 erzeugt (Symbol: "DOUBLE").
    DB100 erzeugt, in dem der UDT100 benutzt wird (Byte 0-7).

    Wie genau bekomme ich den UDT im DB jetzt als Parameter an den Baustein übergeben? Gibt es da einen Trick?

    Ich habe es so probiert: P#DB100.DBX0.0 Byte 8
    oder so: DB100.DOUBLE

    Funktioniert beides nicht.

    Vielleicht kann mir ja jemand helfen.

    Vielen Dank.

  10. #8
    Join Date
    22.03.2007
    Location
    Detmold (im Lipperland)
    Posts
    12,402
    Danke
    422
    Erhielt 2,536 Danke für 2,108 Beiträge

    Default


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,
    wenn dein Datenbaustein einen symbolischen Namen hat dann könnte es z.B. so aussehen :
    Code:
    dbl := "mein_symbolischer_DB_Name".mein_sysmbolischer_UDT_Name
    Gruß
    Larry

Similar Threads

  1. Vier Modbus Register nach double Float
    By knuppel in forum Programmierstrategien
    Replies: 8
    Last Post: 20.02.2015, 22:01
  2. Von VBS Double zu SQL Float
    By Kreak_Blutklinge in forum Hochsprachen - OPC
    Replies: 1
    Last Post: 05.07.2013, 14:27
  3. Float in Real wandeln - SCL
    By Gerri in forum Simatic
    Replies: 6
    Last Post: 23.07.2010, 15:29
  4. Float Wert to Dword und dann zu DINT geht das?
    By mcmatthew in forum Simatic
    Replies: 5
    Last Post: 11.12.2009, 16:50
  5. Sentron : Double nach S7-Real wandeln
    By Kieler in forum Simatic
    Replies: 9
    Last Post: 11.09.2009, 21:51

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •