Forum: Mikrocontroller und Digitale Elektronik Arduino / AVR: Überlauf nicht nachvollziehbar ?


von Manfred (Gast)


Lesenswert?

Ich habe ein Gerät gebaut, welches beim Laden eines Akkus die mAh zählt, 
Funktion ist gegeben. Der µC ist ein AT328 als A*-Nano.
1
unsigned long mAsek = 0;
2
unsigned long mAh = 0;
3
float Strom = 10.5;
4
5
mAsek = mAsek + (Strom * 5);  // Messung in mA alle 5 Sekunden
6
mAh = mAsek / 3600;

Im Test erfolgt bei etwa 125.000 mAh ein Überlauf. Das stört nicht, da 
ich diese niemals zu erreichen gedenke. Aber:

unsigned long mAsek müsste bis 2^32 = 4.294.967.296 reichen.
Teile ich die durch 3600, komme ich auf 1.193.046 mAh - wo ist mein 
Denkfehler?

Gucke ich auf den Timer millis() und teile 4.294.967.296 durch 3600 und 
durch 24, ergeben sich die bekannten 49,7 Tage - von daher sollte 2^32 
doch passen.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich sehe keinen Fehler.
Wie sieht die Ausgaberoutine aus?

von Walter (Gast)


Lesenswert?

Manfred schrieb:
> mAsek + (Strom * 5);

das wird als float gerechnet weil Strom float ist  und die Mantisse von 
Float hat nicht besonders viele Bits

von Joachim B. (jar)


Lesenswert?

Manfred schrieb:
> float Strom = 10.5;

ich verzichte gerne auf float, ist dein Strom A oder mA
mit int Variablen kannst du doch alles abdecken von µA bia kA

Ich nehme dann immer was ich zum Rechnen brauche, z.B. cV als Ganzzahl 
(wenn ich 2 Nachkommastellen möchte und setze das Komma in den String 
ein)

von Manfred (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Wie sieht die Ausgaberoutine aus?
1
float Ah = 11.22;
2
3
if (mAh >= 10000) {   // weil im Display nur 4/5-Stellen verfügbar
4
  Ah = mAh / 1000.00; // ich will zwei Nachkommastellen
5
  lcd.print(Ah, 2);
6
  lcd.print(" Ah");
7
}

Wenn Du den Verdacht in diese Richtung lenken willst, könnte ich ja mal 
ein serial.print der mAs bauen und gucken, was da kommt. Dafür muss ich 
eine Sonderversion mit getürktem Strom bauen, drei Tage unter Reallast 
dauern zu lange.

----------

Joachim B. schrieb:
>> float Strom = 10.5;
> ich verzichte gerne auf float, ist dein Strom A oder mA
> mit int Variablen kannst du doch alles abdecken von µA bia kA

Den Strom liefert die INA219.h in mA als Float, natürlich mit 
Nachkommastellen.

=========

Wie gesagt: Ich beklage keine Fehlfunktion, mich ärgert, das ich das 
Verhalten nicht nachgerechnet bekomme!

von (prx) A. K. (prx)


Lesenswert?

Walter schrieb:
>> mAsek + (Strom * 5);
>
> das wird als float gerechnet weil Strom float ist  und die Mantisse von
> Float hat nicht besonders viele Bits

... damit das niemand übersieht ...

von Manfred (Gast)


Lesenswert?

A. K. schrieb:
> ... damit das niemand übersieht ...

Übersehen nicht, aber nicht verstanden. Kannst Du das in Zahlen fassen?

von S. R. (svenska)


Lesenswert?

Gleitkommazahlen sind genau um die Null herum, und ungenau für Zahlen 
weit davon weg.

Ein "float" (double gibt es beim avr-gcc nicht, bzw. wird wie float 
behandelt) hat etwa 7 signifikante Stellen, bei (125.000 * 5) könnte das 
schon auffallen...

Rechne die Stromwerte in mA um und speichere sie in einem long. Das 
könnte helfen.

von Bernd B. (bbrand)


Lesenswert?

Manfred schrieb:
> float Ah = 11.22;
> if (mAh >= 10000) {   // weil im Display nur 4/5-Stellen verfügbar
>   Ah = mAh / 1000.00; // ich will zwei Nachkommastellen
>   lcd.print(Ah, 2);
>   lcd.print(" Ah");
> }

Ich kenne Arduino nicht, daher ist das vielleicht eine blöde Frage:
Kann lcd.print() standardmäßig float verarbeiten? Bei der avr-libc muss 
dazu eine spezielle Library (libprintf_flt.a) gelinkt werden.

Gruß,
Bernd

von Manfred (Gast)


Angehängte Dateien:

Lesenswert?

Bernd B. schrieb:
> Kann lcd.print() standardmäßig float verarbeiten?

Ja.
In "lcd.print(Ah, 2);" sagt die zwei, dass ich zwei Nachkommastellen 
angezeigt haben möchte.

(Bild von einem anderen Gerät)

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.