Hallo zusammen, ich habe einen NXP MPL3115A2 mit einem AVR 328 p. Laut Datenblatt wird der Temperaturmesswert in 2 Registern mit der Adresse 0x4h und 0x5h gespeichert. http://www.nxp.com/assets/documents/data/en/data-sheets/MPL3115A2.pdf The temperature data is stored as a signed 12-bit integer with a fractional part. The OUT_T_MSB (04h) register contains the integer part in °C and the OUT_T_LSB (05h) register contains the fractional part. This value is representative as a Q8.4 fixed point format where there are eight integer bits (including the signed bit) and four fractional bits. Heisst also, in Register 4 steht der Teil vor dem Komma, inclusive Vorzeichen. Wie darf ich mir das dann vorstellen? ist das dann ein in Bit 7 ein Vorzeichenbit und in bit 6...0 ein Wert von 0..127? Im Zweiten Byte 0x05 stehen dann die Nachkommastellen mit 4Bit left adjusted. Die 4 LSB sind leer. Mein Problem ist dass ich nicht ganz verstehe wie der Datentyp float bei Arduino funktioniert und ich generell auch nicht genau verstehe wie die Konversion funktioniert. Im Beispielcode wird das ganze erst in einen 16 bit integer kopiert: int16_t t; t = Wire.read(); // receive DATA t <<= 8; t |= Wire.read(); // receive DATA t >>= 4; Jetzt steht ja das ja quasi als signed integer da drin, die ersten 4 MSB sind leer, oder? float temp = t; temp /= 16.0; Jetzt wird durch 16 geteilt, durch den Punkt ist eine Floating point operation forciert. Und ich teile durch 16, weil durch 16 teilen das gleiche ist wie 4 bit nach links schieben und ich damit die 4 nachkommastellen-bits in den nachkommabreich verschiebe? aber genau da hört mein Verständnis auf weil ich nicht genau weiss wie die 32Bit der float auf arudino funktioniert. wenn mir das einer erklären könnte wäre super.. grüße und danke.
> aber genau da hört mein Verständnis auf weil ich nicht genau weiss > wie die 32Bit der float auf arudino funktioniert. Brauchst Du auch gar nicht. Der Compiler macht das bei der impliziten Umwandlung von int nach float automatisch. > Und ich teile durch 16, weil durch 16 teilen das gleiche ist > wie 4 bit nach links schieben und ich damit die 4 > nachkommastellen-bits in den nachkommabreich verschiebe? Nein, durch 16 teilen ist das selbe wie um 4 Bit nach rechts schieben. int16_t t; t = Wire.read(); // receive DATA t <<= 8; t |= Wire.read(); // receive DATA //jetzt stehen die 12 Bits linksbündig drin t >>= 4; //und jetzt rechsbündig. Dieser Integer ist die Temperatur in 1/16°C. > Jetzt steht ja das ja quasi als signed integer da drin, > die ersten 4 MSB sind leer, oder? Nein, beim Rechtsschieben von int wird das Vorzeichenbit kopiert (bleibt erhalten). 0x80 (-128) >>1 ist 0xc0 (-64). float temp = t; // integer in float wandeln temp /= 16.0; // 1/16°C in Grad umrechnen Float würde ich aber gar nicht verwenden. Vergleiche etc. funktionieren viel einfacher in int (1/16°C). Beispielcode für die Ausgabe findest Du zur Genüge, z.B. hier: (zweiter Teil des Postings) ab Zeile "f=t12&15; //fractionals " Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C"
Es wird also 2 mal durch 16 dividiert. Zuerst das int16 mit dem >>4, und dann nochmal das float mit /16. Das hätte man auch einfacher haben können: float f= ((Wire.read()<<8) + Wire.read()) / 256.0; Beachte das 256.0: dadurch wird erreicht, dass die Division nicht in Integer, sondern in float geschieht. Sonst gingen die Nachkommastellen verloren.
wenn es dir darum geht die Temperatur auf einem Display anzuzeigen, kannst du vollständig bei integer bleiben. Vorkommawert steht in Register 4. Dann "," aufs Display schreiben und dann Registerwert 5 geteilt durch 26 (als integer). Gibt genau 1 Nachkommastelle, aber mehr macht bei 1/16 Grad C Auflösung eh keinen Sinn.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.