Hi, ich berechne den Mittelwert aus 40 Werten wie folgt: float mittel(float aktuell) { static u08 x=0; static float value[40]; float ergebnis=0; x%=40; value[x++] = aktuell; for (u08 y=0;y<40;y++)ergebnis+= value[y]; return (ergebnis/40); } Die Funktion wird und muss 40mal/Sekunde angesprungen werden. Hat jemand eine schlankere oder schnellere Lösung?
Heb dir die Summe auf. Am Beispiel von 5 zu mittelnden Werten v1 v2 v3 v4 v5 Der Mittelwert berechnet sich zu m = ( v1 + v2 + v3 + v4 + v5 ) / 5 kommt jetzt ein neuer Wert v6 hinzu, dann fällt v1 aus der Rechnung raus: m = ( v2 + v3 + v4 + v5 + v6 ) / 5 Wenn du jetzt die beiden Summierungen betrachtest, dann sind die im wesentlichen gleich. Nur in der zweiten Summe kommt kein v1 vor, dafür aber v6. Die Summanden v2, v3, und v4 sind aber gleich und an deren Summe ändert sich nichts. Aus s = v1 + v2 + v3 + v4 + v5 m = s / 5 ergibt sich daher beim Austauschen von v1 durch v6 s = s - v1 + v6 m = s / 5 auf die Art musst du nicht mehr (in deinem Beispiel) nicht mehr 40 Werte aufsummieren, sondern du nimmst die vorhergehende Summe ziehst das erste Element wieder ab und addierst dafür das letzte hinzu.
1 | float mittel(float aktuell) |
2 | {
|
3 | static u08 x=0; |
4 | static float value[40]; |
5 | static float ergebnis=0; |
6 | |
7 | ergebnis = ergebnis - value[x] + aktuell; |
8 | value[x] = aktuell; |
9 | |
10 | x = ( x + 1 ) % 40; |
11 | |
12 | return ergebnis / 40.0; |
13 | }
|
Da auf einem µC ohne FPU Divisionen teuer sind, würde es sich anbieten, den % zu ersetzen.
1 | float mittel(float aktuell) |
2 | {
|
3 | static u08 x=0; |
4 | static float value[40]; |
5 | static float ergebnis=0; |
6 | |
7 | ergebnis = ergebnis - value[x] + aktuell; |
8 | value[x] = aktuell; |
9 | |
10 | x++; |
11 | if( x == 40 ) |
12 | x = 0; |
13 | |
14 | return ergebnis / 40.0; |
15 | }
|
Warum verwendest du kein PT1-Filter? Müssen das unbedingt 40 Werte sein zum Mitteln? Wenns nur darum geht, Schwankungen zu unterdrücken, dann wird gern ein PT1 genommen...
Vielen Dank lieber Herr Funkamateur aus Mannheim für den Link. Der Rest währe nicht nötig gewesen. 73 & 55
du kannst auch ein PT1 in Software machen das brauch weniger Speicher, aber die fload-division ist lam...
1 | |
2 | float mittel(float aktuell) |
3 | {
|
4 | |
5 | static float ergebnis=0; |
6 | |
7 | ergebnis = ergebnis - ergebnis/40.0 + aktuell; |
8 | |
9 | return ergebnis / 40.0; |
10 | }
|
unschlagbar schnell ist hier integer und eine Zeitkonstante
damit lässt sich nämlich die division als shift erledigen: ob die genauigkeit für dich ausreicht musst du entscheiden.
1 | |
2 | u16 mittel(u16 aktuell) |
3 | {
|
4 | |
5 | static u16 summe=0; |
6 | |
7 | summe = summe - summe/32 + aktuell; |
8 | |
9 | return ergebnis / 32; |
10 | }
|
Für nen gleitenden Mittelwert 40 floats zu spendieren ist sehr großzügig. Kann man sich das nicht leisten gehts auch so: float mittel(float aktuell) { static float ergebnis; #define EPS (1.0/40.0) ergebnis = (1.0-EPS)*ergebnis + EPS*aktuell; return ergebnis; } btw.: Dett is nen PT1 ! Cheers Detlef
Besten Dank an Alle, die Lösung von Karl heinz Buchegger ist genau das was ich gesucht habe. Funktioniert einwandfrei! Michael
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.