mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rundungsfehler vermeiden


Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas B. (owz)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian S. (mueke)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: StinkyWinky (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.