Sunday, October 2, 2016

Gleitender Durchschnitt Gegen Tiefpaß

Frequenzgang des laufenden Mittelfilters Der Frequenzgang eines LTI-Systems ist die DTFT der Impulsantwort, Die Impulsantwort eines L-Sample-gleitenden Mittelwerts Da der gleitende Mittelwert FIR ist, reduziert sich der Frequenzgang auf die endliche Summe We Kann die sehr nützliche Identität verwenden, um den Frequenzgang zu schreiben, wo wir ae minus jomega haben lassen. N 0 und M L minus 1. Wir können an der Größe dieser Funktion interessiert sein, um zu bestimmen, welche Frequenzen durch den Filter ungedämpft werden und welche gedämpft werden. Unten ist ein Diagramm der Größe dieser Funktion für L 4 (rot), 8 (grün) und 16 (blau). Die horizontale Achse reicht von Null bis pi Radiant pro Probe. Man beachte, daß der Frequenzgang in allen drei Fällen eine Tiefpaßcharakteristik aufweist. Eine konstante Komponente (Nullfrequenz) im Eingang durchläuft das Filter ungedämpft. Bestimmte höhere Frequenzen, wie z. B. pi / 2, werden durch das Filter vollständig eliminiert. Wenn es aber die Absicht war, ein Tiefpassfilter zu entwerfen, dann haben wir das nicht sehr gut gemacht. Einige der höheren Frequenzen sind nur um einen Faktor von etwa 1/10 (für den 16-Punkt-Bewegungsdurchschnitt) oder 1/3 (für die Vierpunkt-gleitender Durchschnitt) gedämpft. Wir können viel besser als das. Der oben genannte Plot wurde durch den folgenden Matlab-Code erzeugt: omega 0: pi / 400: pi H4 (1/4) (1-exp (-iomega4)) ./ (1-exp (-Iomega)) H8 (1/8 ) (1-exp (-iomega)) - (1-exp (-iomega)) - Geispiel (Omega , Abs (H4) abs (H8) abs (H16) Achse (0, pi, 0, 1) Copyright-Kopie 2000- - Universität von Kalifornien, BerkeleyIm Kodierung etwas in dem Moment, wo Im eine Reihe von Werten im Laufe der Zeit von einer Hardware-Kompass. Dieser Kompass ist sehr genau und Updates sehr oft, mit dem Ergebnis, dass wenn es leicht wackelt, ich am Ende mit dem ungeraden Wert, der wild unvereinbar mit seinen Nachbarn ist. Ich möchte diese Werte glätten. Nachdem ich einiges gelesen hatte, scheint es, dass was ich will, ein Hochpaßfilter, ein Tiefpaßfilter oder ein gleitender Durchschnitt ist. Gleitender Durchschnitt kann ich mit erhalten, halten Sie einfach eine Geschichte der letzten 5 Werte oder was auch immer, und verwenden Sie den Durchschnitt dieser Werte stromabwärts in meinem Code, wo ich war einmal nur mit dem jüngsten Wert. Das sollte, glaube ich, die Wackeln schön abschneiden, aber es schlägt mir, dass seine wahrscheinlich ziemlich ineffizient, und dies ist wahrscheinlich eines dieser bekannten Probleme zu Proper Programmers, denen theres eine wirklich ordentliche Clever Math-Lösung. Ich bin jedoch einer jener schrecklichen selbstprogrammierten Programmierer ohne einen Fetzen der formalen Bildung in irgendetwas sogar vage mit CompSci oder Mathe verwandt. Lesen um ein Bit deutet darauf hin, dass dies ein Hoch-oder Tiefpassfilter sein kann, aber ich kann nicht finden, was in Begriffen verständlich für einen Hack wie ich, was die Wirkung dieser Algorithmen wäre auf einer Reihe von Werten, geschweige denn wie die Mathematik Arbeitet. Die Antwort hier. Zum Beispiel, technisch beantwortet meine Frage, aber nur verständlich für diejenigen, die wahrscheinlich schon wissen, wie das Problem zu lösen. Es wäre ein sehr schöner und kluger Mensch, der die Art des Problems erklären könnte, und das, wie die Lösungen funktionieren, in Begriffen, die einem Kunstabsolventen verständlich sind. Wenn Ihr gleitender Durchschnitt muss lang sein, um die gewünschte Glättung zu erreichen, und Sie brauchen nicht wirklich eine bestimmte Form des Kernels, dann sind Sie besser dran, wenn Sie einen exponentiell verfallenden gleitenden Durchschnitt verwenden: wo Sie Wählen Sie winzig, um eine passende Konstante zu sein (zB, wenn Sie winzige 1- 1 / N wählen, wird es die gleiche Menge der Mittelung wie ein Fenster der Größe N haben, aber verteilt unterschiedlich über ältere Punkte). Wie auch immer, da der nächste Wert des gleitenden Durchschnitts hängt nur von der vorherigen und Ihre Daten, müssen Sie nicht eine Warteschlange oder etwas zu halten. Und Sie können denken, dies zu tun, so etwas wie: Nun, ich habe einen neuen Punkt, aber ich dont wirklich vertrauen es, so Im werde 80 meiner alten Schätzung der Messung zu halten, und nur vertrauen diesem neuen Datenpunkt 20. Das ist So ziemlich das gleiche wie zu sagen, Nun, ich vertraue nur diesem neuen Punkt 20, und ich benutze 4 andere Punkte, die ich vertrauen die gleiche Menge, außer dass anstatt explizit nehmen die 4 anderen Punkten, youre unter der Annahme, dass die Mittelung haben Sie das letzte Mal War vernünftig, so können Sie Ihre vorherige Arbeit. Beantwortet Sep 21 10 at 14:27 Hey, ich weiß, das ist 5 Jahre zu spät, aber danke für eine großartige Antwort. I39m arbeitet an einem Spiel, bei dem der Klang sich nach Ihrer Geschwindigkeit ändert, aber wegen des Laufenlassens des Spiels auf einem langsam-ass Computer, würde die Geschwindigkeit wild schwanken, was für die Lenkung gut war, aber super ärgerlich in Bezug auf Sound. Dies war eine wirklich einfache und billige Lösung für etwas, das ich für ein wirklich komplexes Problem halten würde. Ndash Wenn Sie versuchen, den gelegentlichen ungeraden Wert zu entfernen, ist ein Tiefpassfilter die beste der drei Optionen, die Sie identifiziert haben. Tiefpaßfilter erlauben langsame Änderungen, wie die, die durch das Drehen eines Kompasses von Hand verursacht werden, während Abweisen von Hochgeschwindigkeitsänderungen, wie z. B. durch Stöße auf der Straße, verursacht werden. Ein gleitender Durchschnitt wird wahrscheinlich nicht ausreichen, da die Auswirkungen eines einzelnen Blips in Ihren Daten auf mehrere nachfolgende Werte wirken, abhängig von der Größe des gleitenden Durchschnittsfensters. Wenn die ungeraden Werte leicht erkannt werden, können Sie sogar mit einem Glitch-Entfer - nal-Algorithmus besser abschneiden, der sie komplett ignoriert: Hier ist ein Guick-Graphen zu veranschaulichen: Der erste Graphen ist das Eingangssignal mit einem unangenehmen Glitch. Die zweite Grafik zeigt die Wirkung eines 10-stelligen Gleitmittels. Der endgültige Graph ist eine Kombination aus dem 10-Sample-Mittelwert und dem einfachen Glitch-Detektionsalgorithmus, der oben gezeigt ist. Wenn der Glitch detektiert wird, wird anstelle des tatsächlichen Wertes der 10-Sample-Mittelwert verwendet. Beantwortet Sep 21 10 am 13:38 Schön erklärt und Bonuspunkte für die Grafik) ndash Henry Cooke Sep 22 10 at 0:50 Wow. Seldomly sah so eine schöne Antwort ndash Muis Jun 4 13 at 9:14 Der gleitende Durchschnitt ist ein Tiefpassfilter. Ndash nomen Okt 21 13 am 19:36 Versuchen Sie einen laufenden / Streaming-Median statt. Ndash kert Apr 25 14 am 22:09 Gleitender Durchschnitt kann ich unten erhalten. Aber es scheint mir, dass seine wahrscheinlich ziemlich ineffizient. Theres wirklich kein Grund ein gleitender Durchschnitt sollte ineffizient sein. Sie halten die Anzahl der Datenpunkte, die Sie in einem Puffer (wie eine zirkuläre Warteschlange) wollen. An jedem neuen Datenpunkt pflücken Sie den ältesten Wert und subtrahieren ihn von einer Summe, und drücken Sie den neuesten und fügen Sie ihn der Summe hinzu. Jeder neue Datenpunkt beinhaltet also nur einen Pop / Push, eine Addition und eine Subtraktion. Ihr gleitender Durchschnitt ist immer diese Verschiebungssumme geteilt durch die Anzahl der Werte in Ihrem Puffer. Es wird ein wenig trickiger, wenn youre Empfangen von Daten gleichzeitig von mehreren Threads, aber da Ihre Daten von einem Hardware-Gerät kommt, das scheint sehr zweifelhaft für mich. Oh und auch: schreckliche Selbst-gelehrte Programmierer vereinen) Der gleitende Durchschnitt schien mir ineffizient, weil Sie einen Puffer von Werten speichern müssen - besser, nur einige Clever Maths mit Ihrem Eingabewert und aktuellen Arbeitswert zu tun Ich denke, dass ist wie exponentiell gleitenden Durchschnitt Arbeitet. Eine Optimierung, die ich für diese Art von gleitendem Durchschnitt gesehen habe, beinhaltet die Verwendung eines Fixlängen-Warteschlangen-Amps, einen Zeiger auf, wo Sie sich in dieser Warteschlange befinden, und einfach den Zeiger um (mit oder einem If) wickeln. Voila Kein teurer Push / Pop. Power für die Amateure, Bruder ndash Henry Cooke Henry: Für einen geraden-gleitenden Durchschnitt brauchst du den Puffer einfach so, dass du weißt, welcher Wert geknallt wird, wenn der nächste Wert gedrückt wird. Das heißt, die quotfixed-Länge Warteschlange amp eine pointerquot Sie beschreiben ist genau das, was ich durch quotcircular queue. quot Bedeutet, warum ich sage, es ist nicht ineffizient. Was meinst du, ich meinte, Und wenn Ihre Antwort ist quotan Array, das seine Werte zurück verschiebt sich auf jedem indexierten removalquot (wie std :: vector in C). Also, I39m so weh I don39t sogar wollen, um mit Ihnen zu sprechen) ndash Dan Tao 22 September at 1:58 Henry: Ich don39t wissen über AS3, aber ein Java-Programmierer hat Sammlungen wie CircularQueue zu seiner Verfügung (I39m Nicht ein Java-Entwickler, so I39m sicher, es gibt bessere Beispiele da draußen that39s genau das, was ich aus einer schnellen Google-Suche gefunden), die genau die Funktionalität implementiert, über die wir reden. I39m ziemlich zuversichtlich, die Mehrheit der Mittel-und Low-Level-Sprachen mit Standard-Bibliotheken haben etwas ähnliches (z. B. in there39s QueueltTgt). Jedenfalls war ich selbst Philosophie. alles ist vergeben. Ndash Dan Tao Ein exponentiell abnehmender gleitender Durchschnitt kann von Hand mit nur dem Trend berechnet werden, wenn Sie die richtigen Werte verwenden. Siehe www. fourmilab. ch/hackdiet/e4/ für eine Idee, wie dies schnell mit einem Stift und Papier, wenn Sie für exponentiell geglättet gleitenden Durchschnitt mit 10 Glättung suchen. Aber da Sie einen Computer haben, möchten Sie wahrscheinlich binäre Verschiebung im Gegensatz zur Dezimalverschiebung tun) Auf diese Weise brauchen Sie nur eine Variable für Ihren aktuellen Wert und einen für den Durchschnitt. Daraus kann dann der nächste Mittelwert berechnet werden. Beantwortet eine Technik namens Bereichstor, die gut funktioniert mit Low-Vorkommen falschen Proben. Unter der Annahme einer der oben erwähnten Filtertechniken (gleitender Durchschnitt, exponentiell), sobald Sie über ausreichende Historie verfügen (eine Zeitkonstante), können Sie die neue, eingehende Datenprobe für die Angemessenheit testen, bevor sie zur Berechnung hinzugefügt wird. Ist ein gewisses Wissen über die maximale vernünftige Änderungsrate des Signals erforderlich. Wird die Rohprobe mit dem letzten geglätteten Wert verglichen, und wenn der absolute Wert dieser Differenz größer als der zulässige Bereich ist, wird diese Probe herausgeworfen (oder durch eine Heuristik ersetzt, zB eine Vorhersage basierend auf der Steigungsdifferenz oder dem Trend Vorhersagewert aus doppelter exponentieller Glättung) antwortete am 30. April um 6: 56 Ein gleitender Mittelfilter filtert eine Anzahl von Eingangsabtastwerten und erzeugt ein einziges Ausgangsmuster. Diese Mittelungsaktion entfernt die hochfrequenten Komponenten, die in dem Signal vorhanden sind. Gleitende Mittelfilter werden normalerweise als Tiefpassfilter verwendet. Bei dem rekursiven Filteralgorithmus werden auch vorhergehende Abtastwerte für die Mittelung genommen. Ein gleitender Durchschnittsfilter mittelt eine Anzahl von Eingangsabtastwerten und erzeugt eine einzelne Ausgangsabtastung. Diese Mittelungsaktion entfernt die hochfrequenten Komponenten, die in dem Signal vorhanden sind. Gleitende Mittelfilter werden normalerweise als Tiefpassfilter verwendet. Bei dem rekursiven Filteralgorithmus werden auch vorhergehende Abtastwerte für die Mittelung genommen. Dies ist der Grund, warum seine Impulsantwort bis ins Unendliche reicht. So verwenden Sie das Beispielprogramm Die. zip-Datei enthält sowohl Quellcode als auch ausführbare Dateien. Zum Kompilieren und Ausführen des Quellcodes müssen Sie Visual Basic 6.0 in Ihrem Computer installiert haben. Zum Ausführen der ausführbaren Datei müssen Sie Visual Basic 6.0-Laufzeitdateien herunterladen und installieren. Führen Sie movavgfilt. exe aus und Sie sehen das Hauptfenster. Im Hauptfenster. Der obere Teil ist der Funktionsgenerator. Die unterschiedliche Wellenformen erzeugt, um den Filter zu testen. Wir können interaktiv die Amplitude, Frequenz und Form des erzeugten Signals verändern. Um das Programm zu testen, müssen wir zuerst eine entsprechende Wellenform erzeugen. Hier erzeugen wir eine komplexe Wellenform, die aus zwei verschiedenen Frequenzen besteht. Lassen Sie alles in den Standardeinstellungen und klicken Sie aufgeneratequot Button. Nun können Sie in der Grafik neben dem Signalgenerator ein 10 Hz-Signal sehen. Abbildung unten zeigt die Wellenform. Ändern Sie nun die Frequenz auf 100 Hz und klicken Sie erneut auf die Schaltfläche "Generatequot". Die neu erzeugte Wellenform wird der vorhandenen Wellenform hinzugefügt, und die resultierende Wellenform sieht wie eine 10 Hz-Sinuswelle mit 100 Hz-Rauschen aus. Siehe Wellenform unten. Diese Wellenform eignet sich am besten für die Prüfung des Filters, da er zwei unterschiedliche Frequenzen enthält. Sie können den Filter ausführen, indem Sie auf die Schaltfläche "Filterquot" klicken. Von den verfügbaren Optionen auf die quotFilterquot-Schaltfläche. Können Sie Rekursive, nicht rekursive Filterung oder gar keine Filterung auswählen. Die folgende Abbildung zeigt den Ausgang des Filters. Download Moving Average FilterquellcodeMoving Durchschnittlicher Filter (MA Filter) Loading. Das gleitende Mittelfilter ist ein einfaches Tiefpassfilter (Finite Impulse Response), das üblicherweise zum Glätten eines Arrays von abgetasteten Daten / Signalen verwendet wird. Es benötigt M Abtastwerte von Eingang zu einem Zeitpunkt und nimmt den Durchschnitt dieser M-Abtastungen und erzeugt einen einzigen Ausgangspunkt. Es ist eine sehr einfache LPF (Low Pass Filter) Struktur, die praktisch für Wissenschaftler und Ingenieure, um unerwünschte laute Komponente aus den beabsichtigten Daten zu filtern kommt. Mit zunehmender Filterlänge (Parameter M) nimmt die Glätte des Ausgangs zu, während die scharfen Übergänge in den Daten zunehmend stumpf werden. Dies impliziert, dass dieses Filter eine ausgezeichnete Zeitbereichsantwort, aber einen schlechten Frequenzgang aufweist. Der MA-Filter erfüllt drei wichtige Funktionen: 1) Es benötigt M Eingangspunkte, berechnet den Durchschnitt dieser M-Punkte und erzeugt einen einzelnen Ausgangspunkt 2) Aufgrund der Berechnungen / Berechnungen. Führt das Filter eine bestimmte Verzögerung ein 3) Das Filter wirkt als ein Tiefpaßfilter (mit einer schlechten Frequenzbereichsantwort und einer guten Zeitbereichsantwort). Matlab-Code: Der folgende Matlab-Code simuliert die Zeitbereichsantwort eines M-Point Moving Average Filters und zeigt auch den Frequenzgang für verschiedene Filterlängen. Time Domain Response: Auf dem ersten Plot haben wir die Eingabe, die in den gleitenden Durchschnitt Filter geht. Der Eingang ist laut und unser Ziel ist es, den Lärm zu reduzieren. Die nächste Abbildung ist die Ausgangsantwort eines 3-Punkt Moving Average Filters. Es kann aus der Figur abgeleitet werden, dass der Filter mit 3-Punkt-Moving-Average bei der Filterung des Rauschens nicht viel getan hat. Wir erhöhen die Filterabgriffe auf 51 Punkte und wir können sehen, dass sich das Rauschen im Ausgang stark reduziert hat, was in der nächsten Abbildung dargestellt ist. Wir erhöhen die Anzapfungen weiter auf 101 und 501, und wir können beobachten, dass auch wenn das Rauschen fast Null ist, die Übergänge drastisch abgebaut werden (beobachten Sie die Steilheit auf beiden Seiten des Signals und vergleichen Sie sie mit dem idealen Ziegelwandübergang Unser Eingang). Frequenzgang: Aus dem Frequenzgang kann behauptet werden, dass der Roll-off sehr langsam ist und die Stopbanddämpfung nicht gut ist. Bei dieser Stoppbanddämpfung kann klar sein, daß der gleitende mittlere Filter nicht ein Band von Frequenzen von einem anderen trennen kann. Wie wir wissen, führt eine gute Leistung im Zeitbereich zu einer schlechten Leistung im Frequenzbereich und umgekehrt. Kurz gesagt, der gleitende Durchschnitt ist ein außergewöhnlich guter Glättungsfilter (die Aktion im Zeitbereich), aber ein außergewöhnlich schlechtes Tiefpaßfilter (die Aktion im Frequenzbereich) Externe Links: Empfohlene Bücher: Primäre SidebarAs andere haben Sie erwähnt Sollte ein IIR (Endlosimpulsantwort) - Filter anstelle des FIR (Finite Impulse Response) - Filter, den Sie jetzt verwenden, berücksichtigen. Es gibt mehr dazu, aber auf den ersten Blick werden FIR-Filter als explizite Windungen und IIR-Filter mit Gleichungen implementiert. Das besondere IIR-Filter, das ich viel in Mikrocontrollern verwende, ist ein einpoliges Tiefpaßfilter. Dies ist das digitale Äquivalent eines einfachen R-C-Analogfilters. Für die meisten Anwendungen haben diese bessere Eigenschaften als der Kastenfilter, den Sie verwenden. Die meisten Verwendungen eines Box-Filter, die ich begegnet bin, sind ein Ergebnis von jemand nicht Aufmerksamkeit in der digitalen Signalverarbeitung Klasse, nicht als Ergebnis der Notwendigkeit ihrer besonderen Eigenschaften. Wenn Sie nur wollen, um hohe Frequenzen zu dämpfen, dass Sie wissen, Rauschen sind, ist ein einpoliges Tiefpassfilter besser. Der beste Weg, um ein digitales in einem Mikrocontroller zu implementieren, ist in der Regel: FILT lt - FILT FF (NEW - FILT) FILT ist ein Stück persistenten Zustand. Dies ist die einzige persistente Variable, die Sie benötigen, um diesen Filter zu berechnen. NEU ist der neue Wert, den der Filter mit dieser Iteration aktualisiert. FF ist die Filterfraktion. Die die Schwere des Filters einstellt. Betrachten Sie diesen Algorithmus und sehen Sie, dass für FF 0 der Filter unendlich schwer ist, da sich der Ausgang nie ändert. Für FF 1 ist das eigentlich gar kein Filter, da der Ausgang nur dem Eingang folgt. Nützliche Werte sind dazwischen. Bei kleinen Systemen wählen Sie FF auf 1/2 N, so dass die Multiplikation mit FF als Rechtsverschiebung um N Bits erreicht werden kann. Beispielsweise kann FF 1/16 betragen und das Multiplizieren mit FF daher eine Rechtsverschiebung von 4 Bits. Andernfalls benötigt dieses Filter nur eine Subtraktion und eine Addition, obwohl die Zahlen in der Regel größer als der Eingangswert sein müssen (mehr über die numerische Genauigkeit in einem separaten Abschnitt weiter unten). Ich normalerweise nehmen A / D-Messwerte deutlich schneller als sie benötigt werden und wenden Sie zwei dieser Filter kaskadiert. Dies ist das digitale Äquivalent von zwei R-C-Filtern in Serie und dämpft um 12 dB / Oktave über der Rolloff-Frequenz. Für A / D-Messungen ist es jedoch gewöhnlich relevanter, den Filter im Zeitbereich zu betrachten, indem er seine Sprungantwort betrachtet. Dies zeigt Ihnen, wie schnell Ihr System eine Änderung sehen wird, wenn die Sache, die Sie messen, ändert. Zur Erleichterung der Gestaltung dieser Filter (was nur bedeutet Kommissionierung FF und entscheiden, wie viele von ihnen zu kaskadieren), benutze ich mein Programm FILTBITS. Sie legen die Anzahl der Schaltbits für jede FF in der kaskadierten Filterreihe fest und berechnen die Schrittantwort und andere Werte. Eigentlich habe ich in der Regel laufen diese über mein Wrapper-Skript PLOTFILT. Dies führt FILTBITS, die eine CSV-Datei macht, dann die CSV-Datei. Beispielsweise ist hier das Ergebnis von PLOTFILT 4 4: Die beiden Parameter zu PLOTFILT bedeuten, dass es zwei Filter gibt, die von dem oben beschriebenen Typ kaskadiert sind. Die Werte von 4 geben die Anzahl der Schaltbits an, um die Multiplikation mit FF zu realisieren. Die beiden FF-Werte sind in diesem Fall 1/16. Die rote Spur ist die Einheit Schritt Antwort, und ist die Hauptsache zu betrachten. Dies bedeutet beispielsweise, dass sich der Ausgang des kombinierten Filters auf 90 des neuen Wertes in 60 Iterationen niederschlägt, falls sich der Eingang sofort ändert. Wenn Sie ca. 95 Einschwingzeit kümmern, dann müssen Sie etwa 73 Iterationen warten, und für 50 Einschwingzeit nur 26 Iterationen. Die grüne Kurve zeigt Ihnen den Ausgang einer einzelnen Amplitude. Dies gibt Ihnen eine Vorstellung von der zufälligen Rauschunterdrückung. Es sieht aus wie keine einzelne Probe wird mehr als eine 2,5 Änderung in der Ausgabe verursachen. Die blaue Spur soll ein subjektives Gefühl geben, was dieser Filter mit weißem Rauschen macht. Dies ist kein strenger Test, da es keine Garantie gibt, was genau der Inhalt der Zufallszahlen war, die als der weiße Rauscheneingang für diesen Durchlauf von PLOTFILT ausgewählt wurden. Seine nur, um Ihnen ein grobes Gefühl, wie viel es gequetscht werden und wie glatt es ist. PLOTFILT, vielleicht FILTBITS, und viele andere nützliche Dinge, vor allem für PIC-Firmware-Entwicklung ist verfügbar in der PIC Development Tools-Software-Release auf meiner Software-Downloads-Seite. Hinzugefügt über numerische Genauigkeit Ich sehe aus den Kommentaren und nun eine neue Antwort, dass es Interesse an der Diskussion der Anzahl der Bits benötigt, um diesen Filter zu implementieren. Beachten Sie, dass das Multiplizieren mit FF Log 2 (FF) neue Bits unterhalb des Binärpunkts erzeugt. Bei kleinen Systemen wird FF gewöhnlich mit 1/2 N gewählt, so daß diese Multiplikation tatsächlich durch eine Rechtsverschiebung von N Bits realisiert wird. FILT ist daher meist eine feste Ganzzahl. Beachten Sie, dass dies ändert keine der Mathematik aus der Prozessoren Sicht. Wenn Sie beispielsweise 10-Bit-A / D-Messwerte und N 4 (FF 1/16) filtern, benötigen Sie 4 Fraktionsbits unter den 10-Bit-Integer-A / D-Messungen. Einer der meisten Prozessoren, youd tun 16-Bit-Integer-Operationen aufgrund der 10-Bit-A / D-Lesungen. In diesem Fall können Sie immer noch genau die gleichen 16-Bit-Integer-Opertions, aber beginnen mit der A / D-Lesungen um 4 Bits verschoben verschoben. Der Prozessor kennt den Unterschied nicht und muss nicht. Das Durchführen der Mathematik auf ganzen 16-Bit-Ganzzahlen funktioniert, ob Sie sie als 12,4 feste oder wahre 16-Bit-Ganzzahlen (16,0 Fixpunkt) betrachten. Im Allgemeinen müssen Sie jedem Filterpole N Bits hinzufügen, wenn Sie aufgrund der numerischen Darstellung kein Rauschen hinzufügen möchten. Im obigen Beispiel müsste das zweite Filter von zwei 1044 18 Bits haben, um keine Informationen zu verlieren. In der Praxis auf einer 8-Bit-Maschine bedeutet, dass youd 24-Bit-Werte verwenden. Technisch nur den zweiten Pol von zwei würde den größeren Wert benötigen, aber für Firmware Einfachheit ich in der Regel die gleiche Darstellung, und damit der gleiche Code, für alle Pole eines Filters. Normalerweise schreibe ich eine Unterroutine oder Makro, um eine Filterpol-Operation durchzuführen, dann gelten, dass für jeden Pol. Ob eine Unterroutine oder ein Makro davon abhängt, ob Zyklen oder Programmspeicher in diesem Projekt wichtiger sind. So oder so, ich benutze einige Scratch-Zustand, um NEU in die Subroutine / Makro, die FILT Updates, sondern auch lädt, dass in den gleichen Kratzer NEU war in. Dies macht es einfach, mehrere Pole anzuwenden, da die aktualisierte FILT von einem Pol ist Die NEUE der nächsten. Wenn ein Unterprogramm, ist es sinnvoll, einen Zeiger auf FILT auf dem Weg in, die auf nur nach FILT auf dem Weg nach draußen aktualisiert wird. Auf diese Weise arbeitet das Unterprogramm automatisch auf aufeinanderfolgenden Filtern im Speicher, wenn es mehrmals aufgerufen wird. Mit einem Makro benötigen Sie nicht einen Zeiger, da Sie in der Adresse passieren, um auf jeder Iteration zu arbeiten. Code-Beispiele Hier ein Beispiel für ein Makro wie oben für eine PIC 18 beschrieben: Und hier ist ein ähnliches Makro für eine PIC 24 oder dsPIC 30 oder 33: Beide Beispiele werden als Makros unter Verwendung meines PIC-Assembler-Präprozessors implementiert. Die mehr fähig ist als eine der eingebauten Makroanlagen. Clabacchio: Ein weiteres Thema, das ich erwähnen sollte, ist die Firmware-Implementierung. Sie können eine einpolige Tiefpassfilter-Subroutine einmal schreiben und dann mehrmals anwenden. Tatsächlich schreibe ich normalerweise solch ein Unterprogramm, um einen Zeiger im Gedächtnis in den Filterzustand zu nehmen, dann ihn voranbringen den Zeiger, so daß er nacheinander leicht aufgerufen werden kann, um mehrpolige Filter zu verwirklichen. Ndash Olin Lathrop Apr 20 12 at 15:03 1. Dank sehr viel für Ihre Antworten - alle von ihnen. Ich beschloss, dieses IIR-Filter zu verwenden, aber dieser Filter wird nicht als Standard-Tiefpaßfilter verwendet, da ich die Zählerwerte berechnen und sie vergleichen muss, um Änderungen in einem bestimmten Bereich zu erkennen. Da diese Werte von sehr unterschiedlichen Dimensionen abhängig von Hardware Ich wollte einen Durchschnitt nehmen, um in der Lage sein, auf diese Hardware spezifischen Änderungen automatisch reagieren. Wenn Sie mit der Beschränkung einer Macht von zwei Anzahl von Elementen zu durchschnittlich leben können (dh 2,4,8,16,32 etc), dann kann die Teilung einfach und effizient auf einem getan werden Low-Performance-Mikro ohne dedizierte Division, weil es als Bit-Shift durchgeführt werden kann. Jede Schicht rechts ist eine Macht von zwei zB: Der OP dachte, er hatte zwei Probleme, die Teilung in einem PIC16 und Speicher für seinen Ringpuffer. Diese Antwort zeigt, dass die Teilung nicht schwierig ist. Zwar adressiert es nicht das Gedächtnisproblem, aber das SE-System erlaubt Teilantworten, und Benutzer können etwas von jeder Antwort für selbst nehmen oder sogar redigieren und kombinieren andere39s Antworten. Da einige der anderen Antworten eine Divisionsoperation erfordern, sind sie ähnlich unvollständig, da sie nicht zeigen, wie dies auf einem PIC16 effizient erreicht werden kann. Ndash Martin Apr 20 12 at 13:01 Es gibt eine Antwort für einen echten gleitenden Durchschnitt Filter (auch bekannt als Boxcar-Filter) mit weniger Speicher Anforderungen, wenn Sie dont mind Downsampling. Es heißt ein kaskadiertes Integrator-Kamm-Filter (CIC). Die Idee ist, dass Sie einen Integrator, die Sie nehmen Differenzen über einen Zeitraum, und die wichtigsten Speicher-sparende Gerät ist, dass durch Downsampling, müssen Sie nicht jeden Wert des Integrators zu speichern. Es kann mit dem folgenden Pseudocode implementiert werden: Ihre effektive gleitende durchschnittliche Länge ist decimationFactorstatesize, aber Sie müssen nur um Stateize Proben zu halten. Offensichtlich können Sie bessere Leistung erzielen, wenn Ihr stateize und decimationFactor Potenzen von 2 sind, so dass die Divisions - und Restoperatoren durch Shifts und Masken ersetzt werden. Postscript: Ich stimme mit Olin, dass Sie sollten immer erwägen, einfache IIR-Filter vor einem gleitenden durchschnittlichen Filter. Wenn Sie die Frequenz-Nullen eines Boxcar-Filters nicht benötigen, wird ein 1-poliger oder 2-poliger Tiefpassfilter wahrscheinlich gut funktionieren. Auf der anderen Seite, wenn Sie für die Zwecke der Dezimierung filtern (mit einer hohen Sample-Rate-Eingang und Mittelung es für die Verwendung durch einen Low-Rate-Prozess), dann kann ein CIC-Filter genau das, was Sie suchen. (Vor allem, wenn Sie stateize1 verwenden und den Ringbuffer insgesamt mit nur einem einzigen vorherigen Integrator-Wert zu vermeiden) Theres einige eingehende Analyse der Mathematik hinter der Verwendung der ersten Ordnung IIR-Filter, Olin Lathrop bereits beschrieben hat auf der Digital Signal Processing Stack-Austausch (Enthält viele schöne Bilder.) Die Gleichung für diese IIR-Filter ist: Dies kann mit nur Ganzzahlen und keine Division mit dem folgenden Code implementiert werden (möglicherweise benötigen einige Debugging, wie ich aus dem Speicher wurde.) Dieser Filter approximiert einen gleitenden Durchschnitt von Die letzten K Proben durch Einstellen des Wertes von alpha auf 1 / K. Führen Sie dies im vorherigen Code durch die Definition von BITS auf LOG2 (K), dh für K 16 gesetzt BITS auf 4, für K 4 gesetzt BITS auf 2, etc. (Ill Überprüfung der Code hier aufgelistet, sobald ich eine Änderung und Bearbeiten Sie diese Antwort, wenn nötig.) Antwort # 1 am: Juni 23, 2010, um 4:04 Uhr Heres ein einpoliges Tiefpassfilter (gleitender Durchschnitt, mit Cutoff-Frequenz CutoffFrequency). Sehr einfach, sehr schnell, funktioniert super, und fast kein Speicher Overhead. Hinweis: Alle Variablen haben einen Bereich über die Filterfunktion hinaus, mit Ausnahme des übergebenen newInput Hinweis: Dies ist ein einstufiger Filter. Mehrere Stufen können zusammen kaskadiert werden, um die Schärfe des Filters zu erhöhen. Wenn Sie mehr als eine Stufe verwenden, müssen Sie DecayFactor anpassen (was die Cutoff-Frequenz betrifft), um sie zu kompensieren. Und natürlich alles, was Sie brauchen, ist die beiden Zeilen überall platziert, brauchen sie nicht ihre eigene Funktion. Dieser Filter hat eine Rampenzeit, bevor der gleitende Durchschnitt diejenige des Eingangssignals darstellt. Wenn Sie diese Rampenzeit umgehen müssen, können Sie MovingAverage auf den ersten Wert von newInput anstelle von 0 initialisieren und hoffen, dass der erste newInput kein Ausreißer ist. (CutoffFrequency / SampleRate) einen Bereich zwischen 0 und 0,5 aufweist. DecayFactor ist ein Wert zwischen 0 und 1, in der Regel in der Nähe von 1. Single-precision Schwimmer sind gut genug für die meisten Dinge, ich bevorzuge nur Doppel. Wenn Sie mit ganzen Zahlen bleiben müssen, können Sie DecayFactor und Amplitude Factor in Fractional Integers umwandeln, in denen der Zähler als Integer gespeichert wird und der Nenner eine Ganzzahl von 2 ist (so können Sie Bit-Shift nach rechts als die Nenner, anstatt sich während der Filterschleife teilen zu müssen). Zum Beispiel, wenn DecayFactor 0.99, und Sie Ganzzahlen verwenden möchten, können Sie DecayFactor 0.99 65536 64881. Und dann immer wenn Sie multiplizieren mit DecayFactor in Ihrer Filterschleife, nur verschieben Sie das Ergebnis 16. Für weitere Informationen über dieses, ein ausgezeichnetes Buch thats Online, Kapitel 19 auf rekursive Filter: www. dspguide / ch19.htm PS Für das Moving Average-Paradigma, einen anderen Ansatz für die Einstellung DecayFactor und AmplitudeFactor, die möglicherweise mehr relevant für Ihre Bedürfnisse, können Sie sagen, Sie wollen die vorherigen, etwa 6 Artikeln gemittelt, diskret tun es, fügen Sie 6 Elemente und teilen durch 6, so Können Sie den AmplitudeFactor auf 1/6 und DecayFactor auf (1.0 - AmplitudeFactor) einstellen. Antwortete May 14 12 at 22:55 Jeder andere hat kommentiert gründlich über den Nutzen der IIR vs FIR, und auf Power-of-two-Division. Id nur, um einige Implementierungsdetails zu geben. Das unten genannte funktioniert gut auf kleinen Mikrocontrollern ohne FPU. Es gibt keine Multiplikation, und wenn Sie N eine Potenz von zwei halten, ist die gesamte Division ein-Zyklus-Bit-Verschiebung. Basic FIR-Ringpuffer: Halten Sie einen laufenden Puffer der letzten N-Werte und einen laufenden SUM aller Werte im Puffer. Jedes Mal, wenn eine neue Probe kommt, subtrahieren Sie den ältesten Wert im Puffer von SUM, ersetzen Sie ihn durch das neue Sample, fügen Sie das neue SUM zu SUM hinzu und geben Sie SUM / N aus. Modifizierter IIR-Ringpuffer: Halten Sie einen laufenden SUM der letzten N-Werte. Jedes Mal, wenn ein neues Sample eingeht, SUM - SUM / N, fügen Sie das neue Sample hinzu und geben SUM / N aus. Antwort # 1 am: August 28, 2008, um 13:45 Uhr Wenn Sie 399m lesen Sie Recht, you39re beschreiben einen First-Order IIR-Filter der Wert you39re Subtraktion isn39t der älteste Wert, der herausfällt, sondern ist stattdessen der Durchschnitt der vorherigen Werte. Erstklassige IIR-Filter können sicherlich nützlich sein, aber I39m nicht sicher, was du meinst, wenn Sie vorschlagen, dass der Ausgang ist der gleiche für alle periodischen Signale. Bei einer Abtastrate von 10 kHz liefert das Einspeisen einer 100 Hz-Rechteckwelle in ein 20-stufiges Kastenfilter ein Signal, das für 20 Abtastungen gleichmäßig ansteigt, für 30 sitzt, für 20 Abtastungen gleichmäßig sinkt und für 30 sitzt. Ein erster Ordnung IIR-Filter. Ndash Supercat Aug 28 13 bei 15:31 wird eine Welle, die scharf anfängt zu steigen und allmählich Niveaus in der Nähe (aber nicht auf) das Eingabe-Maximum, dann scharf beginnt zu fallen und schrittweise Niveaus in der Nähe (aber nicht auf) der Eingabe Minimum. Sehr unterschiedliches Verhalten. Ndash Supercat Ein Problem ist, dass ein einfacher gleitender Durchschnitt kann oder auch nicht nützlich sein. Mit einem IIR-Filter können Sie einen schönen Filter mit relativ wenigen Calcs erhalten. Die FIR Sie beschreiben kann Ihnen nur ein Rechteck in der Zeit - ein sinc in freq - und Sie können nicht die Seitenkeulen zu verwalten. Es kann lohnt sich, in ein paar ganzzahlige Multiplikatoren zu werfen, um es eine schöne symmetrische abstimmbare FIR, wenn Sie die Zeitschaltuhren ersparen können. Ndash ScottSeidman: Keine Notwendigkeit für Multiplikatoren, wenn man einfach jede Stufe der FIR entweder den Durchschnitt der Eingabe auf diese Stufe und ihre vorherigen gespeicherten Wert, und dann speichern Sie die Eingabe (wenn man hat Der numerische Bereich, man könnte die Summe anstatt den Durchschnitt verwenden). Ob das besser ist als ein Box-Filter, hängt von der Anwendung ab (die Sprungantwort eines Boxfilters mit einer Gesamtverzögerung von 1ms wird zum Beispiel eine böse d2 / dt-Spitze aufweisen, wenn der Eingang geändert wird, und wieder 1ms später, wird aber haben Die minimal mögliche d / dt für einen Filter mit einer Gesamtverzögerung von 1ms). Ndash supercat Wie mikeselectricstuff sagte, wenn Sie wirklich brauchen, um Ihren Speicherbedarf zu reduzieren, und Sie dont dagegen Ihre Impulsantwort ist eine exponentielle (anstelle eines rechteckigen Puls), würde ich für einen exponentiellen gleitenden durchschnittlichen Filter gehen . Ich nutze sie ausgiebig. Mit dieser Art von Filter, brauchen Sie nicht jeden Puffer. Sie brauchen nicht zu speichern N Vergangenheit Proben. Nur einer. So werden Ihre Speicheranforderungen um einen Faktor von N reduziert. Auch brauchen Sie keine Division für das. Nur Multiplikationen. Wenn Sie Zugriff auf Gleitpunktarithmetik haben, verwenden Sie Fließkomma-Multiplikationen. Andernfalls können ganzzahlige Multiplikationen und Verschiebungen nach rechts erfolgen. Allerdings sind wir im Jahr 2012, und ich würde Ihnen empfehlen, Compiler (und MCUs), mit denen Sie mit Gleitkommazahlen arbeiten können. Abgesehen davon, dass mehr Speicher effizienter und schneller (Sie dont haben, um Elemente in jedem kreisförmigen Puffer zu aktualisieren), würde ich sagen, es ist auch natürlich. Weil eine exponentielle Impulsantwort besser auf die Art und Weise reagiert, wie sich die Natur verhält, in den meisten Fällen. Ein Problem mit dem IIR-Filter fast berührt von Olin und Supercat, aber anscheinend von anderen ignoriert ist, dass die Rundung nach unten führt einige Ungenauigkeiten (und möglicherweise Bias / Trunkierung). Unter der Annahme, dass N eine Potenz von zwei ist und nur ganzzahlige Arithmetik verwendet wird, beseitigt das Shift-Recht systematisch die LSBs des neuen Samples. Das bedeutet, dass, wie lange die Serie jemals sein könnte, wird der Durchschnitt nie berücksichtigen. Nehmen wir z. B. eine langsam abnehmende Reihe (8,8,8,8,7,7,7,7,6,6) an und nehmen an, daß der Durchschnitt tatsächlich 8 ist. Die Faust 7 Probe bringt den Durchschnitt auf 7, unabhängig von der Filterstärke. Nur für eine Probe. Gleiche Geschichte für 6, usw. Jetzt denke an das Gegenteil. Die serie geht auf. Der Durchschnitt bleibt auf 7 für immer, bis die Probe groß genug ist, um es zu ändern. Natürlich können Sie für die Bias korrigieren, indem Sie 1 / 2N / 2, aber das nicht wirklich lösen, die Präzision Problem. In diesem Fall wird die abnehmende Reihe für immer bei 8 bleiben, bis die Probe 8-1 / 2 (N / 2) ist. Für N4 zum Beispiel, wird jede Probe über Null halten den Durchschnitt unverändert. Ich glaube, eine Lösung für das implizieren würde, um einen Akkumulator der verlorenen LSBs halten. Aber ich habe es nicht weit genug, um Code bereit, und Im nicht sicher, es würde nicht schaden, die IIR Macht in einigen anderen Fällen der Serie (zum Beispiel, ob 7,9,7,9 würde durchschnittlich 8 dann). Olin, Ihre zweistufige Kaskade würde auch eine Erklärung brauchen. Halten Sie zwei durchschnittliche Werte mit dem Ergebnis der ersten in die zweite in jeder Iteration eingezogen halten. Was ist der Vorteil davon


No comments:

Post a Comment