www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mittelwert aus 40 Werten


Autor: Michael (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
float mittel(float aktuell)
{
  static u08 x=0;
  static float value[40];
  static float ergebnis=0;

  ergebnis = ergebnis - value[x] + aktuell;
  value[x] = aktuell;

  x = ( x + 1 ) % 40;

  return ergebnis / 40.0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da auf einem µC ohne FPU Divisionen teuer sind, würde es
sich anbieten, den % zu ersetzen.
float mittel(float aktuell)
{
  static u08 x=0;
  static float value[40];
  static float ergebnis=0;

  ergebnis = ergebnis - value[x] + aktuell;
  value[x] = aktuell;

  x++;
  if( x == 40 )
    x = 0;

  return ergebnis / 40.0;
}

Autor: Matthias Lipinsky (lippy)
Datum:

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

Autor: Primaner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist ein PT1?
Und wo bekommt mann sowas?

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier:
http://de.wikipedia.org/wiki/PT1-Glied

oder in der Winkelgasse gleich neben den Glaskugeln

Autor: Primaner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank lieber Herr Funkamateur aus Mannheim für den Link.
Der Rest währe nicht nötig gewesen.

73 & 55

Autor: Andreas R. (rebirama)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du kannst auch ein PT1 in Software machen
das brauch weniger Speicher, aber die fload-division ist lam...

 
float mittel(float aktuell)
{
  
  static float ergebnis=0;

  ergebnis = ergebnis - ergebnis/40.0 + aktuell;

  return ergebnis / 40.0;
}

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.
 
u16 mittel(u16 aktuell)
{
  
  static u16 summe=0;

  summe = summe - summe/32 + aktuell;

  return ergebnis / 32;
}

Autor: Detlef _a (detlef_a)
Datum:

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

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist, zu langsam

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die Winkelgasse bezog sich hierauf
Beitrag "Einfach Frage zu einer Funktion!"

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank an Alle,

die Lösung von Karl heinz Buchegger ist genau das was ich gesucht habe.
Funktioniert einwandfrei!

Michael

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.