mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mittelwert mit unbestimmter Anzahl Messwerten


Autor: Hubert F. (hubsif)
Datum:

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

Autor: StinkyWinky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs denn folgendermassen:

MWert_neu = (MWert_neu + ADC_Wert) / 2

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

Autor: zonendoedel (Gast)
Datum:

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

Autor: Hubert F. (hubsif)
Datum:

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

Autor: Uhu Uhuhu (uhu)
Datum:

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

Autor: Hannes Lux (hannes)
Datum:

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

...

Autor: Werner Kraus (i-mon)
Datum:

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

Autor: Rene (Gast)
Datum:

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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rene wrote:
> Man kann auch einen exponentiellen Mittelwert rechnen.
> http://www.ibrtses.com/embedded/exponential.html
> Dessen Funktion is identisch zu einem Tiefpass
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?
;für 8-Bit-Wert:
 in wl,adch             ;linksbündig justierten ADC-Wert einlesen
 sub wert_n,wert        ;1/256 vom alten Wert
 sbc wert,null          ;mit Übertrag subtrahieren
 add wert_n,wl          ;1/256 vom neuen Wert
 adc wert,null          ,mit Übertrag addieren
;fertig...

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

...

Autor: Matthias (Gast)
Datum:

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

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.