Forum: Mikrocontroller und Digitale Elektronik ADC Gleitender Mittelwert ATmega 8535


von Lars W. (Gast)


Lesenswert?

Hallo

ich habe folgendes Anliegen.
ich habe eine wechslespannung die ich mit einem aktiven gleichrichter zu 
einer pulsierenden Gleichspannung umwandle.
da sich aber sowhl frequenz , als auch spannungshöhe ändert kann ich 
kaum mit glättungskondensatoren arbeiten.
ich wollte jetzt um den spannungswert zu erfassen die pulsierende 
spannung an meinen AD-Wandler anlegen und einen gleitenden Mittlewert 
bilden.
allerings hilft mir dieser artikel kaum weiter:
http://www.rn-wissen.de/index.php/Gleitender_Mittelwert_in_C
ich bräuchte sozusagen eine grundlegende erklärung des dort gegebenen 
programms oder eine andere methode den gleitenden mittelwert zu bilden.

vielen dank schon mal

von Fabian O. (xfr)


Lesenswert?

Das Programm besteht im Prinzip aus einem Ringpuffer, hier ein Array mit 
8 Einträgen. Mit jeder Messung wird der älteste Wert im Array durch den 
neuen Messwert ersetzt. Der gleitende Durchschnitt ist der Durchschnitt 
der 8 Arraywerte.

Beispiel (mit 4 Einträgen):
Der markierte Wert 11 ist der älteste.
1
10 | 12 | 11 |  9
2
          ^^
Durchschnitt = (10 + 12 + 11 + 9) / 4 = 10,5

Jetzt wird 8 gemessen, d.h. der älteste Wert wird durch 8 ersetzt. Der 
neue älteste Wert ist jetzt an der nächsten Position:
1
10 | 12 |  8 |  9
2
               ^^
Durschnitt = (10 + 12 + 8 + 9) / 4 = 9,75

Jetzt wird 10 gemessen:
1
10 | 12 |  8 | 10
2
^^
Durschnitt = (10 + 12 + 8 + 10) / 4 = 10,0

usw.

von Tach (Gast)


Lesenswert?

Das ist so ziemlich die Holzhammer Methode.
Man kann das noch ziemlich vereinfachen wenn man die letzte Summe,den 
ältesten Wert und die aktuelle Position im Array merkt !

Du wirst aber auch hier ein Problem haben.
Du musst Deine Samplefrequenz und Filterlange genauso anpassen an Deine 
gegebenheiten.
Denn das Abtasttheorem gilt hier genauso.
Und endlich viel Ram wirst Du auch haben.

Also erzähl mehr uber das Signal,verwendeten Controller....

von Tach (Gast)


Lesenswert?

Ups.. .uC uberlesen...

von Fabian O. (xfr)


Lesenswert?

Eine Alternative ohne Array wäre folgende:
1
#define FACTOR 4
2
3
uint16_t next(uint16_t val)
4
{
5
  static uint32_t avg = 0;
6
  avg = avg + val - (avg / FACTOR);
7
  return avg / FACTOR;
8
}

Der vierfache Durchschnitt wird in der Variable avg gespeichert. Mit 
jeder Messung wird der aktuelle Messwert addiert und zum Ausgleich der 
bisherige Durchschnitt (avg / FACTOR) abgezogen. Am Ende wird neue 
Durchschnitt (avg /FACTOR) zurückgegeben.

Beispiel mit den gleichen Zahlen:

Die bisherigen Durchschnitt liegt bei 10,5. Der Wert avg beträgt das 
vierfache, also 42.

Jetzt wird 8 gemessen:
avg = 42 + 8 - (42 / 4) = 39,5
Neuer Durchschnitt: 39,5 / 4 = 9,875

Jetzt wird 10 gemessen:
avg = 39,5 + 10 - (39,5 / 4) = 39,625
Neuer Durchschnitt: 39,625 / 4 = 9,90625

Ich habe in beiden Beispielen mit Kommazahlen gerechnet, damit sie 
vergleichbar sind. Tatsächlich kommen bei der Rechnung mit Integern aber 
natürlich nur ganze Zahlen raus.

von Rene (Gast)


Lesenswert?


von Jost S. (hummelfan)


Lesenswert?

Hallo,
ich glaube ich habe da was für Dich:
http://www.eetindia.co.in/STATIC/PDF/200011/EEIOL_2000NOV03_EMS_EDA_TA.pdf?SOURCES=DOWNLOAD
Phil Ekstrom erklärt schön verständlich, wie und wofür man gleitender 
Mittelwert nutzen kann.

Im folgenden Beitrag vergleicht Nigel Jones beispielhaft die Effizienz 
des Ekstrom-Algorithmus mit einem QuickSort-Algorithmus.
http://embeddedgurus.com/stack-overflow/2010/11/median-filter-performance-results/
(auch den "earlier post" lesen)

Gruß, Jost

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.