Forum: Mikrocontroller und Digitale Elektronik Rundungsfehler vermeiden


von Christian S. (mueke)


Lesenswert?

Hallo Leute,
ich habe da mal ne Frage bezüglich der Rundungsfehler.
Ich lese einen Sensor aus, welcher mir 14bit digitale Daten an meinen uC 
gibt. Hieraus bilde ich den Mittelwert nach folgender Formel:

NeuerMW = SensorWert/32 + AlterMW - AlterMW/32

Die Division durch 32 mache ich natürlich mit 5 shifts nach rechts. Mein 
Problem dabei ist nun, dass der Mittelwert dann zu ungenau wird. Im 
schlechtesten Fall sind die unteren 5 Bits alle 1 (Also D'31'). Diese 
Abweichung ist mir zu groß. Wie bekomme ich nun hier das Ergebnis 
genauer? Die Bits die bei den Shifts "rausfallen" fange ich schon in 
einer Variablen auf... Wie kann ich das Ergebnis nun damit noch 
korriegieren?

MfG
Muecke

von Thomas B. (owz)


Lesenswert?

Hallo!

Ich hoffe ich hab dein Problem verstanden.
Das Problem ist, dass du erst die Division machts, und dann die Adition.

Probiers mal damit:
NeuerMW = (SensorWert + 32*AlterMW - AlterMW)/32
Das sollte genauer werden.
Und Aufpassen dass keine Überläufe passieren!

MfG Owz

von Christian S. (mueke)


Angehängte Dateien:

Lesenswert?

Hallo Leutz,
im Anhang ist mal ein Bild von meiner Auswertesoftware angehängt.
´Grün dargestelt ist der aktuelle Sensorwert und schwarz der Mittelwert.
Wie man im zweiten Teil des Bildes sieht fällt der Mittelwert 
"Stufenweise" ab. GTenau diesen Effekt möchte ich verhindern und dachte 
mir das es an den Rundungsfehlern bei der Mittelwertbildung liegt... 
Oder woran kann das anders liegen?

MfG
Muecke

von Andreas W. (Gast)


Lesenswert?

hi

mache es wie thomas vorgeschlagen hat, nur lasse die Division durch 32 
weg. dann hast du eine festkommazahl mit einen komma nach den 5 digit. 
wenn du es auf einen PC auswertest kannst du es da ja durch 32 rechnen 
(natürlich mit fließkommazahlen). Wenn du es im µC weiterverwenden 
ausgeben möchtest musst du dir eine nette routine einfallen lassen die 
die kommas (oder kommata?) ausrechnet :)

von Johannes M. (johnny-m)


Lesenswert?

Thomas B. wrote:
> Probiers mal damit:
> NeuerMW = (SensorWert + 32*AlterMW - AlterMW)/32
> Das sollte genauer werden.
> Und Aufpassen dass keine Überläufe passieren!
Und die korrekte Rundung kriegste in den Griff, indem Du vor der 
Division 16 hinzuaddierst. Also
NeuerMW = (SensorWert + 32*AlterMW - AlterMW + 16)/32
Dann ist das Ergebnis auch korrekt gerundet.

von Christian S. (mueke)


Lesenswert?

OK, danke,
ich werde das jetzt mal versuchen und melden, obs geklappt hat. Mit 
Festkommazahlen kann ich leider nicht rechnen wegen dem Prozessor 
(PIC12F675). Nicht gerade viel Platz für große Fließkommaroutinen ;-)

MfG
Muecke

von Johannes M. (johnny-m)


Lesenswert?

Christian Schmalor wrote:
> Wie man im zweiten Teil des Bildes sieht fällt der Mittelwert
> "Stufenweise" ab. GTenau diesen Effekt möchte ich verhindern und dachte
> mir das es an den Rundungsfehlern bei der Mittelwertbildung liegt...
> Oder woran kann das anders liegen?
Ich vermute, dass das u.a. auch daran liegt, dass die Ermittlung der 32 
Messwerte und die Bildung des Mittelwertes zu lange Dauern und das 
Sensorsignal sich dementsprechend zu schnell ändert. Dadurch kriegste 
auch die großen Abweichungen am Anfang, weil der Mittelwert aus 
Messpunkten um einen Spitzenwert herum nunmal deutlich niedriger liegt 
als der Spitzenwert selbst.

von Johannes M. (johnny-m)


Lesenswert?

Christian Schmalor wrote:
> OK, danke,
> ich werde das jetzt mal versuchen und melden, obs geklappt hat. Mit
> Festkommazahlen kann ich leider nicht rechnen wegen dem Prozessor
> (PIC12F675).
Wie bitte? Festkomma geht auf jedem Prozessor! Ich glaube, Du 
verwechselst da was. Schau mal bei Festkommaarithmetik. Da wirst Du 
geholfen.

