Forum: Compiler & IDEs dtostrf()-Funktion


von Ralf K. (Gast)


Lesenswert?

Hallo zusammen,

ich möchte die Temperatur mit der Funktion dtostrf() per UART mit einer 
Nachkommastelle ausgeben. Die Temperatur wird über den Sensor SHT21 
ermittelt.

Mein Problem ist nun, dass nach dem Komma immer nur eine 0 ausgegeben 
wird und sich nur die Vorkommastellen ändern.

Jemand die selbe Erfahrung gemacht und kann mir helfen?

double = temperatur
temperatur = read_temp();
dtostrf(temperatur, 3, 1, puffer_temp);
uart_puts("Temperatur ");
uart_puts(puffer_temp);
uart_puts(" C\n\r");

Danke im Voraus.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf K. schrieb:
> Mein Problem ist nun, dass nach dem Komma immer nur eine 0 ausgegeben
> wird und sich nur die Vorkommastellen ändern.

Du bist dir aber sicher, dass der Temperaturwert auch wirklich mit
Nachkommastellen ermittelt worden ist?

dtostrf() wird in der Testsuite der avr-libc getestet, insofern würde
ich dort erstmal den Fehler eher nicht suchen.

Sofern du nicht akuten Mangel an Flash in deinem Controller hast, würde
ich aber zur deutlich komfortableren Variante mit sprintf() raten.

von Klaus W. (mfgkw)


Lesenswert?

Ralf K. schrieb:
> double = temperatur
> temperatur = read_temp();

Was ist das denn für ein Quelltext? Soll man darin Fehler finden?
Nichts leichter als das...

von Dirk B. (dirkb2)


Lesenswert?

Wie sind read_temp() und  puffer_temp deklariert?

von Karl H. (kbuchegg)


Lesenswert?

Dirk B. schrieb:
> Wie sind read_temp() und  puffer_temp deklariert?

Auch die Funktionsdefnition für read_temp wäre interessant. Denn 
meistens ist es ja so, dass man sich den Wert von einem Sensor holt, der 
die Temperatur nicht als Floating Point Zahl liefert, sondern in 
irgendeiner Form eines int. Sprich: da sind dann Umrechnungen 
involviert. Auch dort können Fehler stecken.

von Ralf K. (Gast)


Lesenswert?

erstmal danke für die Mühe!

also der Sensor ist so konfiguriert, dass er mit 14bit Auflösung misst.

gelesen werden ein high- und ein low-byte, welche dann zusammen in einer 
16bit-Variablen gespeichert werden:

  temperature = ((uint16_t)high<<8) + (low & 0b11111100);

für "temperature" bin ich noch ausprobieren, ob double oder int16_t

diese Variable möchte ich nun formatiert und gewandelt als ASCII-Zeichen 
haben, um per UART und auf einem Display ausgeben zu können.

zu diesem zweck verwende ich zurzeit die dtostrf-Funktion, bin aber auch 
offen für andere Lösungen.

der Puffer für den ASCII-Code ist wie folgt definiert:
char puffer_temp[8];

von Karl H. (kbuchegg)


Lesenswert?

Ralf K. schrieb:

>   temperature = ((uint16_t)high<<8) + (low & 0b11111100);
>
> für "temperature" bin ich noch ausprobieren, ob double oder int16_t

Da brauchst du nix ausprobieren.
Es gibt Regeln in C wie arithmetische Ausdrücke ausgewertet werden.

FAQ: Datentypen in Operationen

>
> diese Variable möchte ich nun formatiert und gewandelt als ASCII-Zeichen
> haben, um per UART und auf einem Display ausgeben zu können.

Na dann passt es ja. Wo keine Kommastellen sind, kommt bei dtostrf eben 
irgendwas.0 raus.

: Bearbeitet durch User
von Ralf K. (Gast)


Lesenswert?

okay, also der fehler ist an der Stelle, an der der Messwert in einer 
uint16_t abgelegt wird?

nach der Umrechnung in die Temperatur muss der Wert in einem Datentyp 
abgelegt werden, der auch Nachkommastellen beinhaltet.

double temp_umgewandelt = -46.82 + 175.72 * temperatur / 65536;

und dann

dtostrf(temp_umgewandelt, 3, 1, puffer_temp); ?

von Karl H. (kbuchegg)


Lesenswert?

Ralf K. schrieb:
> okay, also der fehler ist an der Stelle, an der der Messwert in einer
> uint16_t abgelegt wird?

Das weiss ich nicht.
Du zeigst ja keinen Code bzw. nur homöopathische Dosen davon.

Zeig halt mal alles! So viel wird das schon nicht sein. Auf Anhieb 
fallen mir mindestens 5 mögliche Fehler ein, die du alle gemacht haben 
könntest, die man aber nicht korrigieren kann, wenn man im Code nicht 
prüfen kann, welchen davon du gemacht hast.

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
Noch kein Account? Hier anmelden.