Friday, 14 April 2017

Moving Average C Code

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 Ausgang und die aktuelle input. but dies ist nicht ein Standard ungewichtet gleitenden Durchschnitt, sondern ein exponentiell gewichtet gleitenden Durchschnitt, wo Proben weiter in der Vergangenheit erhalten ein kleineres Gewicht, aber zumindest in der Theorie Sie nie vergessen, die Gewichte Nur kleiner und kleiner für Proben weit in der Vergangenheit. Ich habe einen gleitenden Durchschnitt ohne individuellen Element 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 sich mit 2 auf die aktuelle avg. Dies geht weiter, bis ich auf die Länge des durchschnittlichen. Jede Zeit später, füge ich in die neue Probe, bekomm den Durchschnitt und entfernen Sie diesen Durchschnitt aus der total. Ich bin kein Mathematiker aber das Schien wie ein guter Weg, um es zu tun Ich dachte, es würde den Magen eines echten Mathe-Kerl drehen, aber es stellt sich heraus, es ist eine der akzeptierten Möglichkeiten, es zu tun Und es funktioniert gut Nur daran erinnern, dass je höher Ihre Länge, je langsamer es ist Nach dem, was du dir folgen möchtest, das kann die meiste Zeit nicht ausmachen, aber wenn du Satelliten verfolgst, wenn du langsam bist, könnte der Weg weit von der tatsächlichen Position entfernt sein und es wird schlecht aussehen Du könntest eine Lücke zwischen dem Sat und den hinteren Punkten haben Ich wählte eine Länge von 15 aktualisiert 6 mal pro Minute, um ausreichende 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 insgesamt 0, zählen 0 jedes Mal sehen ein neues Value. Then eine Eingabe scanf, man add add total newValue, eine Inkrementzählung, eine geteilte durchschnittliche Gesamtzählung. Dies wäre ein gleitender Durchschnitt über allen inputs. To, um den Durchschnitt über nur die letzten 4 Eingänge zu berechnen, würde 4 Eingabevariablen erfordern, vielleicht kopieren Jeder Eingang zu einem älteren Eingang variabel, dann die Berechnung der neuen gleitenden Durchschnitt als Summe der 4 inputvariables, geteilt durch 4 richtige Verschiebung 2 wäre gut, wenn alle Eingänge waren positiv, um die durchschnittliche Berechnung. Erwerben 3. Februar 15 um 4 06.That Wird tatsächlich den Gesamtdurchschnitt berechnen und NICHT der gleitende Durchschnitt Wenn der Zählwert größer wird, wird der Einfluss einer neuen Eingabeprobe verschwindend klein Hilmar 3. Februar 15 um 13 53. Ihre Antwort.2017 Stack Exchange, Inc. Ich weiß, dass dies mit Boost erreichbar ist Per. But aber ich möchte wirklich vermeiden, Boost Ich habe gegoogelt und nicht gefunden, alle geeigneten oder lesbaren Beispiele. Basically Ich möchte den gleitenden Durchschnitt eines laufenden Streams von einem Strom von Gleitkommazahlen mit den neuesten 1000 Zahlen als Datenprobe. Was ist der einfachste Weg, dies zu erreichen. Ich experimentierte mit der Verwendung eines kreisförmigen Arrays, exponentiell gleitenden Durchschnitt und ein einfacher gleitender Durchschnitt und festgestellt, dass die Ergebnisse aus dem kreisförmigen Array zu meinen Bedürfnissen am besten gemacht wurde 12. Juni 12 bei 4 38.Wenn Ihre Bedürfnisse einfach sind, können Sie einfach versuchen, einen exponentiellen gleitenden Durchschnitt zu verwenden. Einfach nur, Sie machen 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 Ist zwischen 0 und 1, und berechnen dies. Sie müssen nur einen Wert von Alpha, wo die Wirkung einer bestimmten Probe nur für etwa 1000 Proben. Hmm dauern, ich bin nicht wirklich sicher, dass dies für Sie geeignet ist, jetzt, dass ich ve Setzen Sie es hier Das Problem ist, dass 1000 ein ziemlich langes Fenster für einen exponentiellen gleitenden Durchschnitt ist 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 wollte Durchschnitt, wie 30 Zahlen oder so, das ist eine sehr einfache und schnelle Art und Weise zu tun it. answered Jun 12 12 bei 4 44. 1 auf deinem Post Der exponentielle gleitende Durchschnitt kann das Alpha variabel sein. So läßt dies auch verwendet werden Berechnen von Zeitbasis-Mittelwerten zB Bytes pro Sekunde Wenn die Zeit seit dem letzten Akkumulator-Update mehr als 1 Sekunde beträgt, lassen Sie alpha 1 1 sein. Andernfalls können Sie alpha be usecs seit letzter Aktualisierung 1000000 jxh Jun 12 12 at 6 21.Basically I Wollen den gleitenden Durchschnitt eines laufenden Stroms eines Stroms von Gleitkommazahlen mit den neuesten 1000 Zahlen als Datenbeispiel verfolgen. Hinweis, dass die unten die Gesamtsumme als Elemente als addiert ersetzt, vermeidet kostspielige ON-Traversal, um die Summe zu berechnen, Benötigt für den Durchschnitt - auf Nachfrage. Total ist ein anderer Parameter von T zu unterstützen, z. B. mit einer langen langen, wenn insgesamt 1000 lange s, ein int für char s oder ein doppeltes zu total float s. This ist ein bisschen fehlerhaft in diesem Numsamples könnten an INTMAX vorbeikommen - wenn Sie sich vorstellen können, dass Sie eine vorzeichenlose lange lange benutzen oder ein zusätzliches bool Datenelement verwenden können, um aufzuzeichnen, wann der Container zum ersten Mal gefüllt wird, während Sie Numsamples um das Array herumfahren, dann umbenannt etwas Unschuldiges wie pos. answered Jun 12 12 at 5 19.in nehme an, dass void Operator T Probe tatsächlich void Operator T Probe oPless Jun 8 14 bei 11 52. oPless ahhh gut gefleckt eigentlich ich bedeutete dafür, dass es void Betreiber T Probe, aber natürlich könnten Sie verwenden, was Notation Sie mochten Will Fix, danke Tony D Jun 8 14 bei 14 27.Als andere haben erwähnt, sollten Sie ein IIR unendlichen Impulsantwort-Filter anstatt der FIR endlichen Impulsantwort-Filter, den Sie jetzt verwenden Es gibt mehr zu, aber auf den ersten Blick FIR-Filter Sind als explizite Windungen und IIR-Filter mit Gleichungen implementiert. Der besondere IIR-Filter Ich benutze viel in Mikrocontroller ist ein einpoliger Tiefpass-Filter Dies ist das digitale Äquivalent eines einfachen RC-Analog-Filter Für die meisten Anwendungen haben diese bessere Eigenschaften als die Box-Filter, den Sie verwenden Die meisten Anwendungen 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, die Sie wissen, abzuschwächen 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 berechnen müssen Dieser Filter 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 die Ausgabe niemals für FF ändert 1, es ist eigentlich 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 rechte Verschiebung durch N Bits erreicht werden kann , FF könnte 1 16 sein und die Multiplikation mit FF also eine rechte Verschiebung von 4 Bits Andernfalls benötigt dieser Filter nur einen Subtrakt und man fügt hinzu, obwohl die Zahlen in der Regel breiter als der Eingangswert mehr auf numerische Genauigkeit in einem separaten Abschnitt unten sein müssen. Ich nehme in der Regel AD-Messungen deutlich schneller als sie benötigt werden und wenden Sie zwei dieser Filter kaskadiert Dies ist das digitale Äquivalent von zwei RC-Filter in Serie und dämpft um 12 dB Oktave über die Rolloff-Frequenz Aber für AD-Messungen ist es meist mehr Relevant, um den Filter im Zeitbereich zu betrachten, indem man seine Stufenreaktion betrachtet. Dies sagt dir, wie schnell dein System eine Veränderung sehen wird, wenn das, was du misst, um Änderungen zu erleichtern. Um die Gestaltung dieser Filter zu erleichtern, bedeutet das nur die Auswahl von FF und die Entscheidung, wieviele von ihnen Kaskade, ich verwende mein Programm FILTBITS Sie geben die Anzahl der Verschiebungsbits für jede FF in der kaskadierten Filterreihe an und es berechnet die Sprungantwort und andere Werte. Eigentlich laufe ich das meist über mein Wrapperskript PLOTFILT Das läuft FILTBITS Eine CSV-Datei, dann zeichnet die CSV-Datei zum Beispiel 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 zu überwachenden Schaltbits an Die Multifunktion von FF Die beiden FF-Werte sind also in diesem Fall 1 16. Die rote Spur ist die Einheitsreaktion, und ist die Hauptsache, zum Beispiel zu betrachten. Dies sagt Ihnen, dass, wenn sich die Eingabe sofort ändert, die Ausgabe der Kombinierter Filter wird bei 60 Iterationen auf 90 des neuen Wertes abrechnen Wenn Sie etwa 95 Einschwingzeit betreuen, dann müssen Sie auf 73 Iterationen warten und für 50 Einschwingzeit nur 26 Iterationen. Die grüne Spur zeigt Ihnen die Ausgabe von einer einzigen vollen Amplitude Spike 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 ist, um ein subjektives Gefühl von dem, was dieser Filter mit weißen Rauschen zu tun Dies ist nicht ein Rigoroser Test, da es keine Garantie gibt, was genau der Inhalt von den zufälligen Zahlen war, 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. PLOTFILT , Vielleicht FILTBITS, und viele andere nützliche Sachen, vor allem für PIC-Firmware-Entwicklung ist in der PIC-Entwicklungstools Software-Release 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 gibt Bei der Erörterung der Anzahl der Bits, die für die Implementierung dieses Filters erforderlich sind. Beachten Sie, dass die Multiplikation mit FF log 2 FF neue Bits unterhalb des Binärpunktes erzeugt. Bei kleinen Systemen wird FF gewöhnlich als 1 2 N gewählt, so dass diese Multiplikation tatsächlich durch a realisiert wird Rechtsverschiebung von N Bits. FILT ist also meist eine Fixpunkt-Ganzzahl. Beachten Sie, dass dies keine Mathematik aus der Sicht des Prozessors ändert. Wenn Sie z. B. 10-Bit-AD-Werte und N 4 FF 1 16 filtern, dann Du brauchst 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 kannst du immer noch genau die gleichen 16-Bit-Integer-Optionen machen, aber mit dem anfangen Die AD-Lesungen links um 4 Bits verschoben 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 fester Punkt Allgemeines müssen Sie N Bits jeden Filterpol hinzufügen, wenn Sie nicht möchten, dass Rauschen aufgrund der numerischen Darstellung hinzuzufü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 Eine 8-Bit-Maschine, dh Sie verwenden 24-Bit-Werte Technisch nur der zweite Pol von zwei würde den größeren Wert benötigen, aber für Firmware Einfachheit verwende ich in der Regel die gleiche Darstellung und damit den gleichen Code für alle Pole eines Filters Ich schreibe eine Unterroutine oder ein Makro, um einen Filterpole-Vorgang auszuführen, dann wende das auf jeden Pol an Ob eine Subroutine oder ein Makro davon abhängt, ob Zyklen oder Programmspeicher in diesem bestimmten Projekt wichtiger sind. Irgendwann benutze ich einen Kratzzustand, Das Subroutine-Makro, das FILT aktualisiert, aber auch das in denselben Scratch-Status lädt. NEU war in Dies macht es einfach, mehrere Pole anzuwenden, da die aktualisierte FILT von einem Pole die NEU des nächsten ist. Wenn eine Unterroutine es nützlich ist Habe einen Zeiger auf FILT auf dem Weg in, die aktualisiert wird, um nur nach FILT auf dem Ausweg auf diese Weise die Subroutine automatisch arbeitet auf aufeinanderfolgenden Filtern im Speicher, wenn mehrere Male genannt Mit einem Makro Sie don t brauchen einen Zeiger, da Sie passieren Die Adresse für jede Iteration zu betreiben. Code Beispiele. Hier ist ein Beispiel für ein Makro wie oben für ein PIC 18.Und hier ist ein ähnliches Makro für ein PIC 24 oder dsPIC 30 oder 33.Beide diese Beispiele sind als Makros mit implementiert Mein PIC-Assembler-Präprozessor, der mehr fähig ist als die eingebauten 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 speichersparendes Gerät ist, dass durch Downsampling, Sie don t müssen jeden Wert des Integrators speichern Kann mit dem folgenden Pseudocode implementiert werden. Ihre effektive gleitende durchschnittliche Länge ist decimationFactor stateize aber du musst nur um Zustandsmuster zu halten. Offensichtlich kannst du eine bessere Leistung erzielen, wenn dein Status und DecimationFactor Kräfte von 2 sind, so dass die Division und Restbetreiber ersetzt werden Durch verschiebungen und mask-ands. Postscript Ich bin mit Olin einverstanden, dass man immer einfache IIR-Filter vor einem gleitenden durchschnittlichen Filter betrachten sollte Wenn Sie nicht brauchen die Frequenz-Null von einem Boxcar-Filter, eine 1-polige oder 2-polige Low - Pass-Filter wird wahrscheinlich gut funktionieren. Auf der anderen Seite, wenn Sie filtern für die Zwecke der Dezimierung unter einem High-Sample-Rate-Input und Mittelung es für den Einsatz durch einen Low-Rate-Prozess dann ein CIC-Filter kann genau das, was Sie re Vor allem, wenn Sie stateize 1 verwenden können und vermeiden Sie den Ringbuffer insgesamt mit nur einem einzigen vorherigen Integrator Wert. Es gibt eine eingehende Analyse der Mathematik hinter mit dem ersten Auftrag IIR-Filter, die Olin Lathrop bereits über das digitale Signal beschrieben hat Die Verarbeitung von Stack-Austausch umfasst viele schöne Bilder Die Gleichung für diese IIR-Filter ist. Dies kann mit nur Integers implementiert werden und keine Teilung mit dem folgenden Code könnte einige Debugging, wie ich aus dem Speicher war. This Filter nähert sich ein gleitender Durchschnitt der letzten K-Samples durch Setzen des Wertes von alpha auf 1 K 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 gesetzt BITS bis 2, etc. I ll überprüfen den Code aufgeführt Hier, 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 CutoffFrequenz Sehr einfach, sehr schnell, funktioniert super und fast Kein Speicher overhead. Note Alle Variablen haben Umfang über die Filterfunktion hinaus, außer dass in newInput. Note passiert ist. Dies ist ein einstufiges Filter Mehrere Stufen können zusammenkaskadiert werden, um die Schärfe des Filters zu erhöhen Wenn Sie mehr als eine Stufe verwenden, werden Sie ll Müssen DecayFactor anpassen, bezogen auf die Cutoff-Frequenz, um zu kompensieren. Und offensichtlich alles, was Sie brauchen, ist die beiden Linien platziert irgendwo, sie don t brauchen ihre eigene Funktion Dieser Filter hat eine Ramp-up-Zeit vor dem gleitenden Durchschnitt repräsentiert die der Eingangssignal 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 filter. 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, sagen wir, Sie wollen die vorherigen, etwa 6 Artikel gemittelt zusammen, tun es diskret , Du fügst 6 Gegenstände hinzu und teile mit 6, so dass du den AmplitudeFactor auf 1 6 setzen kannst und DecayFactor auf 1 0 - AmplitudeFactor. answered am 14. Mai 12 um 22 55. Jeder andere hat sich kommentiert über den Nutzen 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 behalten, ist die ganze Teilung Single-Cycle-Bit - shifting. Basic FIR Ringpuffer halten einen laufenden Puffer der letzten N Werte und eine laufende SUM aller Werte im Puffer Jedes Mal, wenn ein neues Sample hereinkommt, subtrahiere den ältesten Wert im Puffer von SUM, ersetze ihn mit dem Neues Sample, fügt das neue Sample zu SUM hinzu und gibt SUM N aus. Modifizierter IIR Ringpuffer behält einen laufenden SUM der letzten N Werte Jedes Mal, wenn ein neues Sample kommt, SUM - SUM N, fügen Sie das neue Sample hinzu und geben Sie SUM aus N. answered Aug 28 13 at 13 45.Wenn ich dich richtig richtig lese, beschreibst du einen IIR-Filter erster Ordnung, den Wert, den du subtrahierst, ist nicht der älteste Wert, der herausfällt, sondern stattdessen der Durchschnitt der vorherigen Werte ist Erste-Ordnung-IIR-Filter können sicherlich nützlich sein, aber ich bin mir nicht sicher, was du meinst, wenn du vorschreibst, dass die Ausgabe für alle periodischen Signale gleich ist. Bei einer 10KHz-Abtastrate wird eine 100Hz-Rechteckwelle in einen 20-stufigen Boxfilter geleitet Ergibt ein Signal, das für 20 Abtastungen gleichmäßig ansteigt, für 30 sitzt, für 20 Proben gleichmäßig abfällt und für 30 A für den ersten A-IIR-Filter-Supercat am 28. August bei 15 31 niedrig sitzt. Es wird eine Welle ergeben, die scharf ansteigt und allmählich ansteigt Levels in der Nähe, aber nicht am Eingangsmaximum, dann fängt man scharf an und schreitet allmählich aus, 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 kannst du einen schönen Filter mit relativ wenigen Berechnungen bekommen. Die FIR, die du beschreibst, kann dir nur ein Rechteck geben - ein sinc in freq - und du kannst die Seitenlappen nicht verwalten. Es lohnt sich auch Werfen in ein paar Integer Multiplikationen, um es eine schöne symmetrische abstimmbare FIR, wenn Sie die Uhr ticks Scott Seidman Aug 29 13 bei 13 50. ScottSeidman Keine Notwendigkeit für Multiplikationen, wenn man einfach jede Stufe der FIR entweder die Ausgabe der Durchschnitt der Eingabe in diesem Stadium und seinen vorherigen gespeicherten Wert, und dann speichern Sie die Eingabe, wenn man den numerischen Bereich hat, könnte man die Summe anstelle von Durchschnitt verwenden Ob das besser als ein Kastenfilter hängt von der Anwendung die Schrittantwort eines Kastenfilters mit Eine Gesamtverzögerung von 1ms, zum Beispiel, wird eine böse d2 dt Spike haben, wenn die Eingabe ändern, und wieder 1ms später, aber haben die minimale d dt für einen Filter mit einer Gesamtmenge von 1ms Verzögerung supercat Aug 29 13 bei 15 25. Wie mikeselectricstuff sagte, wenn Sie wirklich brauchen, um Ihre Gedächtnisbedürfnisse zu reduzieren, und Sie don t mind Ihre Impulsantwort ein exponentieller statt eines rechteckigen Pulses, würde ich für einen exponentiellen gleitenden durchschnittlichen Filter Ich benutze sie ausgiebig Mit dieser Art von Filter, Du brauchst keinen Puffer Du musst nicht n hintere Samples speichern Nur ein So, deine Speicheranforderungen werden durch einen Faktor von N abgeschnitten. Auch du brauchst keine Division für das Nur Multiplikationen Wenn du Zugriff auf Floating - Punkt-Arithmetik, verwenden Sie Gleitkomma-Multiplikationen Andernfalls tun Sie ganzzahlige Multiplikationen und Verschiebungen nach rechts Allerdings sind wir im Jahr 2012, und ich würde Ihnen empfehlen, Compiler und MCUs zu verwenden, die Ihnen erlauben, mit Gleitkommazahlen zu arbeiten. Besides ist mehr Speicher Effizient und schneller Sie don t haben, um Elemente in jedem kreisförmigen Puffer zu aktualisieren, würde ich sagen, es ist auch natürlicher, weil eine exponentielle Impulsantwort besser ist die Art und Weise die Natur verhält sich in den meisten Fällen. answered Apr 20 12 bei 9 59.Ein Problem mit Der IIR-Filter, der fast von Olin und Supercat berührt wird, aber anscheinend von anderen nicht beachtet wird, ist, dass die Abrundung eine Ungenauigkeit und eine potenzielle Bias-Trunkierung einnimmt, vorausgesetzt, dass N eine Potenz von zwei ist und nur eine ganzzahlige Arithmetik verwendet wird, das Verschiebungsrecht systematisch eliminiert 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 wir eine langsam abnehmende Serie 8,8,8 8,7,7,7 7,6,6 an , Und nehmen Sie den Durchschnitt ist in der Tat 8 am Anfang Die Faust 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, das Gegenteil der Serie geht nach oben Der Durchschnitt wird bleiben auf 7 für immer, 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 korrigieren, aber das gewann t wirklich lösen das Präzisionsproblem in diesem Fall die abnehmende Serie wird für immer bei 8 bleiben Bis die Probe 8-1 2 N 2 ist Für N 4 zum Beispiel wird jede Probe über Null 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 bis 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