Sunday, October 9, 2016

Beweglicher Mikrocontroller

Intro Eine der Hauptanwendungen für das Arduino-Board ist das Lesen und Protokollieren von Sensordaten. Zum Beispiel überwacht man den Druck jede Sekunde des Tages. Da hohe Abtastraten oft Spikes in den Graphen erzeugen, möchte man auch einen Mittelwert der Messungen haben. Da die Messungen nicht statisch in der Zeit sind, was wir oft brauchen, ist ein laufender Durchschnitt. Dies ist der Durchschnitt einer bestimmten Periode und sehr wertvoll bei der Trendanalyse. Die einfachste Form eines laufenden Durchmessers kann durch einen Code ausgeführt werden, der auf dem vorherigen laufenden Durchschnitt basiert: Wenn man keine Gleitkomma-Mathematik verwenden möchte - da dies Speicherplatz einnimmt und Geschwindigkeit verringert - kann man dies in der Integer-Domäne vollständig durchführen. Die Teilung durch 256 in dem Beispielcode ist ein Schiebe-Recht 8, das schneller ist als eine Teilung durch z. B. 100. Dies gilt für jede Potenz von 2 als Teiler und man muss nur darauf achten, dass die Summe der Gewichte gleich der Potenz von 2 ist. Und natürlich sollte man darauf achten, dass es keinen Zwischenüberlauf gibt (erwägen Sie unsigned long) Eine genauere laufende Durchschnitt, in concreto aus den letzten 10 Messungen, benötigen Sie ein Array (oder verkettete Liste), um sie zu halten. Diese Anordnung wirkt wie ein kreisförmiger Puffer und bei jeder neuen Messung wird die älteste entfernt. Der laufende Durchschnitt wird als die Summe aller Elemente geteilt durch die Anzahl der Elemente in dem Array berechnet. Der Code für den laufenden Durchschnitt wird etwa so aussehen: Nachteil dieses Codes ist, dass das Array, um alle Werte zu halten, ziemlich groß werden kann. Wenn Sie eine Messung pro Sekunde haben und Sie wollen einen laufenden Durchschnitt pro Minute benötigen Sie ein Array von 60 ein durchschnittliches pro Stunde würde ein Array von 3600 benötigen. Das könnte nicht auf diese Weise auf einem Arduino getan werden, da es nur 2K RAM hat. Allerdings kann durch den Bau eines 2-stufigen Durchschnitts kann es ganz gut angegangen werden (Disclaimer: nicht für alle Messungen). Im psuedo-Code: Da für jede runningAverage-Funktion ein neues internes statisches Array benötigt wird, wird dieses als Klasse implementiert. RunningAverage-Bibliothek Die RunningAverage-Bibliothek bildet eine Klasse der oben genannten Funktion, so dass sie mehrfach in einer Skizze verwendet werden kann. Es entkoppelt die add () - und die avg () - Funktion, um ein wenig flexibler zu sein, z. B. Kann man den Durchschnitt mehrmals nennen, ohne eine Sache hinzuzufügen. Beachten Sie, dass jede Instanz der Klasse ein eigenes Array hinzufügt, um Messungen zu halten, und dass dies die Speicherauslastung addiert. Die Schnittstelle der Klasse wird so klein wie möglich gehalten. Anmerkung: Bei Version 0.2 werden die Namen der Methoden beschreibender. Verwendung Eine kleine Skizze zeigt, wie sie verwendet werden kann. Ein Zufallsgenerator wird verwendet, um einen Sensor nachzuahmen. In setup () wird der myRA gelöscht, so dass wir mit dem Hinzufügen neuer Daten beginnen können. In loop () wird zuerst eine Zufallszahl erzeugt und in einen float umgerechnet, der myRA hinzugefügt wird. Dann wird das runningAverage auf den seriellen Port gedruckt. Man könnte es auch auf einem LCD-Display oder über ethernet etc. Wenn 300 Elemente hinzugefügt myRA ist gelöscht, um neu zu beginnen. Hinweise Um die Bibliothek zu verwenden, müssen Sie einen Ordner in Ihrem SKETCHBOOKPATHlibaries mit dem Namen RunningAverage erstellen und dort die. h - und die. cpp-Datei ablegen. Fügen Sie optional ein Beispielunterverzeichnis hinzu, um die Beispielanwendung zu platzieren. Geschichte 2011-01-30: Anfangsversion 2011-02-28: fester fehlender Zerstörer in der. h Akte 2011-02-28: entfernter Standardkonstruktor 2012--. TrimValue () Yuval Naveh hinzugefügt trimValue (gefunden im Web) 2012-11-21: refactored 2012-12-30: hinzugefügt fillValue () refactored für die Veröffentlichung 2014-07-03: hinzugefügt Speicherschutz-Code - wenn internen Array nicht zugeordnet werden kann Größe Wird 0. Dies ist, um das hier beschriebene Problem zu lösen - forum. arduino. cc/indextopic50473.msg1790086msg1790086 - Todo Test ausführlich. Template-Klasse RunningAverage. h RunningAverage. cppAs andere haben erwähnt, sollten Sie einen IIR (endlose Impulsantwort) - Filter anstatt der FIR (Finite Impulse Response) Filter, die Sie jetzt verwenden. 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 dieser LED LYT Meter: LED, PIC Microcontroller und Moving Average Code Hallo an alle, danke für die Überprüfung meiner ersten Instructable. Ich genieße, Ihre Kreationen über den Jahren zu sehen und zu lieben, was alle von Ihnen beitragen. Dieses Projekt ist ein Spin von einem, das ich vor kurzem hier gesehen habe und ich brauche, um einen Schrei zu Bot1398 zu geben, weil er mir in seinem Instructable gezeigt hat, dass man eine LED benutzen könnte, um Veränderungen in der Lichtintensität in der Umgebung zu erkennen und diese zu verwenden Eine andere LED ein - oder ausschalten. Ich wusste, dass, wenn Sie ein wenig Leistung zu einer LED geliefert würde es Licht ausgeben würde. Ich hätte nie gedacht, es könnte umgekehrt verwendet werden. Nachdem ich seine Instructable: Light Sensing LEDs gesehen habe, war es sinnvoll, aber ich wollte das eigentlich für mich selbst sehen. Ich schreibe diese Instructable weil Bot1398 verwendet ein Arduino und Ive nie verwendet. Ich habe nichts gegen sie, aber, als ich mit Mikrocontrollern begann vor etwa 3 Jahren war ich für Geschwindigkeit und Leistung für eine bestimmte Anwendung suchen. Ich habe mich auf der PIC Microcontroller-Serie von Microchip angesiedelt. Es ist erstaunlich, was Sie mit Mikrocontrollern zu tun, können Sie lassen Sie Ihre Phantasie laufen und mit einem kleinen kreativen Programmierung erreichen genau das, was Sie wollen. Es gibt eine Reihe von Programmiersprachen da draußen, aber als ich begann ich wollte Geschwindigkeit und genau wissen, was los war bei jedem Schritt, daher wählte ich Assembly Language, da es schien eine Menge wie BASIC, dass ich gelernt, auf der IBM PC Jr. zurück in den 1980er Jahren, als ich erwachsen wurde. Das ist, was diese Instructable beinhaltet: PIC-Mikrocontroller und Assembler-Sprache, eine LED (Light Emitting Diode) zu verwenden, um die Menge des Umgebungslichts zu erfassen und das numerische Maß dieses Lichts zusammen mit einem Balkendiagramm auf einem LCD-Bildschirm anzuzeigen. Ich habe die erste Version dieser LED-basierten Lichtsensor-Gerät, die Arbeit funktionierte, die Mühe, die ich bemerkte, dass die Werte um einiges gesprungen. Daher suchte ich nach einer Lösung für dieses Problem, ich dachte über die Mittelung der Werte, aber wie Binär-Mathematik ist etwas schwierig, aber es gibt immer einen Weg, um es zu erledigen. Wie ich auf der Suche nach Lösungen stieß ich auf eine große Seite über Moving Averages und wie es am effektivsten zu tun, so dass selbst die 8-Bit-Mikrocontroller können es mit Leichtigkeit behandeln. Der Link zur Seite ist hier: Computational Efficient Moving Averages und das funktioniert sehr gut. Diese Implementierung zeigt den Moving Average der letzten 256 Lichtwerte an und zeigt diesen Wert zusammen mit einem Balken auf dem LCD-Bildschirm an. Der gleitende Mittelwertcode verhindert, dass die Werte, die von der LED gelesen werden, sehr viel springen und Ihnen ein besseres, viel genaues Ergebnis liefern. Wenn wir eine LED an einen Microcontroller anschließen, tun wir das normalerweise, um es zu beleuchten. In diesem Fall legen wir jedoch eine positive Spannung an das negative Ende der Elektrode an. Dies ist, so können wir die Vorteile der so genannten parasitären Kapazität. Die Anwendung dieser positiven Spannung wird eine kleine Ladung (Ressourcen auf dem Internet sagen innerhalb von 100-200 Nanosekunden) innerhalb dieser parasitären Kapazität der LED, die wir verwenden aufbauen. Die tatsächliche Kapazität ist nicht sehr wichtig, aber online resouces sagen, dass es etwa 10-15 pF ist. Wir schalten dann den Stift des Mikrocontrollers, der an das negative Ende der Elektrode angeschlossen ist, von einem OUTPUT zu einem INPUT und warten, bis die Ladung abgelaufen ist. Wenn der Ladestrom ausreichend ist, liest der Pin nun einen logischen Pegel 0 oder einen Low-Zustand, wo wir den Timer ausschalten und diesen Wert verwenden, um den gleitenden Durchschnitt zu berechnen und die Ergebnisse auf dem Bildschirm anzuzeigen. Wir nehmen dann mehr Lesungen und zeigen sie auf dem Bildschirm in dem Intervall, das in der Assembler-Code geschrieben wird. Im fertigen Code habe ich es gesetzt, um eine Lesung über alle 20 oder so Mikrosekunden. Dies geschieht 50 Mal, so dass ein aktualisiertes Ergebnis auf dem Bildschirm etwa jede Sekunde oder so angezeigt wird. Die Zeit, die benötigt wird, um ein Lesen zu erhalten, variiert ein wenig, da es länger dauert, bis die Ladung in einer dunklen Umgebung abläuft, und dies geschieht schneller in leichten Umgebungen. Die Entladungsrate der LED-Kapazität ist irgendwie direkt mit der Anzahl der Photonen oder der Lichtmenge zusammenhängen, die auf die LED-Licht erzeugenden Elemente auftrifft. Neat ist es nicht. ) Nun, da wir wissen, wie es funktioniert, gehen wir weiter zu Schritt 1. Schritt 1: Sammeln von Komponenten und Montage der Schaltung Alle 5 Bilder Erste sammeln Sie die folgenden Elemente, die Sie benötigen, um die LED LYT METER: PIC Microcontroller (Ich habe die 18F4550) Lcd-Schirm (2x20 oder 2x16) LEDs Breadboard Wires Energiequelle Jetzt sollten Sie in der Lage sein, dem Diagramm zu folgen, um die Schaltung auf einem Steckbrett oder irgendeine andere Weise zusammenzubauen, die Sie Ihre Schaltungen zusammen setzen möchten. Dieses ist ziemlich einfach und hat minimale Teile. Ich habe zwei verschiedene Schemata angebracht, die eine hat die Lichtmess LED an zwei verschiedene Mikrocontroller Pins angeschlossen und die andere hat diese LED mit der Kathode (oder negativen Ende) an einen Mikrocontroller Pin und die Anode (oder positives Ende) der LED an Masse angeschlossen. Dies scheint rückwärts, aber, wir erinnern, wir sind nicht mit der LED zu produzieren Licht, sondern um es stattdessen zu messen. Deshalb ist es auf diese Weise verbunden. In meinen Bildern wirst du sehen, dass die LED an zwei Pins des Mikrocontrollers angeschlossen ist. Dies liegt daran, ich wollte in der Lage, die LED zu produzieren Licht zu, um zu überprüfen, um sicherzustellen, dass es funktioniert, wenn das Programm gestartet wird. Wenn Sie sich dafür entscheiden, die LED an 2 Pins des Mikrocontrollers anzuschließen, müssen Sie dies im Hinterkopf behalten, damit es funktioniert. Ich konnte nicht finden, dass dies dokumentiert überall, so dass es ein wenig Experimentieren, um es an die Arbeit. Um die LED aufleuchten zu können, müssen beide Mikrocontroller-Pins als OUTPUTS eingestellt werden. Dann, um die LED leuchten, setzen Sie die Anode (oder positives Ende) der LED hoch, so dass Strom fließt durch die LED zu produzieren Licht. Zuerst dachte ich, dass ich die Kathode (oder negatives Ende) der LED als INPUT einstellen muss, aber das hat nicht funktioniert. Nun, da Sie die Komponenten haben, legen Sie sie zusammen auf dem Breadboard, indem Sie den Schaltplan, den Sie folgen möchten. Wenn zusammengebaut, sollte es etwas ähnlich den Abbildungen unten schauen. Ich bin mit einem 5 Volt-Regler zur Versorgung 5 Volt an die Stromversorgung. Ich benutze eine Mauer, die etwa 9 Volt an den Regler liefert. Der LCD-Bildschirm, den ich verwende ist ein Newhaven Display NHDC0220AZFSWFTW COG (ChiponGlass) Liquid Crystal Display-Modul. Ich verwendet, um die HD44780 LCD-Displays, die viele andere Menschen nutzen. Sie können die HD44780 Displays ohne Probleme nutzen und es gibt viel mehr Quellcode draußen, um sie laufen zu lassen. Die Newhaven-Anzeige hatte keinen Quellcode, sondern setzte sich mit dem Datenblatt und mit dem HD44780-Quellcode, kam ich mit dem Code, damit es perfekt funktioniert. Ich mag die Anzeige für ein paar Grund. Der Kontrast ist sehr einfach einzustellen und bisher habe ich es nicht ändern müssen, während der verschiedenen Jahreszeiten, es bleibt immer klar und sehr einfach zu lesen. Es hat auch einen kleineren Platzbedarf und war genau das, was ich brauchte für ein riesiges Projekt, das ich arbeite, wo der verfügbare Platz ist an einer Prämie. Es ist kleiner und als die HD44780 zeigt und immer noch 20 Zeichen auf jeder der beiden Zeilen. Schließlich ist es weniger teuer als die HD44780 zeigt auch. Ich wählte ein paar von diesen von Digikey und nur zu einem Preis von 10,25 je. Überprüfen Sie sie hier: Newhaven LCD Display bei Digikey. Denken Sie daran, dass diese Anzeige von 3,3 bis 5,5 Volt benötigt, so halten, dass bei der Auswahl Ihrer Stromquelle. Der gelieferte Quellcode sollte die HD44780-Anzeigen auch ohne Probleme ausführen. Dies ist nur die Art und Weise, dass ich es eingerichtet habe. Sie können die Komponenten zu verschiedenen Pins Ihres Mikrocontrollers platzieren. Denken Sie nur daran, welche Pins des Mikrocontrollers Sie mit dem positiven und negativen Ende der Lichtsensor-LED verbinden. Sie können auch Ihren LCD-Bildschirm verdrahten, um im 4-Bit-Modus statt 8-Bit-Modus arbeiten, wie dargestellt. Das würde vier weniger Anschlüsse in der Schaltung erfordern, aber macht Ihre Programmierung nur etwas komplizierter. Weiter zum nächsten Schritt. Schreiben des Programms. Ein Exponential Moving Average IIR Filter Filterung von Messgrößen eingebettete Mikrocontroller-basierte Schaltungen wird benötigt, um den Mittelwert der Signale zu verfolgen und ihre Variabilität zu reduzieren. Da sich die Signale in ihrem Durchschnittswert über die Zeit ändern, muß das Filter ein Mittel haben, um alte Messungen zu verwerfen, während neue Proben aufgenommen werden. Das exponentiell gleitende, durchschnittliche unendliche Impulsantwort-Filter (IIR-Filter) ist seit vielen Jahrzehnten gut verstanden und wird weitgehend in der statistischen Analyse verwendet. Sie liefert ein rechnerisch einfaches Mittel zur Bestimmung des Mittelwertes einer Variablen, wenn das zugrunde liegende Modell der Variablen unbekannt ist. Wenn v n die zu filternde Variable ist, dann ist ein n-ter Schätzer für den Mittelwert: wobei a ein Gewichtskoeffizient ist, dessen Wert den Glättungsbetrag bestimmt. Je näher a auf 0 gesetzt ist, desto größer ist die Glättung. In einigen Fällen erzeugt der Algorithmus in dieser Form Zwischenergebnisse, die groß werden können. Um dies mit einer endlichen Präzisions-Integer-Arithmetik umzusetzen, wird es in eine etwas andere Form umgeformt, in der Zwischenergebnisse durch einen bekannten Wert begrenzt werden. Der Gewichtskoeffizient wird als 1/1 / c dargestellt. Wobei c eine Potenz von 2 ist. Die Leistung k kann erhöht werden, um die Glättung zu erhöhen, während die Einschränkung auf eine Potenz von 2 ermöglicht, daß Multiplikationen und Teilungen unter Verwendung von sehr schnellen Rechts - und Linksverschiebungsoperationen in einem Mikroprozessor implementiert werden. Die Größe cv av (n) wird verfolgt, um die Genauigkeit aufrechtzuerhalten: Wenn beispielsweise die Abtastwerte 8 Bit-Größen sind (wie in vielen der Algorithmen, die für die hier beschriebenen SMPS-Schaltungen beschrieben sind) und k als 8 gewählt wird, dann ist die Größe Cv av (n) kann als 16-Bit-Wert ohne Verlust von Information dargestellt werden (genau: 8k Bits, siehe unten). Sobald dies bestimmt ist, wird die Größe v av (n) durch eine einfache Rechtsverschiebung um k Stellen erhalten. An diesem Punkt gibt es einen Informationsverlust von weniger als 1 lsb Grße, der in die Unsicherheiten von vn absorbiert werden kann (man beachte jedoch, dass es Korrelationen in dieser verlorenen Information gibt, die systematische Fehler verursachen können). Unter der Annahme, daß die Variablen vi statistisch unabhängig sind, zeigt die Varianzanalyse, daß sie um einen Faktor 1 / (2c) reduziert ist. Für Schrittänderungen in v n ist die Zeitkonstante c Berechnungsintervalle. Das Verfolgen des Mittelwerts wird weniger genau, wenn die Zeitkonstante zunimmt, um mit der niedrigsten Frequenz im zugrunde liegenden Signalmodell vergleichbar zu werden. Obergrenze für den Mittelwert Der Filter beginnt mit v av (0) 0. Alle Messungen v n liegen zwischen 0 und kleiner als B (wobei B in unseren Beispielen normalerweise 256 beträgt). So arbeitet man am Anfang der Sequenz (die in der Praxis immer endlich ist), also nur B. Also ist der Maximalwert des verstärkten Durchschnitts cv av (n) cB, der im obigen Beispiel innerhalb einer 16-Bit-Zahl liegt. Gewichtung In dem Fall, in dem die Proben unterschiedliche statistische Wichtigkeit haben, das heißt, einige haben eine größere Fehlerwahrscheinlichkeit als andere, können Gewichte angewendet werden, um eine allgemeinere Form des Filters zu erzeugen. Diese Gewichte würden so gewählt, daß sie eine umgekehrte Beziehung zur Fehlerwahrscheinlichkeit haben. Wenn w n die anzuwendenden Gewichte sind, kann das folgende Filter verwendet werden: Die zweite Gleichung erzeugt eine IIR-Schätzung des Durchschnitts der Gewichte, die in der ersten Gleichung verwendet wird. Dies kann gezeigt werden, um eine ungehinderte Schätzung des Mittelwerts von v n mit einem Vergessensfaktor von (1-a) zu erzeugen. Wie zuvor wurden die modifizierten Mittelwerte cw av (n) und cw av (n) v av (n), die auf der linken Seite angegeben sind, verfolgt und die gewünschten Mengen durch einfache Division extrahiert. Exponential Moving Average - EMA Laden des Players. BREAKING DOWN Exponential Moving Average - EMA Die 12- und 26-Tage-EMAs sind die beliebtesten Kurzzeitmittelwerte und werden verwendet, um Indikatoren wie die gleitende durchschnittliche Konvergenzdivergenz (MACD) und den prozentualen Preisoszillator (PPO) zu erzeugen. Im Allgemeinen werden die 50- und 200-Tage-EMAs als Signale von langfristigen Trends verwendet. Trader, die technische Analyse verwenden finden fließende Mittelwerte sehr nützlich und aufschlussreich, wenn sie richtig angewendet werden, aber Chaos verursachen, wenn sie falsch verwendet werden oder falsch interpretiert werden. Alle gleitenden Mittelwerte, die gewöhnlich in der technischen Analyse verwendet werden, sind von Natur aus nacheilende Indikatoren. Folglich sollten die Schlussfolgerungen aus der Anwendung eines gleitenden Durchschnitts auf ein bestimmtes Marktdiagramm eine Marktbewegung bestätigen oder ihre Stärke belegen. Sehr oft, bis eine gleitende durchschnittliche Indikatorlinie eine Änderung vorgenommen hat, um eine bedeutende Bewegung auf dem Markt zu reflektieren, ist der optimale Punkt des Markteintritts bereits vergangen. Eine EMA dient dazu, dieses Dilemma zu einem gewissen Grad zu lindern. Da die EMA-Berechnung mehr Gewicht auf die neuesten Daten setzt, umgibt sie die Preisaktion etwas fester und reagiert damit schneller. Dies ist wünschenswert, wenn ein EMA verwendet wird, um ein Handelseintragungssignal abzuleiten. Interpretation der EMA Wie alle gleitenden Durchschnittsindikatoren sind sie für Trendmärkte viel besser geeignet. Wenn der Markt in einem starken und anhaltenden Aufwärtstrend ist. Zeigt die EMA-Indikatorlinie auch einen Aufwärtstrend und umgekehrt einen Abwärtstrend. Ein wachsamer Händler achtet nicht nur auf die Richtung der EMA-Linie, sondern auch auf das Verhältnis der Änderungsgeschwindigkeit von einem Balken zum nächsten. Wenn zum Beispiel die Preisaktion eines starken Aufwärtstrends beginnt, sich zu verflachen und umzukehren, wird die EMA-Rate der Änderung von einem Balken zum nächsten abnehmen, bis zu dem Zeitpunkt, zu dem die Indikatorlinie flacht und die Änderungsrate null ist. Wegen der nacheilenden Wirkung, von diesem Punkt, oder sogar ein paar Takte zuvor, sollte die Preisaktion bereits umgekehrt haben. Daraus folgt, dass die Beobachtung einer konsequenten Abschwächung der Veränderungsrate der EMA selbst als Indikator genutzt werden könnte, der das Dilemma, das durch den nacheilenden Effekt von gleitenden Durchschnitten verursacht wird, weiter beheben könnte. Gemeinsame Verwendung der EMA-EMAs werden häufig in Verbindung mit anderen Indikatoren verwendet, um signifikante Marktbewegungen zu bestätigen und deren Gültigkeit zu messen. Für Händler, die intraday und schnelllebigen Märkten handeln, ist die EMA mehr anwendbar. Häufig benutzen Händler EMAs, um eine Handel Bias zu bestimmen. Zum Beispiel, wenn eine EMA auf einem Tages-Chart zeigt einen starken Aufwärtstrend, eine Intraday-Trader-Strategie kann nur von der langen Seite auf einem Intraday-Diagramm handeln.


No comments:

Post a Comment