Forum: Mikrocontroller und Digitale Elektronik sprintf - Kommazahl ohne float


von Axel Schindler (Gast)


Lesenswert?

Hi!

Mit dem AD meines AT90S8535 erfasse ich 4 Temperaturen, die ich zum 
Steuern von 3 Pumpen benutze. Ausserdem werden alle 4 Temperaturen auf 
einem 2x16 LCD ausgegeben.
Bisher geschieht das alles mit float-Variablen.
Hier die Ermittlung der Temperatur aus AD-Wert:
++++++++++++++++++++++++++++++++++++++++++++++
#define x 0.0000470
#define y 0.4052285
#define z 924.2677621

float ReadTemp(unsigned char pin)
{
  float mittelwert=0;
  float temp=0;
  for(i=0;i<300;i++){mittelwert += ReadAD(pin);}
  mittelwert=mittelwert/300;
  temp=((mittelwert*mittelwert*x) + (mittelwert*y) + z -1000 ) / 3.85 ;
  return(temp);
}
+++++++++++++++++++++++++++++++++++++++++++
Wie man sieht wird der AD-Wert über 300 Einlesevorgänge gemittelt und 
dann daraus die Temperatur über eine quadratische Formel berechnet.

Zur Ausgabe auf dem Display erzeuge ich 4 Strings mit sprintf die dann 
einzeln auf dem LCD platziert werden:

sprintf(ausgabe4, "H:%3.1f", THeizkessel);

Die Temperatur wird also mit einer Nachkommastelle angezeigt.
Soweit so gut. Funktioniert auch alles prächtig. Nur erzeugt die 
floatingpoint sprintf-Version fast 4kb mehr Code als die Version z.B. 
von gcctest.

Für die Ausgabe per sprintf würde ich jetzt also gerne die Temperaturen 
in Integer "konvertieren". Meine bisherige Idee war die Berechnung von 
Vor- und Nachkommastellen in getrennten Integern, die dann 
folgendermassen ausgegeben werden könnten:

sprintf(ausgabe4, "H:%i,%i", vorkommastellen, nachkommastelle);

Werden beim typecast von float auf Integer die Nachkommastellen nur 
abgeschnitten oder wird gerundet?

Gibt es elegantere Möglichkeiten?

Danke für Tips
Axel

von Ingo B. (Gast)


Lesenswert?

Hi,

ich halte nicht viel von floats bei Mikrocontrollern.

Man kann besser die Berechnung mit int oder long machen.
(einfach um Zehensteller verschieben)

Zur Ausgabe kann man dann z.B. eine Funktion verwenden, der man den 
int-Wert übergibt und zusätzlich die Stelle des Kommas.
So kommt man ohne float-point aus...

Bis dann,
Ingo

von Matthias (Gast)


Lesenswert?

Hi

komplettes ACK

Und dann mittelt man noch über 2^n Werte. Dann reduziert sich die 
Division/Modulooperation auf ein einfaches Rechtsschieben um n Stellen. 
Bei der Ausgabe als Dezimalzahl kommt man aber dann doch nicht mehr um 
Ganzzahldivision. Aber immer noch besser als die float-Funktionen mit zu 
linken.

Matthias

von emil (Gast)


Lesenswert?

hi axel,
habe soeben einen thermometer mit ds1820 fertig gemacht;
meine temp. ausgabe mache ich folgenderweise:

#include <stdlib.h>
#include <math.h>

temp=10*_tatsaechliche_temp; //als integer
sprintf(ausgabe,"%2i.%-1u",temp/10,abs(temp%10));

.....

somit hast du ein ergebnis im format xx.x, wobei
die stellen vor dem komma rechtsbündig und nach dem
komma linksbündig dargestellt werden; funzt prima,
sprintf() braucht ca. 700 bytes

emil

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

@Axel: Beim casten werden die Nachkommastellen einfach abgeschnitten, 
wenn gerundet werden soll muss man also vorher 0.5 addieren.

von Axel Schindler (Gast)


Lesenswert?

So, mal danke für die vielen Antworten!

Habe jetzt zumindest mal die Ausgabe auf Interger umgestellt. Wenns mir 
mal langweilig wird, kann ich die Berechungen ja auch noch ändern. Aber 
jetzt gibts erst noch wichtigeres zu tun.
Achja, habe noch herausgefunden, dass die einfache und platzsparende 
sprintf aus gcctest bzw von dieser Seite mit den negativen Zahlen nicht 
umgehen kann. Macht schon wieder über 1,3kB Codegrösse aus. Aber jetzt 
habe ich wenigstens wieder über 2kb platz.... ;o)

Gruß Axel

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.