Forum: Mikrocontroller und Digitale Elektronik langen Mittelwert bilden


von Mitte (Gast)


Lesenswert?

moin,

ich würde gerne einen sehr sehr langen Mittelwert von Messwerten über 
einer großen Zeitspanne ermitteln... Soviele Messwerte, dass diese nicht 
in ein einziges RAM-Array hineinpassen würden.

ich könnte also mehrere kurze Mittelwerte bilden und diese wiederum über 
einen längeren Zeitraum mitteln.

Gibt es aber noch weitere Möglichkeiten, speicherschonend längere 
Mittelwerte zu bilden, als man Werte ausfnehmen kann?

mfg

von Floh (Gast)


Lesenswert?

Du brauchst nur eine Variable, wo du deinen neuen Messwert 
draufaddierst.
Geteilt wird ganz zum Schluss.

Oder willst du einen gleitenden Mittelwert?

von Decius (Gast)


Lesenswert?

Suche mal nach gleitenden Mittelwert! Eventuell hilft das.

von keiner (Gast)


Lesenswert?

Ich mache das gerne so:

mittelwert = 0.99 * mittelwert + 0.01 * aktuellerWert

Die Faktoren 0.99 und 0.01 können geändert werden, die Summe muss aber 
immer 1.00 ergeben. Der "mittelwert" nähert sich hierbei asymptotisch 
dem aktuellen Wert an.
Je kleiner der Faktor vor dem aktuellen Wert ist, desto länger dauert 
es.

von Josef (Gast)


Lesenswert?

Hi,

du kannst dir den Mittelwert MW und die Anzahl N der Werte die zum
Mittelwert gefuehrt haben speichern.
Damit wird

MW = (MW * N + neuerWert) / (N+1);
N = N+1;

Und man sollte sich ueber Ueberlaeufe Gedanken machen.
z.B. MW*N kann zu gross werden, etc.

Gruss
Josef

von Rangi J. (rangi)


Lesenswert?

Es geht ja beim gleitenden Mittelwert darum, einen neuen Wert 
draufzuaddieren und dafür den ältesten Wegzuwerfen. Dazu müssen aber 
alle Werten unterwegs gespeichert sein. Wenn man nun nicht den ältesten 
wegwirft sondern eben den Duchschnitt (also den Mittelwert) funktioniert 
das ganze  bei sich langsam ändernden Werten. Dazu ist dann kein Array 
nötig. Die Abweichung vom Idealen gleitenden Mittelwert muss du noch 
beurteilen.

Also MW=MW-(MW/Spanne)+Neu

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Decius schrieb:
> Suche mal nach gleitenden Mittelwert! Eventuell hilft das.
Sowas wie im Beitrag "PT1-Filter in C"

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mitte schrieb:
> ich würde gerne einen sehr sehr langen Mittelwert von Messwerten über
> einer großen Zeitspanne ermitteln... Soviele Messwerte, dass diese nicht
> in ein einziges RAM-Array hineinpassen würden.
Kannst du da auch Zahlen angeben? Mein PC kann z.B. problemlos 8GB ins 
RAM packen. Und dann ist immer noch was frei...

von Bronco (Gast)


Lesenswert?

Es gibt drei einfache Möglichkeiten:

1. Absoluter Mittelwert:
Meßwerte in einem Accumulator aufaddieren und dessen Inhalt durch die 
Anzahl an Meßwerten teilen, dabei Überlauf des Accus berücksichtigen. Du 
brauchst einen definierten Startpunkt, an dem Du den Accu und den 
Meßwertzähler auf 0 setzt.

2. Gleitender Mittelwert:
Du behältst die letzten x Meßwerte in einem Ringpuffer und ersetzt 
jeweils den ältesten Wert durch den neusten. Der Mittelwert wird dann 
berechnet, in dem alle x Elemente des Ringpuffers aufaddierten und die 
Summe durch x geteilt wird.

