Halo Leute, ich absolviere zurzeit ein Praktikum. Hier frage ich nun einen Sensor (PYD1998) ab (ca jede 15ms). Dieser gibt mir einen digitalen Wert (14bit) aus. Aus diesem Wert möchte ich nun einen gleitenden Mittelwert bilden. Zur Verfügung steht aber nur ein PIC12F675, zu programmieren in Assembler (C Overhead zu groß). Zurzeit mache ich das nach folgendem Schema: (Alter Wert + Neuer Wert) / 2 Dieses ist aber nicht genau genug, da der Wert des Sensors bei Erfasssung einer Person größere Sprünge macht. Der Mittelwert folgt mir dem Signal zu schnell. Hat jemand ne Idee, was man hier fü nen Algorithmus nehmen kann, der auch in Assembler auf den "kleinen" PIC passt? MfG Muecke
Der Algorithmus ist schon der Richtige. Nimm 4 , 8 oder 16 Werte. Welcher Wert für dich der Beste, ist musst du selbst bestimmen. Wenn du ANSI C nimmst und auf Bibliotheken verzichtest, wird der C Overhead sehr klein. Also zb eine Ausgabe nicht mit PRINTF sondern mit direkter Zuweisung in den Ausgangsbuffer schreiben.
Danke schön, aber das würde doch auch bedeuten, dass ich bei 16 Werten, jeden Wert in einer Variablen speichern müsste. Das wären in meinem Fall ja 16Variablen a 16bit, also 32 Byte... Oder bekommt man das auch kleiner hin? MfG Muecke
Du musst halt sehen wieviel Ram du dafür verwenden kannst. Das ist einer der Punkte die du berücksichtigen musst, um die optimalen Parameter zu bestimmen. Eventuell reichen ja auch schon 4 Werte ==> 8 Byte Das Ergebnis einer solchen Praktikumsarbeit kann aber auch sein, das der verfügbare µC für die Aufgabe nicht geeignet ist. Mit Begründung 1.; 2.; ........ Sowie einer Alternative, sprich einem geeigneten µC. Dazu muss aber die ganze Aufgabenstellung, und nicht nur der beschriebene Ausschnitt herangezogen werden.
Beitrag "Re: Mittelwert berechnung" Ist zwar für AVR und ADC, aber anhand der Kommentare sicher auf Dein System und Deinen Sensor übertragbar. ...
>> Das wären in meinem Fall ja 16Variablen a 16bit
Du denkst falsch, du brauchst nur 2 Variablen. Der jeweils neue ADC Wert
sowie den Mittelwert.
adc_summe += adc_wert;
Nen Schleifchen drumherum und gut ist.
Gleitender Mittelwert - ist leider Schrott. Versuch den exponentiellen Mittelwert. http://www.ibrtses.com/embedded/exponential.html
Hallo, habe leider keine Ahnung was dein Sensor macht? Misst er die Wärmeaussendung eines Objektes? Was willst du genau damit feststellen nur ob jemand vorbeiläuft oder auch andere Sachen z.B. wie warm das Objekt ist wie weit weg usw? Könnte mir vorstellen dein dein Wert zu stark schwankt weil man beim vorbeilaufen mit einem Körperteil näher am Objekt ist als mit einem anderen. Probier doch einfach mal nciht alle 15mSek sondern vieleicht alle 100mSek zu messen oder mit noch größeren Abständen so das du nur einen Wert in der Zeit erhälts wo du sonst 10 Werte bekommst. Du kannst aber auch das Signals des Sensors mittels eine regelbaren Widerstand in Reihe und danach einen Kondensator zur Masse dämpfen, oder muss das ganze in Software geschehen. Aber man muss schon wissen was du genau vorhast, also erklär mal deine Aufgabenstellung genauer.
Was du offensichtlich suchst, ist ein Tiefpassfilter in Software (würde der Sensor keine Digital- sondern Analogwerte ausgeben, könntest du das Filter natürlich auch hardwaremäßig realisieren). Die meisten Softwarefilter bilden eine gewichtete Summe über die letzten n (FIR, finite impulse response) oder alle (IIR, infinite impulse response) Messwerte. Die Summe der Gewichte ist i. Allg. gleich 1, so dass bei konstanten Messwerten genau dieser Wert als Ergebnis herauskommt. Der (gleichgewichtete) gleitende Mittelwert ist die einfachste Form eines FIR-Filters. Dabei werden die letzten k Messwerte jeweils mit dem Faktor 1/k gewichtet:
Dazu müssen natürlich die letzten k Werte gespeichert werden, es sei denn, es reicht dir aus, den Mittelwert nur nach jedem k-ten Messzyklus auszugeben. Dann kannst du da so machen, wie Joe vorgeschlagen hat. Die exponentielle Mittelung (s. Rene) ist hingegen die einfachste Form eines IIR-Filters. Dabei unterscheiden sich die Gewichte aufeinander folgender Messwerte um einen konstanten Faktor c:
Der Faktor 1-c sorgt dafür, dass die (unendliche) Summe der Gewichte gleich 1 ist. Die unendliche Summe kann man einfacher rekursiv hinschreiben:
Mit dem Faktor c kann eingestellt werden, wie stark das Filter auf Änderungen der Messwerte reagiert (c=1: überhaupt nicht, c=0: in voller Höhe). Durch andere geeignete Wahl der Gewichte kann praktisch jede Filtercharakteristik realisiert werden. Da es dir aber nicht darum geht, ganz bestimmte Frequenzbereiche scharf auszuschneiden, sondern die Werte einfach irgendwie zu glätten, sollte einer der beiden Vorschläge ausreichend sein. Die exponentielle Mittelung ist vor allem dann einfacher zu realisieren, wenn mit jedem Messwert ein gefilteter Wert als Ergebnis herauspurzeln soll, da außer dem letzten Messwert und dem Mittelwert nichts gespeichert werden muss. Ein Nachteil besteht darin, dass - insbesondere bei großem c - ein grober Ausreißer in den Messwerten das Ergebnis u. U. über sehr lange Zeit verfälscht, da sein Einfluss zwar exponentiell abnimmt, aber nie ganz verschwindet. Bei der gleitenden Mittelung verschwindet der Einfluss nach k Messungen vollständig. Wird der Mittelwert nur alle k Messwerte benötigt, ist die Implemen- tierung der gleitenden Mittelung genauso einfach wie die der exponentielle Mittelung. Um die Divisionen für den µC zu vereinfachen, wählt man für k sinnvollerweise Zweierpotenzen bzw. für c die Kehrwerte von Zweierpotenzen, so dass die Divisionen durch Schiebeoperationen realisiert werden können.
Hi,
>>Dazu müssen natürlich die letzten k Werte gespeichert werden, ...
äh nÖ,..
klar ist wie das arithmetische mittel gebildet wird,..
daher braucht man prinzipiell nur
3
zu Speicherende werte,..
1) k
2) arithmetisches mittel
3) neuer wert
damit man im µC nicht immer hin und her rechnen muss sind natürlich 4
besser:
4) summe aller elemente =(arith. mittel. * k)
nochmal schön:
der ablauf: man bekommt einen neuen wert
addiert diesen zu gespeicherten Summe auf:
jetzt will man das mittel haben , ok:
super, jetzt kann man damit machen was man will, achtung ein neuer wert schleicht sich an =>
ich denke das prinzip ist verstanden, du brauchst also nur k die summe den wert um dein problem zu lösen,.. TIPP: wenn du kein bock auf umständige division hast, addiere erst 2 neue werte auf und dan diviere mit nen shift nach rechts (damit umgehst du die division mit "krummen" divisoren), ... ich hoffe ich habe geholfen,.. grüüüße
oh,.. das mit den schiebeoperationen hat yalu schon gesagt, kommt davon das man das nur überfliegt sry g
Versuche es mal mit dem geometischen Mittelwert, der reagiert nicht so stark auf Ausreisser:
@Zeusi: Was du beschreibst (wenn ich das richtig verstanden habe), ist die Berechnung des Mittelwerts über alle bisherigen Messwerte. Dazu braucht man die Einzelwerte in der Tat nicht zu speichern. Allerdings liefert dieses Verfahren nicht unbedingt das gewünschte Ergebnis, das der Einfluss eines Messwerts auf das Ergebnis mit jeder neuen Messung geringer wird. Dies bedeutet, dass das Ergebnis mit wachsender Laufzeit des Verfahrens immer langsamer auf Änderungen der Messungen reagiert. Das "gleitend" im gleitenden Mittelwert bezieht sich auf das mitlaufende Zeitfenster konstanter Breite k, innerhalb dessen die Messungen gemittelt werden. Alle Messwerte, die älter als die letzen k sind, werden bei der Mittelung nicht mehr berücksichtigt. Damit ist das Verhalten des Verfahrens unabhängig von der Laufzeit. Das Aufsummieren der letzten k Werte kann effizient dadurch erreicht werden, dass in jedem Messschritt der Messwert x(n) zur Summe addiert und der Messwert x(n-k) von der Summe subtrahiert wird. Damit x(n-k) zum aktuellen Zeitpunkt noch bekannt ist, müssen aber die letzten k Werte gespeichert werden. @Michael G.: > Versuche es mal mit dem geometischen Mittelwert, der reagiert nicht > so stark auf Ausreisser: Stimmt. Nur muss dann OP Christian auch noch eine Wurzelfunktion in seinen PIC quetschen :-) Übrigens bin ich begeistert, dass du den Index "geom" in der Formel in aufrechten Buchstaben geschrieben hast. Das machen nicht viele. @pic-assembler: > Wie Setzt man Solche formeln in pic-assambler Um?? Ich stehe eher auf AVRs, außerdem bin ich sehr faul und lasse die Umsetzung lieber den C-Compiler erledigen ;-)
> Ich stehe eher auf AVRs, außerdem bin ich sehr faul und lasse die > Umsetzung lieber den C-Compiler erledigen ;-) Im Ersten beitrag Wurde aber Eindeutig von asm Geschrieben. Demnach Gehen eure Hochwissenschaftlichen antworten an der frage Vorbei.
pic-assambler wrote:
> Wie Setzt man Solche formeln in pic-assambler Um??
Indem man seinen Fundus an Rechenfunktionen durchkramt und
die passenden so kombiniert und abändert, dass
* die Registerbelegungen passen
* die gewünschte Formel berechnet wird.
pic-assambler wrote: >> Ich stehe eher auf AVRs, außerdem bin ich sehr faul und lasse die >> Umsetzung lieber den C-Compiler erledigen ;-) > > Im Ersten beitrag Wurde aber Eindeutig von asm Geschrieben. Demnach > Gehen eure Hochwissenschaftlichen antworten an der frage Vorbei. Seit wann hängt der Gültigkeitsbereich einer Formel von der Programmiersprache ab, in der sie implementiert wird?
> Seit wann hängt der Gültigkeitsbereich einer Formel von der > Programmiersprache ab, in der sie implementiert wird? Der gültigkeitsbereich Nicht, aber die realisierbarkeit bei Knappen ressourcen.
Wie wäre es mit folgendem Weg (Beispiel mit Fensterbreite von 4 Werten, lässt sich natürlich beliebig verändern)? Mittelwert = Summe(k0 .. k3)/4 Neuer Messwert: k4 -> Mittelwert = (3*Mittelwert + k4)/4 Neuer Messwert: k5 -> Mittelwert = (3*Mittelwert + k5)/4 usw... Hierbei soll die Gleichung "Mittelwert = (3*Mittelwert + k4)/4" natürlich im algorithmischen und nicht im mathematischen Sinne gesehen werden.
Fuer knappe resourcen kommt eigentlich nur das exponentielle mittel in Frage. Siehe http://www.ibrtses.com/embedded/exponential.html Ein Bisschen Schieben und Addieren.
Mehr ist es bei mir ja auch nicht (Bei Fensterbreiten von 2,4,8,16 usw. ist die Division ja auch nur ein Bitshift).
Eine Alternative zu Tiefpassfiltern ist der Medianfilter. Liefert bei manchen Anwendungen bessere Ergebnisse und kommt ohne Multiplikationen aus.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.