Forum: Mikrocontroller und Digitale Elektronik Mittelwert mit unbestimmter Anzahl Messwerten


von Hubert F. (hubsif)


Lesenswert?

Hallo Leute!

Folgendes Problem:
Ich möchte gerne den Mittelwert eines stündlich gelesenen ADC-Werts 
(8-Bit) errechnen. Der µC soll allerdings nicht jeden einzelnen Wert 
speichern, sondern gleich den Mittelwert berechnen.

Folgende Formel habe ich schon dazu erstellt:
MWert_neu = MWert_alt + (ADC_Wert - MWert_alt) / Anzahl_Messwerte

Auf diese Weise müsste ich nur zwei Sachen speichern: MWert_neu und 
Anzahl_Messwerte.

Das Ganze soll mit einem PIC in Assembler gelöst werden und genau da 
liegt mein Problem:
Ich hab keine Erfahrung mit Division o.ä.

Könnt ihr mir zu meinem Problem evtl. ein paar Tipps geben?

Danke!
hubsif.

von StinkyWinky (Gast)


Lesenswert?

Wie wärs denn folgendermassen:

MWert_neu = (MWert_neu + ADC_Wert) / 2

wobei du anstatt der Division einen Schiebeoperatoren nehmen würdest.

von zonendoedel (Gast)


Lesenswert?

Moin,

was fuer nen Mittelwert denn?

Gleitendes Mittel, arithmetisches Mittel, ..... oder oder ?

Fuer ein gleitendes Mittel ueber N Werte musst Du auch N Messwerte im 
Speicher wegmerken.

Falls N eine 2-Potenz ist, reichen in der der Tat ein paar 
Schiebeoperationen fuer die Division.

Und wech...

von Hubert F. (hubsif)


Lesenswert?

StinkyWinky wrote:
> Wie wärs denn folgendermassen:
>
> MWert_neu = (MWert_neu + ADC_Wert) / 2
>
> wobei du anstatt der Division einen Schiebeoperatoren nehmen würdest.

Ich brauch den arithmetischen Mittelwert.
Die o.g. Lösung ergibt meiner Ansicht nach nicht diesen.

Im Endeffekt will ich das gleiche errechnen, wie man normalerweise 
macht:

(Wert1 + Wert2 + ... + Wertn) / n = Mittelwert.

Nachdem n allerdings (quasi) zeitlich unbegrenzt läuft, kann es sehr 
groß werden. Meine o.g. Formel würde das Speichern von etlichen Werten 
verhinden - es müssten nur zwei Werte gespeichert werden.
Zudem brauch ich den aktuellen Mittelwert nach jeder Messung, d.h. ich 
muss den Mittelwert für jedes n berechnen (was natürlich nicht immer 
eine 2er-Potenz ist).

Grüße
hubert.

von Uhu U. (uhu)


Lesenswert?

Dann addiere alle Werte auf und teile durch die Anzahl der Werte.

Warum für die Arithmetiknicht C und 32 oder 64 Bit Wortbreite?

Die C-Routine kannst Du Dir dann in ein Assemblerprogramm einbinden.

von Hannes L. (hannes)


Lesenswert?

In AVR-Assembler kostet mich der 8-Bit-Mittelwert über 256 Messungen 
zwei Register, 5 ASM-Instruktionen und 5 Maschinentakte pro Durchlauf 
(also pro fertige ADC-Wandlung).

Beitrag "Re: Mittelwert berechnung"

Pro Durchlauf wird 1/256 aus dem 'Topf' entnommen und dann 1/256 des 
neuen Wertes in den 'Topf' hineingelegt. 1/256 deshalb, weil man sich 
die Division erspart, indem man 'Byteshifting' betreibt, also einfach 
das andere Byte benutzt. Jeder andere Divisor vergrößert den 
Ressourcenbedarf.

...

von Werner K. (i-mon)


Lesenswert?

Du müsstest doch eigentlich noch die Anzahl Meßwerte haben. Dann wäre 
die Berechnung doch folgendermaßen möglich:

MWertneu= ((MWertneu*AnzahlMeßvorgänge)+ADC-Wert )/AnzahlMeßvorgänge + 
1)

Gruß, Werner

von Rene (Gast)


Lesenswert?

Man kann auch einen exponentiellen Mittelwert rechnen.
http://www.ibrtses.com/embedded/exponential.html
Dessen Funktion is identisch zu einem Tiefpass

von Hannes L. (hannes)


Lesenswert?

Rene wrote:
> Man kann auch einen exponentiellen Mittelwert rechnen.
> http://www.ibrtses.com/embedded/exponential.html
> Dessen Funktion is identisch zu einem Tiefpass
1
output:=input * 1/32 + output -( output * 1/32)

Was ist denn (außer der korrekten Bezeichnung und dem Divisor 32 statt 
256) der Unterschied zu meiner (oben vorgeschlagenen) Methode?
1
;für 8-Bit-Wert:
2
 in wl,adch             ;linksbündig justierten ADC-Wert einlesen
3
 sub wert_n,wert        ;1/256 vom alten Wert
4
 sbc wert,null          ;mit Übertrag subtrahieren
5
 add wert_n,wl          ;1/256 vom neuen Wert
6
 adc wert,null          ,mit Übertrag addieren
7
;fertig...

Ich nutze diese Routine nicht deshalb, weil sie 'exponentiell' ist, 
sondern weil sie mit geringstem Ressourcenverbrauch maximale 
Störunterdrückung ermöglicht.

...

von Matthias (Gast)


Lesenswert?

Wenn du einen Ausgabewert nach jeder messung haben willst, und die Sache 
zur Glättung dienen soll, dann nimm doch ein PT1-Filter.
Berechnung so:
y(n) = c*x(n) + (1-c)*y(n-1)

Somit brauchst du nichts zwischenspeichern, mit Ausnahme des letzten 
ausgerechneten Wertes...

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.