3. PT1-Filter:
Accu = Meßwert * Gewichtung + Accu * (1.0-Gewichtung);
Mit Gewichtung zwischen 0.0 und 1.0

Wichtig:
Obwohl sie auf den ersten Blink ähnlich wirken, haben diese Algorithmen 
unterschiedliches verhalten.
Ein absoluter Mittelwert wird mit fortlaufender Zeit immer träger, weil 
der Einfluß einzelner Meßwerte immer geringer wird.
Ein gleitender Mittelwert und ein PT1 sind immer gleich "schnell", haben 
dafür aber nur ein begrenztes Gedächtnis.

von Falk B. (falk)


Lesenswert?

@  Bronco (Gast)

>Meßwerte in einem Accumulator aufaddieren und dessen Inhalt durch die
>Anzahl an Meßwerten teilen, dabei Überlauf des Accus berücksichtigen. Du
>brauchst einen definierten Startpunkt, an dem Du den Accu und den
>Meßwertzähler auf 0 setzt.

Jain. Das macht man aber nicht bis Unendlich, sondern nur über eine 
begrenzte Anzahl Messwerte.

>2. Gleitender Mittelwert:
>Du behältst die letzten x Meßwerte in einem Ringpuffer und ersetzt
>jeweils den ältesten Wert durch den neusten. Der Mittelwert wird dann
>berechnet, in dem alle x Elemente des Ringpuffers aufaddierten und die
>Summe durch x geteilt wird.

Praktisch geht das besser. Man hat ebenfall einen Akku, der am Anfang 
auf Null gesetzt wird. Kommt nun ein neuer messwert, wird

der älteste Messwert vom Akku subtrahiert
aus dem Ringpuffer gelöscht
der neue Messwert zum Akku addiert und
im Ringpuffer an stelle des ältesten Messwerts gespeichert

Damit spart man sich massiv Rechenarbeit.

>3. PT1-Filter:
>Accu = Meßwert * Gewichtung + Accu * (1.0-Gewichtung);
>Mit Gewichtung zwischen 0.0 und 1.0

Das ist die einfachste Version. Allgemein ist das ein FIR Filter, der 
ein Anzahl alter, gespeicherter Messwerte mit einem Gewischtungsfaktor 
multipliziert und anschließend alles summiert. Auch hier gibt es eine 
rechenzeitsparende Umformung.

>Obwohl sie auf den ersten Blink ähnlich wirken, haben diese Algorithmen
>unterschiedliches verhalten.
>Ein absoluter Mittelwert wird mit fortlaufender Zeit immer träger, weil
>der Einfluß einzelner Meßwerte immer geringer wird.

Damit strebt dessen Grenzfrequenz gegen Null, das will keiner.

>Ein gleitender Mittelwert und ein PT1 sind immer gleich "schnell", haben
>dafür aber nur ein begrenztes Gedächtnis.

Wie so ziemlich alle "normalen" Filter. Das ist OK. Wenn man aber sehr 
niedrige Grenzfrequenzen haben will, ohne massig zu speichern, setzt man 
mehrere gleitende Mittelwerte oder FIR hintereinander, wobei der 
nachfolgende nur jeden nten Messwert des Vorgängers nutzt. Damit 
rediziert man die effektive Abtastrate und damit den Speicheraufwand.

MFG
Falk

von Bronco (Gast)


Lesenswert?

Falk Brunner schrieb:
> Wie so ziemlich alle "normalen" Filter. Das ist OK. Wenn man aber sehr
> niedrige Grenzfrequenzen haben will, ohne massig zu speichern, setzt man
> mehrere gleitende Mittelwerte oder FIR hintereinander, wobei der
> nachfolgende nur jeden nten Messwert des Vorgängers nutzt. Damit
> rediziert man die effektive Abtastrate und damit den Speicheraufwand.

http://www.dspguide.com/ch15/5.htm
ist an dieser Stelle auch sehr interessant!

