Die 4 LSBs sind je 1/16°C wert. Das ist bereits der Nachkommaanteil,
aber binär. Blöderweise lässt sich der nur krumm als
Dezimal-Nachkommateil abbilden.
Wenn du die Division am Ende vermeiden willst, greife dir doch die 4
LSBs ab und stecke die in eine Lookuptabelle.
Für eine Anzeige in Dezimal-Vorkomma als Text muss der Vorkommaanteil
übrigens in der printf oder sprintf (oder sonst wie) sowieso umgerechnet
werden.
Vielleicht kommst du mit fraktionalen Zahlen hin, wo dann das Ergebnis
ein Integer in 1/100 °C-Schritten ist.
mfg mf
Ein Profi nimmt die Lösung, die seine Anforderungen am besten erfüllt.
Kommt dein Rechner mit seiner Rechenleistung an seine Grenzen, dann ist
die Lösung 1. die richtige. Brauchst du höhere Genauigkeit und dir
stehen mehr freie Rechenkapazitäten zur Verfügung, dann die Lösung 2.
Was Float Zahlen betrifft: Ist dein Rechner ein 8Bit AVR und hat so um
die 500 Takte frei zwischen zwei Aufgaben die er berechnet, dann geht
auch float.
Gruß,
Simon schrieb:> Gibt es hier keine andere Lösung (kein float)?
Was genau ist denn eigentlich das Problem?
Du erhältst doch eine Ganzzahl zurück, die linear aufsteigende
Bitwertigkeiten hat. Ein Float macht doch bei dieser Anwendung überhaupt
keinen Sinn.
Oder übersiehst du gerade das naheliegende?
// schieben um 6 um den Nachkommaanteil wegzuschneiden und 1/100 degC zu bekommen
18
Temp1_100>>=6u;
Wer einen Fehler findet, darf ihn gern verbessern ^^
mfg mf
PS. Sehe gerade, dass die Rechnung auch in 16bit rein passen würde, wenn
man nur positive Temperaturen hat. Der Achim muss sich also warm
anziehen ;)
Simon schrieb:> Hi,>> ich habe einen DS18B20 1-Wire Temperatursensor.> und würde hier gerne die Temperatur Umrechnen.> // Auslesen> lsb = onewire_Read();> msb = onewire_Read();> temperature = (msb<<8)+lsb;> // Umrechnen> // 1. Möglichkeit, leider ohne Nachkommastellen> temperature = (temperature >> 4);> //2. Möglichkeit> // (Gibt nen Integerwert zurück und die zwei Nachkommastellen sind> dabei)> temperature *= 625; //(0.0625 C je Bit);> temperature /= 100;>> Gibt es hier keine andere Lösung (kein float)?>> Vielen Dank
Falls du den Wert in Berechnungen benutzt oder nur irgendwo anders
hinüberträgst, kannst du die Berechnung bzw das Übertragungsformat in
Festkomma gestalten, so wie es Achim angedeutet hat. Konstanten kann man
zB ja so anpassen, dass die Zahlengleichung mit 1/16°C umgehen kann. Ich
würde mir da noch ein paar Typedefs als Hilfestellung anlegen, sowas wie
[c]typedef uint32_t uq26_6;[\c]
Wenn du es nur anzeigen möchtest, ist eine Umrechung auf Dezimal mit
zwei Nachkommastellen, wie sie von Achim optimiert wurde, doch
eigentlich optimal, oder?
Warum muss die Temperatur überhaupt umgerechnet werden?
Und wenn ja, in was?
Wenn die Temperatur in eine PID rein muss, um damit etwas zu regeln,
dann kannst du doch auch dort in 16tel Grad rechnen.
Und für eine Ausgabe auf ein Display reicht ein sekündliches Update. Da
kann man auch Floats nehmen.
Also, warum soll auf was umgerechnet werden?
Achja, beim meinen LM73 nehme ich nur die 1/4 Grad, und die schwanken
schon ordentlich. Die Genauigkeit mit 16tel Grad würde ich ignorieren.
So genau sind die Sensoren nicht.
PittyJ schrieb:> Die Genauigkeit mit 16tel Grad würde ich ignorieren. So genau sind die> Sensoren nicht.
Du schmeißt Auflösung und Genauigkeit durcheinander. Auflösung ist
manchmal wichtiger als Genauigkeit - hängt von der Anwendung ab.
Wolfgang schrieb:> Du schmeißt Auflösung und Genauigkeit durcheinander. Auflösung ist> manchmal wichtiger als Genauigkeit - hängt von der Anwendung ab.
Wobei die relative Genauigkeit sicher höher als die absolute ist. Eine
hohe Auflösung kann hierbei von Vorteil sein. Ein Regler benötigt
beispielsweise keine Absoluttemperatur sonder eher
Temperaturdifferenzen.
Danke dir eprofi...
wenn ich das so sehe... Puh...
Ich werde mal die ganzen Lösungen ausprobieren und schauen was am Ende
am schnellsten funzt.
Ob das natürlich wirklich Sinn macht das zu überoptimieren ist fraglich.
Für was die Temperatur gebraucht wird? sie wird ansich nur an eine
Datenbank weiter geschickt. Von daher wäre auch eine Zahl ohne jegliche
Nachkommastelle akzeptabel.
Simon schrieb:> temperature *= 625; //(0.0625 C je Bit);> temperature /= 100;
Na dann warte mal, bis Winter ist. Dann liefert Deine Rechnung Mumpitz.
Der Sensor braucht 750ms je Messung. In der Zeit hat jeder 8Bitter
vorzeichenrichtig das bischen float gerechnet und dreht den Rest der
Zeit Däumchen.
Er sucht einen "edlen Weg der Umrechnung"
Ich dachte der "Edler" sei abhanden gekommen. :) Hab den Eröffnungspost
auch gewissenhaft gelesen und für mich "Edler" mit "Integer" im Zuge der
Autokorrektur assoziiert.
Sowas aber auch...
(War ich wieder der einzige?)
Was heißt hier "puh"?
Das ist schon fast Assembler-Niveau. Jede Zeile dürfte 2-5 Befehle
ergeben, d.h. 100 Befehle. Schneller, kürzer und edler geht kaum. :-)
Und bedenke, Du brauchst kein printf etc.
Das ganze Programm sind vielleicht 500 Bytes.