TIA 2 Byte Gleitkommawert erzeugen

SPS-Andy

Level-2
Beiträge
60
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe ein Problem und komme nicht weiter.
Ich will von einer S7 1215 über ein Gateway (PN<->KNX) ein 2 byte Gleitkomma Wert senden (Temperatur).

auf der KNX Seite ist der wert folgendermaßen aufgebaut:

z.B. (Quelle: https://knx-user-forum.de/forum/%C3%...bei-mdt-sensor)
0CBA = 0000 1100 1011 1010 binär

Vorzeichen 0 => positive Zahl
Exponent 0001 = 1
Mantisse 100 1011 1010 = 1210 dezimal

1210 * 2^1 = 2420
geteilt durch 100 wegen 0.01°C Auflösung => 24.2 °C

oder
191D ist binär 0001 1001 0001 1101. Mantisse ist also 285, Exponent ist 3 und 285*8 ist 2280

wie man vom HEX Wert auf ein INT kommt ist kein Problem, aber wie kann ich aus einem INT (z.B. 2420 für 24,2°C) solch einen Wert erzeugen??
Gibt es hier ein Baustein der das übernimmt?

Vielen Dank schonmal im Voraus
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Format heißt Float16. Auf Stackoverflow gibts einen Thread in dem Code gezeigt wird der Float32 in Float16 wandelt. Meine Hochsprachenkenntnisse sind mager... ich weiß nicht ob man das auf SCL umsetzen kann.
https://stackoverflow.com/questions/3026441/float32-to-float16/3026505

Der Code in dem Beitrag 7 lässt sich problemlos in SCL umsetzen.
Ein wenig schieben und ein wenig maskieren ... Ich hab aber mal den Verdacht, dass evtl. die Byteorder dazwischen funkt
 
Der Code in dem Beitrag 7 lässt sich problemlos in SCL umsetzen.
Ein wenig schieben und ein wenig maskieren ... Ich hab aber mal den Verdacht, dass evtl. die Byteorder dazwischen funkt
SCL dürfte nicht das Problem sein, wie Du sagst, Dieter.
Aber die ByteOrder eigentlich auch nicht, da die Umwandlung "im Akku" erfolgt. Der "IndianerTyp" sollte ja wohl innerhalb eines Systems passen.
Wenn KNX allerdings einen anderen Typ voraussetzt, müssten die Bytes noch getauscht werden, aber das sehe ich nicht als Bestandteil dieser UmwandlungsFunktion.

Nach oberflächlicher Betrachtung des Codes und Lesens der "Limitations of the implementation" u.s.w. wäre der Ansatz m.E. recht "hauruckmässig".
Vielleicht ist auch eine Umwandlung von DINT in REAL16 (statt REAL32 in REAL16) für diese Anwendung zweckmässiger (wenn auch aufwändiger), wenn die Einheit in der DINT-Variablen ohnehin nicht °C, sondern d°C oder c°C oder m°C sein sollte ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe ein wenig weiter recachiert und rumexpirimentiert und bin vorerst auf diese lösung gekommen:

Code:
IF #int >= 0 THEN
    #"erg. exp" := #int / 2047;
    
    CASE #"erg. exp" OF
        0:
            #"temp 2byte real" := #int;
            
        1:
            #"temp int" := #int / 2;
            #"temp 2byte real" := (#"temp int" + 2048);
            
        2:
            #"temp int" := #int / 4;
            #"temp 2byte real" := (#"temp int" + 4096);
            
        3:
            #"temp int" := #int / 8;
            #"temp 2byte real" := (#"temp int" + 6144);
            
        4:
            #"temp int" := #int / 16;
            #"temp 2byte real" := (#"temp int" + 8192);
            
        ELSE
            #error := true;
            
    END_CASE;
    
    #"2Byte REAL" := #"temp 2byte real";
    
ELSE
    #"temp int bereinigt" := #int * -1;
    #"erg. exp" := #"temp int bereinigt" / 2047;
    
    CASE #"erg. exp" OF
        0:
            #"temp 2byte real" := #int;
            
        1:
            #"temp int" := #int / 2;
            #"temp 2byte real" := (#"temp int" + 2048);
            
        2:
            #"temp int" := #int / 4;
            #"temp 2byte real" := (#"temp int" + 4096);
            
        3:
            #"temp int" := #int / 8;
            #"temp 2byte real" := (#"temp int" + 6144);
            
        4:
            #"temp int" := #int / 16;
            #"temp 2byte real" := (#"temp int" + 8192);
            
        ELSE
            #error := true;
            
    END_CASE;
    
    #"2Byte REAL" := #"temp 2byte real" + (-30720);
    
END_IF;

irgendwie einfach aber es funktioniert so weit (Temperaturbereich -50 bis +70)
 
Zurück
Oben