Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage Wandlung nach Float sowie Verständnis von Q8.4 bei NXP Pressure Sensor


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von cab_leer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von eProfi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> 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"

von eProfi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.