Tuesday 28 February 2017

Moving Average Filter Code In C

Ist es möglich, einen gleitenden Durchschnitt in C ohne die Notwendigkeit für ein Fenster von Samples zu implementieren. Ich habe festgestellt, dass ich ein bisschen optimieren kann, indem ich eine Fenstergröße, die eine Kraft von zwei, um Bit-Verschiebung statt zu teilen, aber Nicht brauchen einen Puffer wäre nett Gibt es eine Möglichkeit, ein neues gleitendes durchschnittliches Ergebnis nur als eine Funktion des alten Ergebnisses und der neuen Probe auszudrücken. Define ein Beispiel gleitenden Durchschnitt, über ein Fenster von 4 Samples zu sein. Add neue Probe eA Gleitender Durchschnitt kann rekursiv umgesetzt werden, aber für eine genaue Berechnung des gleitenden Mittelpunktes musst du dich an den ältesten Input-Sample in der Summe erinnern, dh der a in deinem Beispiel Für eine Länge N gleitenden Durchschnitt berechnen Sie, wo yn das Ausgangssignal und xn ist Ist das Eingangssignal Eq 1 kann rekursiv geschrieben werden. So müssen Sie sich immer an die Probe x nN erinnern, um zu berechnen 2.As, die von Conrad Turner angezeigt werden, können Sie ein unendlich langes exponentielles Fenster verwenden, das Ihnen erlaubt, zu berechnen Die Ausgabe nur aus der Vergangenheit heraus Setzen und die aktuelle input. but dies ist nicht ein Standard ungewichtet gleitenden Durchschnitt, sondern ein exponentiell gewichteter gleitender Durchschnitt, wo Proben weiter in der Vergangenheit bekommen ein kleineres Gewicht, aber zumindest in der Theorie Sie nie vergessen, was die Gewichte nur kleiner und kleiner für Samples weit in der Vergangenheit. Ich habe einen gleitenden Durchschnitt ohne Einzelposten-Speicher für ein GPS-Tracking-Programm, das ich schrieb. Ich beginne mit 1 Probe und teilen durch 1, um die aktuelle avg. I dann fügen Sie anothe Probe und teilen durch 2 an die Dieses Spiel geht weiter, bis ich die Länge des Durchschnittes bekomme. Jede Zeit danach, füge ich in die neue Probe, bekomm den Durchschnitt und entferne diesen Durchschnitt von der total. Ich bin kein Mathematiker, aber das schien wie ein guter Weg zu Tu es dachte ich, dass es den Magen eines echten Mathe-Kerls drehen würde, aber es stellt sich heraus, dass es eine der akzeptierten Weisen ist, es zu tun Und es funktioniert gut Denken Sie daran, dass je höher Ihre Länge, je langsamer es folgt, was Sie folgen wollen Das ist vielleicht egal Die Zeit, aber wenn Sie Satelliten folgen, wenn Sie langsam sind, könnte der Weg weit von der tatsächlichen Position entfernt sein und es wird schlecht aussehen Sie könnten eine Lücke zwischen dem Sat und den hinteren Punkten haben, wählte ich eine Länge von 15 aktualisiert 6 mal pro Minute zu Erhalten Sie genügend Glättung und nicht zu weit von der tatsächlichen Sat-Position mit dem geglätteten Pfad dots. answered 16. November 16 um 23 03.initialize total 0, zählen 0 jedes Mal sehen einen neuen value. Then eine Eingabe scanf, eine addieren total newValue, Eine Inkrementzählung, eine Divide Durchschnittliche Gesamtzählung. Dies wäre ein gleitender Durchschnitt über alle Eingänge. Um den Durchschnitt über nur die letzten 4 Eingänge zu berechnen, würde es 4 Eingabevariablen erfordern, vielleicht kopiert jeder Eingang in einen älteren Eingang variabel und berechnet dann die neue Bewegung Durchschnittlich als Summe der 4 Eingangsvariablen, geteilt durch 4 rechte Verschiebung 2 wäre gut, wenn alle Eingänge positiv waren, um die durchschnittliche Berechnung zu machen. Vielen Dank am 3. Februar 15 um 4 06.Das wird tatsächlich den Gesamtdurchschnitt und NICHT den gleitenden Durchschnitt berechnen Count erhalten S größer die Auswirkungen einer neuen Eingabe Probe wird verschwindend klein Hilmar 3. Februar 15 um 13 53. Ihre Antwort.2017 Stack Exchange, Inc. Ich weiß, dies ist erreichbar mit Boost wie pro. But ich möchte wirklich vermeiden, Boost ich habe Gegoogelt und fand keine geeigneten oder lesbaren Beispiele. Basisch möchte ich den gleitenden Durchschnitt eines laufenden Stroms von einem Strom von Gleitkommazahlen mit den neuesten 1000 Zahlen als Datenbeispiel verfolgen. Was ist der einfachste Weg, dies zu erreichen. Ich Experimentierte mit der Verwendung eines kreisförmigen Arrays, exponentieller gleitender Durchschnitt und ein einfacher gleitender Durchschnitt und fand heraus, dass die Ergebnisse aus dem kreisförmigen Array meinen Bedürfnissen am besten gefasst wurden. 12 12 bei 4 38.Wenn Ihre Bedürfnisse einfach sind, können Sie einfach nur versuchen, eine Exponentieller gleitender Durchschnitt. Sie ​​einfach machen Sie eine Akkumulator-Variable, und wie Ihr Code bei jedem Sample sieht, aktualisiert der Code den Akkumulator mit dem neuen Wert Sie wählen eine konstante Alpha, die zwischen 0 und 1 ist, und berechnen Sie diese. Sie brauchen nur Einen Wert von a finden Lpha wo die Wirkung einer bestimmten Probe nur für etwa 1000 Proben dauert. Hmm, ich bin nicht wirklich sicher, dass dies für Sie geeignet ist, jetzt, dass ich es hier aussage Das Problem ist, dass 1000 ist ein ziemlich langes Fenster für einen exponentiellen gleitenden Durchschnitt Ich bin mir nicht sicher, dass es ein Alpha gibt, das den Durchschnitt über die letzten 1000 Zahlen verbreiten würde, ohne Unterlauf in der Gleitkomma-Berechnung. Aber wenn man einen kleineren Durchschnitt wünscht, wie 30 Zahlen oder so, ist dies eine sehr einfache und schnelle Art zu tun It. answered Jun 12 12 bei 4 44. 1 auf deinem Post Der exponentielle gleitende Durchschnitt kann das Alpha variabel sein. So kann es verwendet werden, um Zeitbasiswerte zu berechnen zB Bytes pro Sekunde Wenn die Zeit seit dem letzten Akkumulator Update mehr ist Als 1 Sekunde, lassen Sie alpha be 1 0 Andernfalls können Sie alpha be usecs seit letztem Update 1000000 jxh Jun 12 12 at 6 21.Basically Ich möchte den gleitenden Durchschnitt eines laufenden Streams von einem Strom von Gleitkommazahlen mit zu verfolgen Die letzten 1000 Nummern als Datenbeispiel. Nichts E, dass die unten die Gesamtsumme als Elemente als addiert ersetzt, vermeiden kostspielige ON-Traversal, um die Summe zu berechnen - benötigt für den Durchschnitt - on demand. Total ist ein anderer Parameter von T zu unterstützen, zB mit einer langen langen, wenn insgesamt 1000 lang s , Ein int für char s oder ein doppeltes bis total float am. Dies ist ein bisschen fehlerhaft, dass Numsamples an INTMAX vorbeikommen könnten - wenn es dir egal ist, dass du eine langjährige langjährige Benutzung verwenden kannst oder ein extra bool Datenelement verwenden kannst, um zu erfassen, wann der Container ist Wird zuerst gefüllt, während das Radfahren numsamples um das Array am besten dann umbenannt etwas Unschuldiges wie pos. answered Jun 12 12 bei 5 19.on geht davon aus, dass void Operator T Probe ist eigentlich void Operator T Probe oPless Jun 8 14 bei 11 52. oPless ahhh gut gesichtet Eigentlich meinte ich für es zu leeren Betreiber T Probe, aber natürlich könnten Sie verwenden, was Notation Sie mochten, beheben, danke Tony D Jun 8 14 bei 14 27.Als andere haben erwähnt, sollten Sie eine IIR unendliche Impulsantwort Filter anstatt zu betrachten Die FIR endlich i Mpulse-Response-Filter, den Sie jetzt verwenden Es gibt noch mehr, aber auf den ersten Blick sind FIR-Filter als explizite Windungen und IIR-Filter mit Gleichungen implementiert. Der spezielle IIR-Filter, den ich viel in Mikrocontrollern verwende, ist ein einpoliger Tiefpassfilter Digitales Äquivalent eines einfachen RC-Analog-Filters Für die meisten Anwendungen haben diese bessere Eigenschaften als der Box-Filter, den Sie verwenden Die meisten Verwendungen eines Box-Filters, die ich begegnet 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, die Sie wissen, sind Rauschen, ein einpoliger Tiefpassfilter ist besser Der beste Weg, um ein digital in einem Mikrocontroller zu implementieren ist in der Regel. FILT - FILT FF NEU - 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 wird FF ist die Filterfraktion, die die Schwere des Filters anpasst. Betrachten Sie diesen Algorithmus und sehen Sie, dass für FF 0 der Filter unendlich schwer ist, da sich der Ausgang niemals für FF 1 ändert. Es ist wirklich kein Filter, da der Ausgang gerade dem Eingang folgt Nützliche Werte sind dazwischen Auf kleinen Systemen wählst du FF auf 1 2 N, so dass die Multiplikation mit FF als Rechtsverschiebung durch N Bits erreicht werden kann. Beispielsweise könnte FF 1 16 sein und die Multiplikation mit FF also eine richtige Verschiebung von 4 Bits Andernfalls braucht dieser Filter nur einen Subtrakt und man fügt hinzu, obwohl die Zahlen in der Regel breiter sein müssen als der Eingabewert mehr auf die numerische Präzision in einem separaten Abschnitt unten. Ich nehme in der Regel AD-Messwerte deutlich schneller als sie benötigt werden und zwei davon anwenden Diese Filter kaskadiert Dies ist das digitale Äquivalent von zwei RC-Filtern in Serie und dämpft um 12 dB Oktave über der Rolloff-Frequenz. Für AD-Messungen ist es meist meist wichtiger, den Filter im Zeitbereich zu betrachten Erhebt seine Schrittantwort Dies sagt Ihnen, wie schnell Ihr System eine Veränderung sehen wird, wenn das, was Sie Messungen ändern. Zu erleichtern die Gestaltung dieser Filter, die nur bedeutet, FF zu wählen und zu entscheiden, wie viele von ihnen zu kaskaden, ich benutze mein Programm FILTBITS Sie spezifizieren die Anzahl der Verschiebungsbits für jede FF in der kaskadierten Filterreihe und berechnet die Sprungantwort und andere Werte. Eigentlich laufe ich das meist über mein Wrapperskript PLOTFILT Das läuft FILTBITS, das eine CSV-Datei macht und dann die CSV-Datei zeichnet , Hier ist das Ergebnis von PLOTFILT 4 4. Die beiden Parameter zu PLOTFILT bedeuten, dass es zwei Filter gibt, die von der oben beschriebenen Art kaskadiert sind. Die Werte von 4 geben die Anzahl der Verschiebungsbits an, um die Multiplikation mit FF zu realisieren. Die beiden FF-Werte sind also 1 16 in diesem Fall. Die rote Spur ist die Einheit Schritt Antwort, und ist die Hauptsache zu betrachten Zum Beispiel, dies sagt Ihnen, dass, wenn die Eingabe ändert sich sofort, wird die Ausgabe des kombinierten Filters auf 90 der neuen zu begleichen Wert in 60 Iterationen Wenn du ungefähr 95 Setzzeit kümmerst, musst du etwa 73 Iterationen warten und für 50 Einschwingzeit nur 26 Iterationen. Die grüne Trace zeigt dir die Ausgabe von einer einzigen Amplitude an. Dies gibt dir eine Vorstellung von dem 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 ist, um ein subjektives Gefühl von dem, was dieser Filter mit weißen Rauschen Dies ist kein strenger Test, da gibt es keine Garantie, was genau Der Inhalt war von den zufälligen Zahlen, die als der weiße Rauschen Eingang für diesen Lauf von PLOTFILT Es ist nur, um Ihnen ein grobes Gefühl, wie viel es zerquetscht werden und wie glatt es ist. FOTFILT, vielleicht FILTBITS, und viele andere nützliche Sachen, vor allem für PIC-Firmware-Entwicklung ist in der PIC Development Tools Software-Version auf meiner Software-Downloads-Seite verfügbar. Zusätzlich über numerische Präzision. I sehen aus den Kommentaren und jetzt eine neue Antwort, dass es Interesse an der Diskussion über t Die Anzahl der Bits, die für die Implementierung dieses Filters benötigt werden. Beachten Sie, dass die Multiplikation mit FF Log 2 FF neue Bits unterhalb des Binärpunktes erzeugt. Bei kleinen Systemen wird FF gewöhnlich 1 2 N gewählt, so dass diese Multiplikation tatsächlich durch eine Rechtsverschiebung realisiert wird Von N Bits. FILT ist also in der Regel eine feste Punkt-Ganzzahl. Beachten Sie, dass dies keine der Mathematik aus der Sicht des Prozessors ändert. Wenn Sie beispielsweise 10-Bit-AD-Werte und N 4 FF 1 16 filtern, dann benötigen Sie 4 Fraktionsbits unterhalb der 10-Bit-Integer-AD-Lesungen Einer der meisten Prozessoren, du machst 16-Bit-Integer-Operationen aufgrund der 10-Bit-AD-Messungen. In diesem Fall können Sie immer noch genau die gleichen 16-Bit-Integer-Oaksionen ausführen, aber mit dem AD beginnen Lesungen links verschoben um 4 Bits Der Prozessor kennt den Unterschied nicht und braucht nicht die Mathematik auf ganze 16-Bit-Ganzzahlen zu arbeiten, ob man sie als 12 4 Fixpunkt oder wahre 16-Bit-Ganzzahlen betrachtet 16 0 Fixpunkt. Sie müssen N Bits jeden Filterpol hinzufügen, wenn Sie Ich möchte kein Rauschen aufgrund der numerischen Darstellung hinzufügen. Im obigen Beispiel müsste der zweite Filter von zwei 10 4 4 18 Bits haben, um keine Informationen zu verlieren. In der Praxis auf einer 8-Bit-Maschine bedeutet das, dass Sie 24-Bit-Werte verwenden. Technisch Nur der zweite Pol von zwei würde den breiteren Wert brauchen, aber für die Firmware-Einfachheit verwende ich gewöhnlich dieselbe Darstellung und damit denselben Code für alle Pole eines Filters. Normalerweise schreibe ich eine Subroutine oder ein Makro, um einen Filterpolbetrieb auszuführen, Dann wenden Sie sich auf jeden Pol an Ob eine Unterroutine oder ein Makro davon abhängt, ob Zyklen oder Programmspeicher in diesem bestimmten Projekt wichtiger sind. Irgendwann benutze ich einen Kratzzustand, um NEU in das Subroutine-Makro zu übergeben, das FILT aktualisiert, aber auch das lädt Der gleiche Kratzer Zustand NEU war in Dies macht es einfach, mehrere Pole anzuwenden, da die aktualisierte FILT von einem Pole ist die NEUE der nächsten Wenn eine Subroutine, ist es sinnvoll, einen Zeiger Punkt auf FILT auf dem Weg in, was ist aktualisiert Um nur nach FILT auf dem Ausweg auf diese Weise die Subroutine automatisch auf aufeinanderfolgenden Filtern im Speicher, wenn mehrere Male mit einem Makro Sie don t brauchen einen Zeiger, da Sie in die Adresse, um auf jeder Iteration. Code Beispiele. Here ist ein Beispiel eines Makros wie oben für einen PIC 18 beschrieben. Und hier ist ein ähnliches Makro für ein PIC 24 oder dsPIC 30 oder 33.Bof diese Beispiele werden als Makros mit meinem PIC Assembler Preprozessor implementiert, die mehr fähig ist als eine der eingebauten, In Makroanlagen. Clabacchio Ein weiteres Problem, das ich erwähnt habe, ist die Firmware-Implementierung Sie können einmal ein einzelnes Pole-Tiefpass-Filter-Subroutine schreiben, dann wenden Sie es mehrmals an. In der Tat schreibe ich normalerweise eine solche Unterroutine, um einen Zeiger im Speicher auf den Filterzustand zu setzen Der Zeiger, so dass es nacheinander einfach aufgerufen werden kann, um mehrpolige Filter zu realisieren Olin Lathrop 20. April 12 um 15 03.1 Vielen Dank für Ihre Antworten - alle von ihnen habe ich beschlossen, diesen IIR Filter zu verwenden, aber dieser Filter wird nicht als verwendet Ein Standard-LowPass-Filter, da ich durchschnittliche Zählerwerte verwerten und sie vergleichen muss, um Änderungen in einer bestimmten Reichweite zu erkennen, da diese Werte von sehr unterschiedlichen Dimensionen abhängig von Hardware sind, wollte ich einen Durchschnitt nehmen, um auf diese Hardware reagieren zu können Spezifische Änderungen automatisch sensslen Mai 21 12 um 12 06.Wenn Sie mit der Beschränkung einer Macht von zwei Anzahl von Gegenständen zu durchschnittlich dh 2,4,8,16,32 etc leben können, dann kann die Kluft einfach und effizient auf einem getan werden Low-Performance-Mikro mit keiner dedizierten Divide, weil es als Bit-Shift getan werden kann Jeder Shift rechts ist eine Potenz von zwei zB. Die OP dachte, er hatte zwei Probleme, die Teilung in einem PIC16 und Speicher für seine Ring-Puffer Diese Antwort zeigt, dass die Teilung Ist nicht schwierig zugegebenermaßen adressiert es nicht das Speicherproblem, aber das SE-System erlaubt teilweise Antworten, und Benutzer können etwas von jeder Antwort für sich selbst nehmen oder sogar bearbeiten und kombinieren andere s Antworten Da einige der anderen Antworten eine Teilungsoperation erfordern, sie Sind ähnlich unvollständig, da sie nicht zeigen, wie man dies effizient auf einem PIC16 Martin Apr 20 12 um 13 01.Es gibt eine Antwort für eine echte gleitende durchschnittliche Filter aka Boxcar Filter mit weniger Speicherbedarf, wenn Sie don t mind downsampling It s Genannt ein kaskadierter Integrator-Kamm-Filter CIC Die Idee ist, dass Sie einen Integrator haben, den Sie Unterschiede über einen Zeitraum nehmen, und das Schlüssel speichersparende Gerät ist, dass durch Downsampling, müssen Sie nicht zu speichern Vorabend Ry Wert des Integrators Es kann mit dem folgenden Pseudocode implementiert werden. Ihre effektive gleitende durchschnittliche Länge ist decimationFactor stateize aber du musst nur um Zustandsmuster zu halten. Natürlich können Sie eine bessere Leistung erhalten, wenn Ihr stateize und decimationFactor Kräfte von 2 sind, so dass die Divisions - und Restbetreiber werden durch Verschiebungen und Masken ersetzt. Postscript Ich bin mit Olin einverstanden, dass man immer einfache IIR-Filter vor einem gleitenden Durchschnittsfilter betrachten sollte. Wenn Sie nicht brauchen, geben Sie die Frequenz-Nullen eines Boxcar-Filters, ein 1-polig Oder 2-polige Tiefpass-Filter wird wahrscheinlich gut funktionieren. Auf der anderen Seite, wenn Sie filtern für die Zwecke der Dezimierung unter einem High-Sample-Rate-Eingang und Mittelung es für den Einsatz durch einen Low-Rate-Prozess dann ein CIC-Filter Kann genau das sein, was du gerade suchst, vor allem, wenn du den Status 1 verwenden kannst und den Ringpuffer insgesamt mit nur einem vorherigen Integrator-Wert vermeiden kannst. Es gibt eine eingehende Analyse der Mathematik hinter der Verwendung der ersten Ord Er IIR-Filter, den Olin Lathrop bereits auf der Digital Signal Processing Stack Exchange beschrieben hat, enthält viele schöne Bilder Die Gleichung für diesen IIR-Filter ist. Dies kann mit nur ganzzahlen implementiert werden und keine Division mit dem folgenden Code könnte einige Debugging wie ich benötigen Wurde aus dem Speicher eingegeben. Dieser Filter nähert sich einem gleitenden Durchschnitt der letzten K-Samples, indem er den Wert von alpha auf 1 K setzt. Führen Sie dies im vorhergehenden Code durch, indem Sie BITS auf LOG2 K definieren, dh für K 16 gesetzt BITS bis 4, für K 4 set BITS auf 2, etc. Ich überprüfe den hier aufgeführten Code, sobald ich eine Änderung bekomme und diese Antwort editiere, wenn nötig. derwered Jun 23 12 am 4 04.Hier ein einpoliger Tiefpassfilter gleitender Durchschnitt, mit Cutoff-Frequenz CutoffFrequency Sehr einfach, sehr schnell, funktioniert super und fast kein Speicher Overhead. Hinweis Alle Variablen haben Umfang über die Filterfunktion hinaus, außer der übergeben in newInput. Note Dies ist ein einstufiges Filter Mehrere Stufen können zusammen kaskadiert werden, um die zu erhöhen Schärfe von Der Filter Wenn du mehr als eine Stufe brauchst, musst du DecayFactor anpassen, bezogen auf die Cutoff-Frequenz, um zu kompensieren. Und offensichtlich alles was du brauchst ist die beiden Linien irgendwo platziert, sie brauchen nicht ihre eigene Funktion Dieser Filter hat eine Rampenzeit, bevor der gleitende Durchschnitt das 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. CutoffFrequenz SampleRate hat einen Bereich zwischen 0 und 0 5 DecayFactor ist ein Wert zwischen 0 und 1, in der Regel in der Nähe von 1.Single-Präzision Schwimmer sind gut genug für die meisten Dinge, ich bevorzuge einfach doppelt Wenn Sie mit Integers bleiben müssen, können Sie Konvertieren DecayFactor und Amplitude Factor in gebrochene Ganzzahlen, in denen der Zähler als Ganzzahl gespeichert wird, und der Nenner ist eine ganzzahlige Potenz von 2, so dass Sie sich nach rechts als Nenner bitten können, anstatt sich während der Filterschleife zu teilen Beispiel, wenn DecayFactor 0 99, und du willst ganze Zahlen verwenden, kannst du DecayFactor setzen 0 99 65536 64881 Und dann, wenn du dich von DecayFactor in deiner Filterschleife vermehrst, verschiebe einfach das Ergebnis 16.Für weitere Informationen dazu ein exzellentes Buch S online, Kapitel 19 auf rekursive filters. PS Für das Moving Average Paradigma, ein anderer Ansatz zur Einstellung DecayFactor und AmplitudeFactor, die möglicherweise mehr relevant für Ihre Bedürfnisse, lassen Sie uns sagen, Sie wollen die vorherigen, etwa 6 Artikel gemittelt tog Äther, tut es diskret, du fügst 6 Gegenstände und teile mit 6, so dass du den AmplitudeFactor auf 1 6 einstellen kannst und DecayFactor auf 1 0 - AmplitudeFactor. answered am 14. Mai 12 um 22 55. Jeder andere hat sich kommentiert Von IIR vs FIR, und auf Power-of-Two-Division Ich möchte nur einige Implementierungsdetails geben Die unten funktioniert gut auf kleine Mikrocontroller ohne FPU Es gibt keine Multiplikation, und wenn Sie N eine Macht von zwei halten, die ganze Division Ist Single-Cycle-Bit-Shifting. Basis FIR Ring Puffer halten einen laufenden Puffer der letzten N Werte und eine laufende SUM aller Werte im Puffer Jedes Mal, wenn ein neues Sample kommt, subtrahieren Sie den ältesten Wert im Puffer von SUM , Ersetzen Sie es mit dem neuen Sample, fügen Sie das neue Sample zu SUM hinzu und geben Sie SUM N. Modifizierter IIR Ringpuffer ein, um einen laufenden SUM der letzten N Werte zu halten. Jedes Mal, wenn ein neues Sample kommt, SUM - SUM N, fügen Sie das neue hinzu Probe und Ausgabe SUM N. answered Aug 28 13 bei 13 45. Wenn ich dich richtig lese, beschreibst du einen ersten Auftrag IIR Filter der Wert, den Sie subtrahieren isn t der älteste Wert, der ausfällt, sondern ist stattdessen der Durchschnitt der vorherigen Werte 1. Ordnung IIR-Filter können sicherlich nützlich sein, aber ich bin nicht sicher, was Sie meinen, wenn Sie vorschlagen, dass die Ausgabe Ist für alle periodischen Signale gleich. Bei einer Abtastrate von 10 kHz liefert die Zuführung einer 100 Hz-Rechteckwelle in einen 20-stufigen Kastenfilter ein Signal, das für 20 Proben gleichmäßig ansteigt, für 30 sitzt, für 20 Proben gleichmäßig sinkt und sitzt Für 30 A erster Ordnung IIR-Filter-Supercat Aug 28 13 bei 15 31. wird eine Welle ergeben, die scharf ansteigt und allmählich in der Nähe, aber nicht am Eingangsmaximum abfällt, dann fällt scharf an und fällt allmählich nahe, aber nicht am Eingang Minimum Sehr unterschiedliches Verhalten Supercat Aug 28 13 bei 15 32.Ein Problem ist, dass ein einfacher gleitender Durchschnitt kann oder nicht nützlich sein Mit einem IIR-Filter können Sie einen schönen Filter mit relativ wenigen Berechnungen Die FIR Sie beschreiben können nur Ihnen ein Rechteck in der Zeit - ein Sinc in Freq - und du kannst die Seitenlappen nicht verwalten. Es lohnt sich, ein paar Integer-Multiplikatoren zu werfen, um es zu einem schönen symmetrischen, abstimmbaren FIR zu machen, wenn du die Uhr tickt kannst. Scott Seidman 29. August 13 um 13 50. ScottSeidman No Notwendigkeit für Multiplikationen, wenn man einfach jede Stufe der FIR entweder den Mittelwert der Eingabe zu dieser Stufe und ihren vorherigen gespeicherten Wert ausgibt und dann die Eingabe speichert, wenn man den numerischen Bereich hat, könnte man die Summe anstatt den Durchschnitt verwenden S besser als ein Kastenfilter hängt von der Anwendung die Schrittantwort eines Kastenfilters mit einer Gesamtverzögerung von 1ms, zum Beispiel, hat eine böse d2 dt Spike, wenn die Eingabe ändern, und wieder 1ms später, aber hat das Minimum möglich D dt für einen Filter mit einer totalen 1ms Verzögerung supercat Aug 29 13 bei 15 25.As mikeselectricstuff sagte, wenn Sie wirklich brauchen, um Ihren Speicherbedarf zu reduzieren, und Sie don t mind Ihre Impulsantwort ist ein exponentieller statt eines rechteckigen Pulses, ich Würde für eine exponentielle bewegte ave gehen Wut-Filter Ich benutze sie ausgiebig Mit dieser Art von Filter, müssen Sie nicht brauchen Puffer Sie don t haben, um N Vergangenheit Proben Nur ein So, Ihre Speicheranforderungen werden durch einen Faktor von N. Also, Sie don t brauchen keine Division for that Nur Multiplikationen Wenn Sie Zugriff auf Gleitkomma-Arithmetik haben, verwenden Sie Gleitkomma-Multiplikationen Andernfalls machen Sie ganzzahlige Multiplikationen und Verschiebungen nach rechts. Wir sind jedoch 2012 und ich würde Ihnen empfehlen, Compiler und MCUs zu verwenden, die Ihnen erlauben Um mit Gleitkommazahlen zu arbeiten. Besides, die mehr Speicher effizienter und schneller Sie don t haben, um Elemente in jedem kreisförmigen Puffer zu aktualisieren, würde ich sagen, dass es auch natürlicher ist, weil eine exponentielle Impulsantwort besser ist, wie die Natur sich verhält, in den meisten Fällen. Erweiterte Apr 20 12 bei 9 59. Ein Problem mit dem IIR-Filter, der fast von Olin und Supercat berührt wurde, aber anscheinend von anderen nicht beachtet wurde, ist, dass die Abrundung eine Ungenauigkeit und eine potenziell vorschneidende Verkürzung einführt, vorausgesetzt, dass N i Eine Macht von zwei, und nur ganzzahlige Arithmetik verwendet wird, das Verschiebungsrecht testet systematisch die LSBs der neuen Probe Das bedeutet, dass, wie lange die Serie jemals sein könnte, wird der Durchschnitt niemals diese berücksichtigen. Zum Beispiel, nehmen Sie langsam an Abnehmende Serie 8,8,8 8,7,7,7 7,6,6, und nehmen Sie den Durchschnitt ist in der Tat 8 am Anfang Die erste 7 Probe wird den Durchschnitt auf 7 bringen, was auch immer die Filterstärke Nur für eine Probe Gleiche Geschichte für 6, etc Jetzt denken Sie an das Gegenteil die Serie geht nach oben Der Durchschnitt wird auf 7 für immer bleiben, bis die Probe groß genug ist, um es zu ändern. Natürlich können Sie für die Bias durch Hinzufügen von 1 2 N 2, aber korrigieren Das gewann t wirklich lösen das Präzisionsproblem in diesem Fall die abnehmende Serie bleibt für immer bei 8, bis die Probe 8-1 2 N 2 Für N 4 zum Beispiel, jede Probe über Null wird den Durchschnitt unverändert halten. Ich glaube, eine Lösung für Das würde bedeuten, einen Akkumulator der verlorenen LSBs zu halten Aber ich habe es nicht weit genug gemacht, um Code bereit zu haben, Und ich bin mir nicht sicher, dass es nicht schaden würde die IIR Macht in einigen anderen Fällen von Serien zum Beispiel, ob 7,9,7,9 würde durchschnittlich 8 dann. Olin, deine zweistufige Kaskade braucht auch eine Erklärung zu haben. Du meinst, dass du durchschnittlich durchschnittlich mit dem Ergebnis der ersten in die zweite in jeder Iteration gefüttert hast.


No comments:

Post a Comment