Sunday 16 July 2017

Gleitender Mittelwert Algorithmus C

Ein genauerer Blick auf den erweiterten CODAS Moving Average Algorithmus Vielseitiger gleitender Durchschnitt in Advanced CODAS-Algorithmus filtert Wellenformrauschen, extrahiert Mittelwerte und eliminiert Baseline-Drift. Der gleitende Durchschnitt ist eine einfache mathematische Technik, die primär zur Beseitigung von Aberrationen verwendet wird und den tatsächlichen Trend in einer Sammlung von Datenpunkten offenbart. Sie könnten mit ihm aus der Mittelung lärmender Daten in einem Neuling Physik-Experiment oder aus der Verfolgung der Wert einer Investition vertraut sein. Sie wissen vielleicht nicht, dass der gleitende Durchschnitt auch ein Prototyp des endlichen Impulsantwortfilters ist, der häufigste Filtertyp, der in der computerbasierten Instrumentierung verwendet wird. In Fällen, in denen eine gegebene Wellenform mit Rauschen überlagert ist, wo ein Mittel aus einem periodischen Signal extrahiert werden muss oder wo eine langsam driftende Grundlinie aus einem Signal höherer Frequenz eliminiert werden muss, kann ein gleitender Durchschnittsfilter angewendet werden, um das gewünschte zu erzielen Ergebnis. Der gleitende Durchschnittsalgorithmus von Advanced CODAS bietet diese Art der Wellenformfilterleistung. Advanced CODAS ist ein Analyse-Softwarepaket, das auf vorhandenen Wellenformdateien arbeitet, die von WinDaq oder WinDaq-Datenerfassungspaketen der zweiten Generation erstellt wurden. Zusätzlich zu dem gleitenden durchschnittlichen Algorithmus enthält Advanced CODAS auch ein Berichtsgenerator-Dienstprogramm und Software-Routinen für Wellenformintegration, Differenzierung, Peak - und Tal-Erfassung, Rektifikation und arithmetische Operationen. Moving Average Filter Theorie DATAQ Instruments Moving Average Algorithmus ermöglicht eine große Flexibilität in Wellenform-Filter-Anwendungen. Es kann als Tiefpaßfilter verwendet werden, um das Rauschen, das bei vielen Arten von Wellenformen anliegt, oder als Hochpaßfilter zu dämpfen, um eine Drift-Grundlinie von einem Signal höherer Frequenz zu eliminieren. Das Verfahren, das von dem Algorithmus verwendet wird, um die Filtermenge zu bestimmen, beinhaltet die Verwendung eines Glättungsfaktors. Dieser Glättungsfaktor, der von Ihnen durch die Software gesteuert wird, kann erhöht oder verringert werden, um die Anzahl der tatsächlichen Wellenformdatenpunkte oder Abtastwerte anzugeben, die der gleitende Durchschnitt überspannt. Jede periodische Wellenform kann als eine lange Zeichenkette oder Sammlung von Datenpunkten gedacht werden. Der Algorithmus führt einen gleitenden Durchschnitt durch, indem er zwei oder mehr dieser Datenpunkte aus der erfassten Wellenform abgibt, addiert, ihre Summe durch die Gesamtanzahl der hinzugefügten Datenpunkte dividiert und den ersten Datenpunkt der Wellenform durch den gerade berechneten Durchschnitt ersetzt Wiederholen der Schritte mit den zweiten, dritten und so weiter Datenpunkten, bis das Ende der Daten erreicht ist. Das Ergebnis ist eine zweite oder erzeugte Wellenform, die aus den gemittelten Daten besteht und die gleiche Anzahl von Punkten wie die ursprüngliche Wellenform aufweist. Abbildung 1 8212 Jede periodische Wellenform kann als eine lange Zeichenkette oder Sammlung von Datenpunkten gedacht werden. In der obigen Darstellung werden konsekutive Wellenformdatenpunkte durch quotyquot dargestellt, um zu veranschaulichen, wie der gleitende Durchschnitt berechnet wird. In diesem Fall wurde ein Glättungsfaktor von drei angewandt, was bedeutet, dass drei aufeinander folgende Datenpunkte aus der ursprünglichen Wellenform hinzugefügt werden, wobei ihre Summe durch drei geteilt wird, und dann wird dieser Quotient als der erste Datenpunkt einer erzeugten Wellenform aufgetragen. Der Vorgang wiederholt sich mit den zweiten, dritten und anderen Datenpunkten der ursprünglichen Wellenform, bis das Ende der Daten erreicht ist. Eine spezielle Quotientierquot-Technik misst die Anfangs - und Enddatenpunkte der ursprünglichen Wellenform, um sicherzustellen, dass die erzeugte Wellenform die gleiche Anzahl von Datenpunkten wie die Vorlage enthält. Fig. 1 zeigt, wie der gleitende Mittelalgorithmus auf Wellenformdatenpunkte (die durch y dargestellt werden) angewendet wird. Die Abbildung zeigt einen Glättungsfaktor von 3, was bedeutet, dass der Durchschnittswert (dargestellt durch a) über 3 aufeinanderfolgende Wellenformdatenwerte berechnet wird. Beachten Sie die Überlappung, die in den gleitenden Durchschnittsberechnungen vorhanden ist. Es ist diese überlappende Technik, zusammen mit einer speziellen Anfangs - und Endpunktbehandlung, die die gleiche Anzahl von Datenpunkten in der gemittelten Wellenform erzeugt, wie sie im Original existiert. Die Art und Weise, wie der Algorithmus einen gleitenden Durchschnitt berechnet, verdient einen genaueren Blick und kann an einem Beispiel veranschaulicht werden. Sagen wir haben auf einer Diät für zwei Wochen und wir wollen unser durchschnittliches Gewicht in den letzten 7 Tagen zu berechnen. Wir würden unser Gewicht an Tag 7 mit unserem Gewicht an den Tagen 8, 9, 10, 11, 12 und 13 summieren und dann mit 17 multiplizieren. Um das Verfahren zu formalisieren, kann dies folgendermaßen ausgedrückt werden: a (7) 7) y (8) y (9) y (13) Diese Gleichung kann weiter verallgemeinert werden. Der gleitende Mittelwert einer Wellenform kann folgendermaßen berechnet werden: wobei: ein gemittelter Wert n Datenpunktposition s Glättungsfaktor y aktueller Datenpunktwert Bild 2 8212 Die Ausgangswellenform der Kraftmesszelle, die im oberen Kanal als Original und ungefiltert dargestellt ist, und als ein 11-Punkt Gemittelte Wellenform im unteren Kanal. Das Rauschen, das auf der ursprünglichen Wellenform auftritt, war auf die intensiven Vibrationen zurückzuführen, die durch die Presse während des Verpackungsvorgangs erzeugt wurden. Der Schlüssel zu dieser Algorithmenflexibilität ist sein breites Spektrum an auswählbaren Glättungsfaktoren (von 2 - 1.000). Der Glättungsfaktor bestimmt, wie viele tatsächliche Datenpunkte oder Proben gemittelt werden sollen. Das Angeben eines positiven Glättungsfaktors simuliert einen Tiefpaßfilter, während ein negativer Glättungsfaktor ein Hochpassfilter simuliert. Bei dem Absolutwert des Glättungsfaktors gelten bei höheren Werten grßere Glättungsbeschränkungen für die resultierende Wellenform und umgekehrt niedrigere Werte weniger Glättung. Mit der Anwendung des geeigneten Glättungsfaktors kann der Algorithmus auch verwendet werden, um den Mittelwert einer gegebenen periodischen Wellenform zu extrahieren. Ein höherer positiver Glättungsfaktor wird typischerweise angewendet, um mittlere Wellenformwerte zu erzeugen. Anwenden des Moving Average Algorithmus Ein herausragendes Merkmal des gleitenden Durchschnittsalgorithmus ist, dass es viele Male auf die gleiche Wellenform angewendet werden kann, um das gewünschte Filterergebnis zu erhalten. Waveform-Filterung ist eine sehr subjektive Übung. Was möglicherweise eine richtig gefilterte Wellenform zu einem Benutzer sein kann, kann unannehmbar laut zu einem anderen sein. Nur Sie können beurteilen, ob die Anzahl der gemittelten Punkte zu hoch, zu niedrig oder genau richtig gewählt wurde. Die Flexibilität des Algorithmus ermöglicht es Ihnen, den Glättungsfaktor anzupassen und einen weiteren Durchlauf durch den Algorithmus durchzuführen, wenn mit dem anfänglichen Versuch keine zufriedenstellenden Ergebnisse erzielt werden. Die Anwendung und die Fähigkeiten des gleitenden Durchschnittsalgorithmus können am besten durch die folgenden Beispiele veranschaulicht werden. Abbildung 3 8212 Die EKG-Wellenform, die ursprünglich und ungefiltert im oberen Kanal und als 97-Punkt-gemittelte Wellenform im unteren Kanal angezeigt wurde. Beachten Sie die Abwesenheit von Baseline Drift im unteren Kanal. Beide Wellenformen werden in einem komprimierten Zustand für Präsentationszwecke gezeigt. Eine Rauschunterdrückungsanwendung In Fällen, in denen eine gegebene Wellenform mit Rauschen überladen ist, kann das gleitende Durchschnittsfilter angewendet werden, um das Rauschen zu unterdrücken und ein klareres Bild der Wellenform zu liefern. Zum Beispiel benutzte ein fortgeschrittener CODAS-Kunde eine Presse und eine Wägezelle in einem Verpackungsbetrieb. Ihr Produkt sollte auf ein vorbestimmtes Niveau (überwacht durch die Kraftmesszelle) komprimiert werden, um die Größe der Verpackung zu reduzieren, die erforderlich ist, um das Produkt aufzunehmen. Aus Qualitätskontrollgründen beschlossen sie, den Pressenbetrieb mit Instrumentierung zu überwachen. Ein unerwartetes Problem trat auf, als sie begannen, die Echtzeit-Wägezellenausgabe anzuzeigen. Da die Pressenmaschine während des Betriebs beträchtlich vibrierte, war die Ausgangswellenform der Lastzellen schwierig zu unterscheiden, da sie eine große Menge an Rauschen aufgrund der Schwingung aufwies, wie dies in dem oberen Kanal von Fig. 2 gezeigt ist. Dieses Rauschen wurde eliminiert, indem ein 11-Punkt-gemittelter Kanal erzeugt wurde, wie in dem unteren Kanal von Fig. 2 gezeigt. Das Ergebnis war ein deutlich deutlicheres Bild der Wägezellenausgabe. Eine Anwendung bei der Beseitigung von Baseline Drift In Fällen, in denen eine langsam driftende Grundlinie aus einem Signal mit höherer Frequenz entfernt werden muss, kann das gleitende Durchschnittsfilter angewendet werden, um die Drift-Baseline zu eliminieren. Beispielsweise weist eine EKG-Wellenform typischerweise einen gewissen Grad an Grundlinienwanderung auf, wie in dem oberen Kanal von 3 zu sehen ist. Diese Grundliniendrift kann eliminiert werden, ohne die Eigenschaften der Wellenform zu verändern oder zu stören, wie in dem unteren Kanal von Fig. 3 gezeigt. Dies wird durch Anwenden eines geeigneten negativen Glättungsfaktors während der gleitenden Durchschnittsberechnung erreicht. Der geeignete Glättungsfaktor wird durch Dividieren einer Wellenformperiode (in Sekunden) durch das Abtastintervall der Kanäle bestimmt. Das Abtastintervall der Kanäle ist einfach der Reziprokwert der Abtastrate der Kanäle und wird bequem auf dem gleitenden Durchschnitts-Utility-Menü angezeigt. Die Wellenformperiode kann leicht aus dem Anzeigebildschirm bestimmt werden, indem der Cursor an einem geeigneten Punkt auf der Wellenform positioniert, eine Zeitmarke eingestellt und dann der Cursor einen vollständigen Zyklus von der angezeigten Zeitmarke weg bewegt wird. Die Zeitdifferenz zwischen Cursor und Zeitmarke ist eine Wellenformperiode und wird am unteren Rand des Bildschirms in Sekunden angezeigt. In unserem EKG-Beispiel besaß die Wellenform ein Kanalabtastintervall von 0,004 Sekunden (erhalten aus dem gleitenden mittleren Utility-Menü) und eine Wellenformperiode wurde gemessen, um 0,388 Sekunden zu überspannen. Das Dividieren der Wellenformperiode durch das Abtastintervall der Kanäle lieferte einen Glättungsfaktor von 97. Da es sich um die Grundliniendrift handelt, die wir an der Eliminierung interessieren, haben wir einen negativen Glättungsfaktor (-97) auf den gleitenden Durchschnittsalgorithmus angewendet. Dies subtrahierte das gleitende Durchschnittsergebnis des ursprünglichen Wellenformsignals, das die Grundliniendrift ohne störende Wellenforminformation eliminierte. Other Waveform Moving Average Issues Unabhängig von der Anwendung ist der universelle Grund für die Anwendung eines gleitenden mittleren Filters auf Quotsmooth outquot die hohen und niedrigen Aberrationen und zeigen einen repräsentativeren Zwischen-Wellenformwert. Dabei sollte die Software bei der Erzeugung einer gleitenden gemittelten Wellenform nicht andere Merkmale der ursprünglichen Wellenform beeinträchtigen. Beispielsweise sollte die Software automatisch die mit der ursprünglichen Datendatei verknüpften Kalibrierungsinformationen einstellen, so daß sich die gleitende gemittelte Wellenform in den geeigneten Entwicklungseinheiten befindet, wenn sie erzeugt wird. Alle Messwerte in den Figuren wurden mit der WinDaq-Datenerfassungssoftware aufgenommen. Wie andere bereits erwähnt haben, sollten Sie einen IIR-Filter (Endlosimpulsantwort) anstelle des FIR (Finite Impulse Response) - Filters, 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. Auf kleinen Systemen wählen Sie FF auf 12 N, so dass die Multiplikation mit FF als Rechtsverschiebung um N Bits erreicht werden kann. Beispielsweise könnte FF 116 sein 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 nehme in der Regel AD-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 dBoktave über der Rolloff-Frequenz. Allerdings für AD-Lesungen seine in der Regel mehr relevant, um das Filter im Zeitbereich zu betrachten, indem man seine Schrittantwort. 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 daher in diesem Fall 116. 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. Auf kleinen Systemen wird FF gewöhnlich mit 12 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 z. B. 10-Bit-AD-Lesungen und N 4 (FF 116) filtern, benötigen Sie 4 Fraktionsbits unter den 10-Bit-Integer-AD-Messwerten. Einer der meisten Prozessoren, youd tun 16-Bit-Integer-Operationen aufgrund der 10-Bit-AD-Lesungen. In diesem Fall können Sie immer noch genau die gleichen 16-Bit-Integer-Opertions, aber beginnen mit der AD-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 subroutinemacro, 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 Pole 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 ist 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 sind als Makros mit meinem PIC-Assembler-Präprozessor 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 immer sollten 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 Setzen des Wertes von alpha auf 1K. 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 einfach auf den ersten Wert von newInput anstelle von 0 initialisieren und hoffen, dass der erste newInput kein Ausreißer ist. (CutoffFrequencySampleRate) einen Bereich zwischen 0 und 0,5 hat. 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: dspguidech19.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, dass Sie wollen, dass die vorherigen, etwa 6 Artikeln gemittelt, es diskret tun, fügen Sie 6 Elemente und teilen durch 6, so Können Sie den AmplitudeFactor auf 16 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 SUMN aus. Modifizierter IIR-Ringpuffer: Halten Sie einen laufenden SUM der letzten N-Werte. Jedes Mal, wenn ein neues Sample in SUM - SUMN kommt, fügen Sie das neue Sample hinzu und geben SUMN aus. Antwort # 1 am: August 28, 2008, um 13:45 Uhr Wenn Sie 399m lesen Sie Recht, you39re beschreiben ein erster Ordnung IIR-Filter der Wert you39re subtrahieren 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 als ein Box-Filter ist, hängt von der Anwendung ab (die Sprungantwort eines Boxfilters mit einer Gesamtverzögerung von 1ms wird zum Beispiel eine nasty d2dt Spike haben, wenn die Eingangsänderung und wieder 1ms später, aber das Minimum haben wird Mögliche ddt 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 Biastruncation). 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 12N2, aber das nicht wirklich lösen, die Präzision Problem. In diesem Fall bleibt die abnehmende Reihe für immer bei 8, bis die Probe 8-12 (N2) 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 Nutzen dieses Im nicht suren der korrekten Lösung zwar, da das Summieren des Durchschnittes jeder Probe einen angemessenen Betrag des Rundungsfehlers einführen würde. Hmm Ich frage mich, wenn die Trennung der gebrochenen Teil aus dem ganzen Teil helfen würde. Teilen Sie den ganzen Teil jeder Zahl durch den Zähler. Halten Sie drei laufende Summen: 1) der Durchschnitt der ganzen Teile, 2) der Rest von jeder Division und 3) der Bruchteil einer jeden Zahl. Jedes Mal, wenn der ganze Teil einer Zahl geteilt wird, wird das gesamte Teilergebnis zu der durchschnittlichen laufenden Summe addiert, und der Rest wird zu der verbleibenden laufenden Summe addiert. Wenn die verbleibende laufende Summe einen Wert größer oder gleich dem Zählwert erhält, wird sein dividiert durch die Zählung mit dem gesamten Teilergebnis zu der durchschnittlichen laufenden Summe addiert, und der Rest wird zu der restlichen laufenden Summe addiert. Auch wird bei jeder Berechnung der Bruchteil zur Bruchlaufsumme addiert. Wenn die Mittelung beendet ist, wird die verbleibende laufende Summe durch die Zählung geteilt, und das Ergebnis wird der durchschnittlichen laufenden Summe als eine fließende Zahl hinzugefügt. Zum Beispiel: Nun, was mit der fraktionalen laufenden Summe zu tun. Die Gefahr des Überlaufs ist hier viel weniger wahrscheinlich, obwohl es immer noch möglich ist, so dass man damit umgehen würde, wäre es, die gebrochene laufende Summe durch den Zähler am Ende zu teilen und es zu unserem Ergebnis hinzuzufügen: Eine Alternative wäre, den fraktionalen Betrieb zu überprüfen Summe bei jeder Berechnung, um zu sehen, ob sie größer oder gleich count ist. Wenn das passiert, tun Sie einfach das Gleiche, was wir mit der restlichen Summe machen. Excellent Jomit Vaghela 6-Mar-07 21:00 Ich mochte, was Sie gesagt haben kleine Jobs schnell zu großen Arbeitsplätzen. Denken an Optimierung während Codierung ist eine gute Praxis. Vielen Dank Mike DiRenzo 5-Mar-07 16:26 Dies ist das erste Mal, dass ich auf einen Ihrer Artikel reagiert haben. Ich bin aber ein sehr begeisterter Leser. Während des Studiums musste ich gewichtete gleitende Durchschnitte und einfache auch berechnen. Heck, hatte ich sogar einige meiner eigenen gleitenden durchschnittlichen Algorithmen in einer benutzerdefinierten ERP-Implementierung vor einiger Zeit auf der Grundlage einiger der gleichen Formeln, die ich in Operations 101 gelernt zu schaffen. Aber diese Umsetzung, mit Generika, weit überwiegt alles in Bezug auf die Optimierung, Einfachheit und verdammt richtige Coolness. Vielen Dank dafür. Einer Ihrer vielen Fans, In Ruhe und Stille, die Wahrheit wird klar. Ewma gobgob 5-Mar-07 5:30 Wenn Ihr versuchen, einen einfachen gleitenden Durchschnitt zu berechnen, müssen Sie eine Sammlung zu halten, die sehr komplex für eine solche einfache Aufgabe ist. Wie wäre es mit einem ewma Seine 2 Zeilen Code, viel einfacher. Re: ewma Marc Clifton 5-Mar-07 5:47 Wie wäre es mit einer ewma Interessante Idee. Für Leser, die nicht wissen, was ein ewma ist, ist es ein exponentiell gewichtet Moving Average. Die Leute sind nur notorisch unmöglich. --DavidCrow Theres Keine Entschuldigung für nicht kommentieren Ihren Code. - John Simmons geächteter Programmierer Leute, die sagen, daß sie ihren Code später umgestalten, um es gut zu machen, verstehen nicht refactoring, noch die Kunst und das Handwerk der Programmierung. -- Josh Smith Re: ewma pwasser 5-Mar-07 13:21 An estimate of the moving average if the bin size for moving average is n may be obtained by: NewAverage (((n-1) OldAverage) newValue)n This works once the bin is full (sample number n). The bin partially full is often dealt with by using a seed value for the initial moving average (OldAverage) and then using this calculation. This assumes normal distribution of values etc. Youve been busy Colin Angus Mackay 4-Mar-07 12:37 Posting two articles this evening. Great work I dont know how you do it. Ive got about 4 or 5 articles half finished and I just never seem to find the time to complete them. Gut. Maybe if I stayed out of the lounge Id manage it. Re: Youve been busy Marc Clifton 4-Mar-07 14:25 Colin Angus Mackay wrote: Posting two articles this evening. Great work Thanks I was actually writing the article on the running average and realized that the circular list would actually be a really good stand-alone article. Plus, theyre lightweight articles. I can crank them out pretty fast. Its just hard to think of useful but simple stuff. Turns out I needed these two classes anyways. People are just notoriously impossible. --DavidCrow Theres NO excuse for not commenting your code. -- John Simmons outlaw programmer People who say that they will refactor their code later to make it good dont understand refactoring, nor the art and craft of programming. -- Josh Smith Re: Youve been busy JeffPClark 8-Mar-07 1:07 From what Ive read from Marc, he probably has a program that can examine a piece of code and explain the intricate details, then publish it straight to Code Project . Jeff Clark Systems Architect JP Clark, INC. Columbus, Ohio Last Visit: 31-Dec-99 19:00 Last Update: 25-Jan-17 12:14 General News Suggestion Question Bug Answer Joke Praise Rant Admin Use CtrlLeftRight to switch messages, CtrlUpDown to switch threads, CtrlShiftLeftRight to switch pages.


No comments:

Post a Comment