von Christian S. (mueke)


Lesenswert?

Ich meinte doch nicht, dass der Prozessor das nicht kann, sondern nur, 
dass ich keinen Platz auf dem kleinen Prozessor für Festkommaarithmetik 
hab... Schuldigung, dass ich mich ein bisschen Missverständlich 
ausgedrückt habe. Aber der Platz auf dem uC wird ja auch schon so 
ziemlich knapp

von Johannes M. (johnny-m)


Lesenswert?

Festkommaarithmetik braucht in den meisten Fällen kaum Platz (siehe 
verlinkter Artikel und Vorschlag von Andreas W.). Aber Du musst es ja 
wissen...

von Andreas W. (Gast)


Lesenswert?

Johannes hat recht. Fließkomma und Festkomma ist was unterschiedliches.

wegen den bild dachte ich du verarbeitest die daten im Computer und der 
kann fließkomma ohne probleme.

wenn du auf den µC bleibst, dann bleib bei Festkomma. Wenn alle werte um 
den faktor 32 größer sind, dann stecken in der zahl auch 5 Bit mehr 
informationen.

welche größenordnung haben die werte? gib mal ein beispiel.

außerdem:
auf den bild erkennt man deine gemittelten werte haben eine falsche 
zeitzuordnung. Es scheint so als ob der gemittelte wert die Zeit bekommt 
die der letzte messwert hatte. normalerweise sollte er die zeit von 
einem wert aus der mitte bekommen, am bessten den mittelwert aller 
Zeiten :)

von Benedikt K. (benedikt)


Lesenswert?

Christian Schmalor wrote:
> Ich meinte doch nicht, dass der Prozessor das nicht kann, sondern nur,
> dass ich keinen Platz auf dem kleinen Prozessor für Festkommaarithmetik
> hab...

Quatsch.
Das benötigt geschätzt <50 Bytes mehr und die Genauigkeit wird 
theoretisch unendlich hoch (wenn man ausreichend Stellen verwendet.)

von StinkyWinky (Gast)


Lesenswert?

Das Problem der Formel

NeuerMW = SensorWert/32 + AlterMW - AlterMW/32

liegt darin, dass Du versuchst, den 32.Teil der Differenz von 
Sensor-AlterMW zu addieren, welcher sich solange auslöscht, bis die 
Differenz gross genug ist. Dies ist aus der Grafik schön ersichtlich.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Andreas W. wrote:
> auf den bild erkennt man deine gemittelten werte haben eine falsche
> zeitzuordnung. Es scheint so als ob der gemittelte wert die Zeit bekommt
> die der letzte messwert hatte. normalerweise sollte er die zeit von
> einem wert aus der mitte bekommen, am bessten den mittelwert aller
> Zeiten :)

Der Mittelwert ist zwangsläufig gegenüber dem Messwert verzögert, sonst 
müsste das Filter ja in die Zukunft schauen können.

von Andreas W. (Gast)


Lesenswert?

@Andreas Schwarz

huch, hast natürlich recht.

@Christian

ignoriere das mit der Zeitachse, hab nicht bedacht das es in echtzeit 
filtert.

StinkyWinky könnte recht haben. wird bestimmt sogar. nicht umsonst steht 
im artikel Festkommaarithmetik "erst zum schluss die division".

von eProfi (Gast)


Lesenswert?

Das Verfahren heißt PT1-Filter.
Das ist die einzig richtige Lösung:
Autor: Andreas W. (Gast)
Datum: 29.08.2007 08:15

Ich schreibe das immer so:
MittelWert += MessWert - MittelWert/32;

die Mittelwert-Variable ist dann immer 32x so groß wie der Messwert, der 
Trick besteht darin, dass Du erst dann /32 rechnest, wenn Du den Wert 
brauchst, nicht bereits jedes mal in der Filterfunktion.

Display(MittelWert/32);

Wenn Du am Anfang des Filtern nicht warten willst, bis der Wert sich 
angenähert hat, initialisiere den MittelWert einmalig:

MittelWert = 32 * MessWert;

Du musst bei 14 Bit natürlich aufpassen, weil MittelWert dann 14+5=19 
Bits braucht, also ist eine 24- oder 32-Bit Variable angesagt.

Ein 32er Filter ist übrigens schon relativ stark (hängt vom Verhältinis 
Sampelrate und Nutzfrequenz ab).

Weitere Möglichkeiten:
gleitender Mittelwert  (einfach mit einem Array zu lösen):
Beitrag "Mittelwert aus 40 Werten" (sehr lesenswert!)

oder

echtes DigiFilter (Bessel, Butterworth etc.)

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.