float - Ablage

OP #366164
Lesenswert?

Hi,

ich empfange über UART den Wert von einem zweiten Atmel vom ADC (10
bit). Mein Sensor ist nun so kalibriert, dass ADC 1000 (dez) bzw.
0x3E8
dem "Messwert" 5,0 bar entspricht. Ich muss also meinen Eingangswert
durch 200 teilen. Zur Anzeige auf dem LCD wollte ich sprintf()
verwenden. Passt aber nicht mehr rein :-((. Muss ich mir also selber
was zusammen basteln. Dazu müsste ich aber wissen, wie die einzelnen
Stellen in dem float-Wert (also Eingangswert geteilt durch 200)
abgelegt werden. Habe dazu in der Doku leider nichts gefunden. Ich
hoffe ich habe mich soweit verständlich ausgedrückt. Kann mir jemand
helfen?

Gruss Holger
Gast #366166
Lesenswert?

Versuche am besten, floats komplett zu umgehen. Mach alles mit
Integer-Berechnungen, die benötigen nicht so viele Ressourcen und sind
bei vernünftiger Anwendung meist sogar genauer. Multipliziere Deinen
AD-Wert z.B. zunächst mit 5 (also *1000 / 200) und setze dann bei der
Umformung in ASCII-Zeichen das Komma an die richtige Stelle... (gibt
auch andere Lösungen, das war jetzt die, mit der ich es erst mal auf
die Schnelle probieren würde).

Gruß

Johnny
Gast #366167
Lesenswert?

Warum überhaupt float? Etwas integer-Arithmetik, nach Vor- und
Nachkommastellen getrennt, fertig. Genauer als 5mbar bist du sowieso
nicht, falls dein Sensor das überhaupt hergibt. Wenn du dann die
float-lib weglassen kannst, passt vielleicht auch sprintf wieder rein.

Oliver
#366168
Lesenswert?

Hast du eine Funktion ftoa()?

Wenn nicht kannst du dir auch selbst eine schreiben

Eine sehr kurze Möglichkeit, nicht unbedingt die Schnellste,
ist zb.

void MyFtoA( double Val, char* Buffer )
{
  char Tmp[20];

  itoa( (int)Val, Buffer, 10 );
  Val = Val - (int)Val;   // Nachkommateil
  if( Val < 0 )
  Val = -Val;
  Val *= 1000;                        // für 3 Nachkommastellen
  itoa( (int)(Val+0.5), Tmp, 10 );
  strcat( Buffer, "." );
                    // "000" muss für die Anzahl an Kommastellen
                    // angepasst werden
  strcat( Buffer, &"000"[ strlen(Tmp) ] );
  strcat( Buffer, Tmp );
}

Sie beruht darauf, die Zahl in einen Vorkomma und einen Nachkomma-
Anteil zu splitten und beide Teile getrennt als int-Zahl
mittels itoa zu konvertieren. Ein bischen Mumbo-Zambo ist
noch notwendig, damit im Nachkommateil führende Nullen,
wie bei  31.021, nicht verloren gehen.
Durch den Umweg über int, ist allerdings der Zahlenbereich
klarerweise eingeschränkt. D.h. solange deine float Zahlen
im Bereich -32760 bis +32760 bleiben, ist alles Paletti.

Eine Funktion die eine String Repräsentierung durch fortgesetzte
Division/Multiplikation erreicht, wäre auch nicht schwer
zu schreiben, wäre allerdings deutlich länger.
Gast #366169
Lesenswert?

Also das mit *5 statt /200 ist ja eigentlich nur eine Umrechnung in mBar
und die Werte passen (bei 10 Bit ADC-Auflösung) alle noch locker in
einen 16-Bit (unsigned) integer rein (0x3ff * 5 = 0x13fb [=5115d]). Da
dürfte es überhaupt keine Schwierigkeiten geben. Dann das ganze in (4)
Dezimalstellen umwandeln (musste sowieso machen), in ASCII umwandeln
(im einfachsten Fall, also wenn jede Dezimalstelle in einem char
abgelegt ist, einfach 0x30 addieren)(oder mit itoa(), wenn vorhanden)
und nach der ersten Ziffer ein Komma einfügen -> fertig!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren