Guten Tag,
ich würde mir gerne einen Nachkommawert berechnen. Ich denke ich habe
eine Lösung, diese ist aber ziemlich aufwendig. Vielleich kann mir
jemand bei einer eleganteren Lösung behilflich sein.
Es geht um folgendes. Ich lese über den I2C Bus die Temperatur mittels
ds1631 in eine 2 Byte int Variable aus. Eingestellt habe ich eine 12 Bit
Auflösung, also eine 0.0625°C. Der Nachkommawert befindet sich in den
vier höchstwertigen Bits des Lowbytes. Diese Maskiere ich und weise dann
den entsprechenden Wert zu. Ich muss bzw. will ohne float Variable
auskommen.
"The DS1631 and DS1631A thermometer accuracy is ±0.5°C from 0°C to
+70°C"
Da macht eine Darstellung mit 4 Nachkommastellen wohl kaum Sinn...
Es reicht wohl aus Bit 8 zu testen, wenn 1 -> ".5" anhängen, wenn 0 ->
".0" anhängen.
Nachtrag:
Negative Zahlen müssen dann eh nochmal gesondert behandelt werden.
Am besten erstmal Vorzeichen ausgeben (in Abhängigkeit von Bit 16), und
negative Temperaturen für die weitere Ausgabe in positive Zahl
umwandeln.
Dann stimmt auch die Nachkommastelle.
Hi
Negative Zahlen werden glaub per 2er Komplement gebildet (also
entweder $FF-x oder $00-x .. Eines davon passt).
(wenn's halbwegs zum DS18B20 kompatibel ist)
Dann hast Du den Zahlenwert wieder als positive Zahl, musst Dir halt
merken, daß da nen Minus vor gehört (oder sogar bei der Umwandlung schon
ausgeben).
Die Nachkommastellen nerechne ich mit den vollen 4 Bit (also 12bitig)
und rechne die Komma-Werte zusammen.
0b0001 = 0625
0b0010 = 1250
0b0100 = 2500
0b1000 = 5000
=============
max 9375
Diese Zahl teile ich durch 100, ergibt maximal 93 (den Rest verwerfe
ich)
Jetzt teile ich diese max 93 durch 10.
Wenn der Rest >=5 ist, wird das Ergebnis um 1 erhöht, sonst nicht.
Fertig ist die gerundete 1/10tel-Grad-Stelle
Ähnlich berechne ich auch die Ziffern der Grade, immer :10 und den Rest
ausgeben.
Ist's eine Null, nur ausgeben, wenn's die Einer-Stelle ist.
Ziffer >0 und zuvor 0er ausgelassen? Dann jetzt die fehlenden Nuller
ausgeben und die aktuelle Ziffer.
So unterdrückst Du gleich noch anführende Nullen.
Die Rumrechnerei mit nahezu beliebig vielen Bit ist, schriftlich, kein
Hexenwerk und dürfte vom Speicherverbrauch einbindbare Bibliotheken um
Längen schlagen. VOn der Ausführungsgeschwindigkeit müsste man schauen,
was die Bibliothek braucht. Die Assembler-Routine ist da recht genügsam.
40bit : 8bit in 40Runden (bei der ersten Routine 26990 Takte, 1MHz ~27ms
für die Umwandlung einer 40bit Zahl in Dezimal).
MfG
Man kann natürlich auch das ganze Gefummel sein lassen, mit
Gleitkommazahlen rechnen, und sich anschließend wundern, dass der
Code 1) deutlich einfacher aussieht damit und 2) trotzdem noch in
den Flash passt. ;-)
Auch, wenn der Chip die Genauigkeit nicht bringt, könnte zumindest
eine komplette erste Nachkommastelle (also nicht nur ".0" oder ".5")
Sinn haben, falls man damit eine Temperaturtendenz erkennen möchte.
Joe F. schrieb:> Da macht eine Darstellung mit 4 Nachkommastellen wohl kaum Sinn...
doch macht es.
Damit kann man eine Änderung ablesen, ob der wert Absolut richtig ist,
spielt oft keine rolle.
Es ist ja nicht so das der Wert um 0,5Grad schwankt, wenn eine konstante
Temperatur vorhanden ist,
Wenn es nicht so genau werden muss geht es recht einfach ohne division.
Deine vier bits um zwei nach rechts schuppsen. Mit 25 multiplizieren und
fertig.
Pseudocode:
print(8bit), print(','), print((4bit >> 2)*25),print('\n')
Edit: ggf. halt eine Variante davon die dein Bit7 auf null prüft. Dann
gehen auch alle 4 bits rein mit dem Faktor 125.
0.0625°K = 62,5°mK !!!!
60 Millikelvin sind schon sehr sehr sportlich (auch wenn hier immer
etwas anderes behauptet wird), 2°mK ... da sieht man keinen Trend, da
sieht man nur noch Rauschen, garantiert.
Mein bester Referenzthermometer auf Arbeit löst 0,005 °K auf bei einer
(vom Hersteller versprochenen) Genauigkeit von +- 1 Digit.
0,0625K Auflösung sind nicht wirklich sinnvoll und schon gar nicht zum
Erkennen eines Trendes (von der absoluten Genauigkeit rede ich nicht).
Hi
Kelvin doch ohne Grad, oder??
Da das 12.te (letzte) Bit 0,0625K entspricht, ist eh bestenfalls das
11.te Bit aussagekräftig, wobei eine reine Versteifung auf das dann
'letzte Bit' auch wieder keine Ruhe in die Anzeige bringt.
Für Ruhe sorgt man, wenn man der Änderung um das letzte Bit 'hinterher
hinkt' - wenn es weiter in die gleiche Richtung geht, kommen wir schon
hinterher, wenn das letzte Bit aber wackelt (und ggf. dadurch Das davor
auch), wird die Anzeige erst angepasst, wenn der Messwert 'mehr als
einen Schritt' entfernt ist.
Gerade erst aus den Fingern gesaugt, klingt aber ganz brauchbar :)
(und ganz ohne Fließkommazahlen und 'noch nen Pfund in den Flash ...
kommen se ruhig rein, wir verkaufen auch größere Steinchen)
MfG
posti schrieb:> (und ganz ohne Fließkommazahlen und 'noch nen Pfund in den Flash ...> kommen se ruhig rein, wir verkaufen auch größere Steinchen)
Ausprobiert oder daher gelabert?
Matze schrieb:> Ich lese über den I2C Bus die Temperatur mittels> ds1631 in eine 2 Byte int Variable aus. Eingestellt habe ich eine 12 Bit> Auflösung, also eine 0.0625°C. Der Nachkommawert befindet sich in den> vier höchstwertigen Bits des Lowbytes.
Watt is ne Dampfmaschin?..
Versuche doch mal, nachzudenken. Also du hast da ein 2 Byte-Ergebnis,
dessen LSB für dein gewünschtes Ergebnis eine Wertigkeit von 0.0625 hat.
Also ist irgendwo weiter links dein gedachter Dezimalpunkt. Klaro?
Zunächst wandelst du die Zahl ins Positive um und gibst ggf. ein
Minuszeichen aus.
Jetzt kannst du per Schiebeoperation erstmal deinen ganzen Teil
separieren und ausgeben. Ebenfalls klaro? (Wie man sowas macht, solltest
du beherrschen. Nein, nicht mit printf!)
Nun wendest du dich dem Rest zu, also deinem echt gebrochenen Teil. Den
wandelt man so um, daß man ihn zuerst mit 10 multipliziert und dann den
dabei entstehenden ganzen Teil abtrennt (eben so, wie du das zuvor mit
dem ganzen Teil gemacht hast). Der kann jetzt logischermaßen nur 0..9
sein, die Umwandlung in eine Ziffer sollte also auch dir gelingen.
Diese letzte Operation, also Multiplizieren mit 10, ganzen Teil
abtrennen und als Ziffer ausgeben, kannst du so oft machen wie du
willst. In jeder Runde gibt's ne Ziffer. Ab wann die eine Hausnummer
ist, entscheidest du. Bei 4 Nachkommabits würde ich die Runde nur ein
einziges Mal drehen, alle weiteren Stellen sind Mumpitz.
Hast du das jetzt begriffen?
Mir ist das zum Kopfschütteln, mit ansehen zu müssen, mit was für
hochtrabenden Projekten die Leute sich befassen, ohne auch nur
ansatzweise die grundlegenden Fertigkeiten zu beherrschen.
W.S.