von Frido (Gast)


Lesenswert?

Josef schrieb:
> Hi,
>
> du kannst dir den Mittelwert MW und die Anzahl N der Werte die zum
> Mittelwert gefuehrt haben speichern.
> Damit wird
>
> MW = (MW * N + neuerWert) / (N+1);
> N = N+1;
>
> Und man sollte sich ueber Ueberlaeufe Gedanken machen.
> z.B. MW*N kann zu gross werden, etc.
>
> Gruss
> Josef

Diese Gleichung ist praktisch, um einen Mittelwert zu bekommen, der 
bspw. alle Messwerte seit Programmstart mittelt, z.B. die im Schnitt 
verbrauchte Energie von einem Motor einer Maschine seit Maschinenstart. 
Vorteil ist, dass ich dann keine große Summe bilden muss, die evtl. zu 
einem Überlauf führen könnte, und ich kann den aktuellen Durchschnitt in 
Echtzeit anzeigen. Ich denke, die Gleichung müsste jedoch korrekt 
lauten:

MW = MW(N-1)/N + MW/N;
N = N + 1;

Überprüfen lässt sich das leicht anhand eines einfachen Beispiels aus 
z.B. 3 Zahlen (N = 3).

von Stefan F. (Gast)


Lesenswert?

keiner schrieb:
> mittelwert = 0.99 * mittelwert + 0.01 * aktuellerWert

Das entspricht einem Tiefpass, richtig?

von Stephan (Gast)


Lesenswert?

Frido schrieb:
> Diese Gleichung ist praktisch, um einen Mittelwert zu bekommen, der
> bspw. alle Messwerte seit Programmstart mittelt, z.B. die im Schnitt
> verbrauchte Energie von einem Motor einer Maschine seit Maschinenstart.
> Vorteil ist, dass ich dann keine große Summe bilden muss, die evtl. zu
> einem Überlauf führen könnte, und ich kann den aktuellen Durchschnitt in
> Echtzeit anzeigen. Ich denke, die Gleichung müsste jedoch korrekt
> lauten:
>
> MW = MW(N-1)/N + MW/N;
> N = N + 1;
>
> Überprüfen lässt sich das leicht anhand eines einfachen Beispiels aus
> z.B. 3 Zahlen (N = 3).

Hat aber den Nachteil das es ziemlich lange dauert bis der Endwert 
angezeigt wird. Habe ich für ein DVM so gemacht. 
Wert=Wert_Alt*3+wert_Neu/4 Wenn der bei Null startet dauert was bis der 
Endwert steht.

von A. Z. (donvido)


Lesenswert?

Ihr Leichenschänder...

Stefanus F. schrieb:
> keiner schrieb:
>> mittelwert = 0.99 * mittelwert + 0.01 * aktuellerWert
>
> Das entspricht einem Tiefpass, richtig?

Das entspricht einem PT1. Ein gleitender Mittelwert ist auch ein 
Tiefpass.

Falk B. schrieb:
> Allgemein ist das ein FIR Filter,

Eher ein IIR...

von Achim H. (anymouse)


Lesenswert?

Frido schrieb:
> Josef schrieb:
>> Hi,
>>
>> du kannst dir den Mittelwert MW und die Anzahl N der Werte die zum
>> Mittelwert gefuehrt haben speichern.
>> Damit wird
>>
>> MW = (MW * N + neuerWert) / (N+1);
>> N = N+1;
>>
>> Gruss
>> Josef
>
> Ich denke, die Gleichung müsste jedoch korrekt
> lauten:
>
MW = MW(N-1)/N + nW/N;
> N = N + 1;

Es sind beides identische Formeln. Unterschied ist die Definition von N:
Oben hat der neue Wert die Nummer "N+1", unten "N". Bei der unteren 
Formel habe ich man das zweite "MW" zu einem "nW" (_n_euer _W_ert) 
korrigiert.

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.