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
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.
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
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
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...
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.
@ 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
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!
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).
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.
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...
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.