Daten Filtern (Mittelwertfilter)

#1066231
Lesenswert?

Hi

Ich habe einen Neigungssensor von dem ich Werte bekomme.
Nun haben aber die Werte der Neigung auch wenn sich der Sensor nicht 
bewegt einen Spielraum von 0.1-0.3 Grad in denen sich der Wert befindet.

Meine Lösung war ein Mittelwertfilter der immer 10Werte verwendet.
1
xincl01d[9] = xincl01d[8];
2
xincl01d[8] = xincl01d[7];
3
xincl01d[7] = xincl01d[6];
4
xincl01d[6] = xincl01d[5];
5
xincl01d[5] = xincl01d[4];
6
xincl01d[4] = xincl01d[3];
7
xincl01d[3] = xincl01d[2];
8
xincl01d[2] = xincl01d[1];
9
xincl01d[1] = xincl01d[0];
10
xincl01d[0] = xincl01;
11

12
xincl01=xincl01d[0]+xincl01d[1]+...+xincl01d[9];
13
xincl01 = (xincl01/10);

Gibt es einen besseren Lösungsweg für dieses Problem?
Oder meinen Code zu verbessern?

vielen Dank
mfg Rene
#1066322
Lesenswert?

ok sorry etwas genauer:
1
...
2
float xincl01;
3
float xincl01d[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
4
...
5
while(1) {
6
  xincl01 = readXInclinationAdis(); // Sensor auslesen
7

8
  xincl01d[9] = xincl01d[8];
9
  xincl01d[8] = xincl01d[7];
10
  xincl01d[7] = xincl01d[6];
11
  xincl01d[6] = xincl01d[5];
12
  xincl01d[5] = xincl01d[4];
13
  xincl01d[4] = xincl01d[3];
14
  xincl01d[3] = xincl01d[2];
15
  xincl01d[2] = xincl01d[1];
16
  xincl01d[1] = xincl01d[0];
17
  xincl01d[0] = xincl01;       //aktueller Sensorwert
18

19
  xincl01=xincl01d[0]+xincl01d[1]+...+xincl01d[9]; //alle Addieren
20
  xincl01 = (xincl01/10);   //Mittelwert bilden
21

22
  USART_Transmit( xincl01 ); //an PC senden
23

24
}

am Schleifenanfang wird immer ein Wert aus dem Sensor gelesen.
Danach wird dieser in Das Array( xincl01d[0] = xincl01; ) gespeichert. 
Im nächsten Schleifendurchlauf werden alle Werte im Array um eins nach 
"hinten" verschoben und als erster Wert wieder der aktuelle Wert des 
Sensors eingetragen. So erhällt hat man immer die letzten 10 Werte des 
Sensors von denen man den Mittelwert bilden kann.

Meine Frage war ob man dies vereinfachen kann oder ob es andere, bessere 
Verfahren (Filter) gibt um mein Problem zu lösen.

danke
Gast #1067502
Lesenswert?

Die Methode von Benedikt gewichtet natürlich die aktuellen Ergebnisse 
stärker entsprechend der gewählten Konstanten (hier 0.9), eben so wie 
das bei einem IIR-Filter erster Ordnung ist.
Wenn Du trotzdem Deine erste Variante mit dem gleitenden Mittelwert 
möchtest, kann das wesentlich effizienter mit einem Ringpuffer und dem 
aktualisieren der Summe in etwa so gemacht werden:
1
...
2
#define N_WINDOW 10
3

4
float xincl01d[N_WINDOW] = {};
5
float sum_window = 0;
6
int n = 0;
7
...
8
while(1) {
9
  const float x = readXInclinationAdis(); // Sensor auslesen
10
  float y;
11
 
12
  sum_window -= xinc101d[n];  //ältesten Wert rausschmeißen
13
  sum_window += x;
14
  xinc101d[n] = x;  //neuen Wert reinschreiben
15

16
  n++;
17
  if (n >= N_WINDOW)
18
     n = 0;
19

20
  y = sum_window/10;   //Mittelwert bilden
21

22
  USART_Transmit(y); //an PC senden
23
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren