Wie andere schon erwähnt haben, sollten Sie einen IIR (unendliche Impulsantwort) Filter anstatt den FIR (Finite Impulse Response) Filter, den Sie jetzt verwenden. Es gibt mehr dazu, 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 den Mikrocontrollern verwende, ist ein einpoliger Tiefpassfilter. Dies ist das digitale Äquivalent eines einfachen R-C-Analogfilters. Für die meisten Anwendungen, diese haben bessere Eigenschaften als die Box-Filter, die Sie verwenden. Die meisten Verwendungen eines Kastenfilters, dem ich begegnet haben, sind ein Ergebnis von jemand, der nicht in der digitalen Signalverarbeitung Klasse auffällt, nicht als Ergebnis der Notwendigkeit ihrer besonderen Eigenschaften. Wenn du nur hohe Frequenzen abschwächen willst, die du kennst, ist Rauschen, ein einpoliger Tiefpassfilter ist besser. Der beste Weg, um ein digital in einem Mikrocontroller zu implementieren, ist in der Regel: FILT lt-- 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. FF ist die Filterfraktion. Die die Schwere des Filters anpasst. Schauen Sie sich diesen Algorithmus an und sehen Sie, dass für FF 0 der Filter unendlich schwer ist, da sich die Ausgabe niemals ändert. Für FF 1 ist das eigentlich kein Filter, da der Ausgang gerade dem Eingang folgt. Nützliche Werte sind dazwischen. Bei kleinen Systemen wählst du FF auf 12 N, so dass die Multiplikation mit FF als rechte Verschiebung durch N Bits erreicht werden kann. Zum Beispiel könnte FF 116 sein und die Multiplikation mit FF daher eine rechte Verschiebung von 4 Bits. Andernfalls braucht dieser Filter nur einen Subtrakt und man fügt hinzu, obwohl die Zahlen in der Regel breiter als der Eingabewert sein müssen (mehr auf numerische Genauigkeit in einem separaten Abschnitt unten). Ich nehme normalerweise AD-Lesungen 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 dBoctave über der Rolloff-Frequenz. Allerdings ist für AD-Lesungen in der Regel mehr relevant, um den Filter im Zeitbereich zu betrachten, indem man seine Schrittantwort berücksichtigt. Dies sagt Ihnen, wie schnell Ihr System eine Veränderung sehen wird, wenn das, was Sie Änderungen messen. Um das Entwerfen dieser Filter zu erleichtern (was nur bedeutet, FF zu wählen und zu entscheiden, wie viele von ihnen zu kaskaden), verwende ich mein Programm FILTBITS. Sie legen die Anzahl der Schaltbits für jede FF in der kaskadierten Filterreihe fest und berechnet die Sprungantwort und andere Werte. Eigentlich laufe ich in der Regel über mein Wrapper-Skript PLOTFILT. Dies führt FILTBITS, die eine CSV-Datei macht, dann die CSV-Datei. Zum Beispiel ist hier 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 in diesem Fall 116. Die rote Spur ist die Einheit Schritt Antwort, und ist die Hauptsache zu betrachten. Zum Beispiel sagt Ihnen dies, dass, wenn sich die Eingabe sofort ändert, die Ausgabe des kombinierten Filters auf 90 des neuen Wertes in 60 Iterationen absetzen wird. Wenn Sie sich um 95 Zeit entscheiden, 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 Amplitude. Dies gibt Ihnen eine Vorstellung von der zufälligen Geräuschunterdrückung. Es sieht so aus, als würde kein einzelnes Beispiel mehr als eine 2,5-Änderung in der Ausgabe verursachen. Die blaue Spur ist, ein subjektives Gefühl zu geben, was dieser Filter mit weißem Rauschen macht. Dies ist kein 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 ausgewählt wurden. Sein nur, um Ihnen ein grobes Gefühl zu geben, wie viel es zerquetscht wird 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 Development Tools Software-Version auf meiner Software-Downloads-Seite verfügbar. Hinzugefügt über numerische Präzision sehe ich aus den Kommentaren und nun eine neue Antwort, dass es Interesse an der Diskussion über die Anzahl der Bits, die benötigt werden, um diesen Filter zu implementieren. 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 12 N gewählt, so daß diese Multiplikation tatsächlich durch eine rechte Verschiebung von N Bits realisiert wird. FILT ist also meist ein Fixpunkt ganzzahlig. Beachten Sie, dass dies nicht ändern, eine der Mathematik aus der Prozessoren Sicht. Wenn Sie z. B. 10-Bit-AD-Messwerte und N 4 (FF 116) filtern, benötigen Sie 4 Bruchbits unterhalb der 10-Bit-Integer-AD-Messwerte. Eine der meisten Prozessoren, youd machen 16-Bit-Integer-Operationen aufgrund der 10-Bit-AD-Messwerte. In diesem Fall können Sie immer noch genau die gleichen 16-Bit-Integer-Opertionen, aber beginnen mit der AD-Lesungen links um 4 Bits verschoben. Der Prozessor kennt den Unterschied nicht und muss nicht. Die Mathematik auf ganzen 16-Bit-Ganzzahlen zu machen, funktioniert man, wenn man sie als 12,4 Fixpunkt oder wahre 16-Bit-Ganzzahlen betrachtet (16,0 Fixpunkt). Im Allgemeinen müssen Sie N Bits jeden Filterpol hinzufügen, wenn Sie nicht möchten, dass Rauschen aufgrund der numerischen Darstellung hinzufügen. Im obigen Beispiel müsste der zweite Filter von zwei 1044 18 Bits haben, um keine Informationen zu verlieren. In der Praxis auf einer 8-Bit-Maschine, die bedeutet, dass Sie 24-Bit-Werte verwenden. Technisch würde nur der zweite Pol von zwei den größeren Wert benötigen, 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 Unterroutine oder ein Makro, um einen Filterpolbetrieb durchzuführen, dann das auf jeden Pol anwenden. Ob eine Subroutine oder ein Makro davon abhängt, ob Zyklen oder Programmspeicher in diesem Projekt wichtiger sind. So oder so, ich benutze einen Scratch-Zustand, um NEU in den Subroutinemacro zu übergeben, der FILT aktualisiert, aber auch Lasten, die in den gleichen Kratzer Zustand NEU war in. Dies macht es einfach, mehrere Pole anzuwenden, da die aktualisierte FILT von einem Pole die NEU ist Der nächsten. Wenn eine Subroutine, ist es nützlich, einen Zeiger auf FILT auf dem Weg in, die aktualisiert wird, um nur nach FILT auf dem Ausweg. Auf diese Weise arbeitet die Subroutine automatisch auf aufeinanderfolgenden Filtern im Speicher, wenn sie mehrmals aufgerufen wird. Mit einem Makro brauchst du keinen Zeiger, da du die Adresse passierst, um bei jeder Iteration zu operieren. Code Beispiele Hier ist ein Beispiel für ein Makro wie oben für ein PIC 18 beschrieben: Und hier ist ein ähnliches Makro für ein PIC 24 oder dsPIC 30 oder 33: Beide Beispiele werden als Makros mit meinem PIC Assembler Preprocessor implementiert. Die mehr fähig ist als die eingebauten Makroanlagen. Clabacchio: Ein anderes Problem, das ich erwähnt habe, ist die Firmware-Implementierung. Sie können einmal ein einzelnes Pole-Tiefpassfilter-Subroutine schreiben, dann mehrmals anwenden. In der Tat schreibe ich normalerweise eine solche Unterroutine, um einen Zeiger in den Speicher auf den Filterzustand zu bringen, dann schalte ihn der Zeiger vor, damit er nacheinander einfach aufgerufen werden kann, um mehrpolige Filter zu realisieren. Ndash Olin Lathrop 20. April um 15:03 1. Vielen Dank für eure Antworten - alle von ihnen. Ich habe mich entschlossen, diesen IIR Filter zu verwenden, aber dieser Filter wird nicht als Standard LowPass Filter verwendet, da ich die Zählerwerte durchschnittlich vergleichen und sie vergleichen muss, um Änderungen in einem bestimmten Bereich zu erkennen. Da diese Werte von sehr unterschiedlichen Dimensionen je nach Hardware abhängen, wollte ich einen Durchschnitt nehmen, um auf diese Hardware-spezifischen Änderungen automatisch reagieren zu können. Ndash sensslen Wenn Sie mit der Beschränkung einer Macht von zwei Anzahl von Gegenständen zu durchschnittlich (dh 2,4,8,16,32 usw.) leben können, dann kann die Kluft einfach und effizient auf einem getan werden Low-Performance-Mikro mit keine dedizierten Divide, weil es als Bit-Shift durchgeführt werden kann. Jede Schicht rechts ist eine Potenz von zwei zB: Das OP dachte, er habe zwei Probleme, die sich in einem PIC16 und Speicher für seinen Ringpuffer teilen. Diese Antwort zeigt, dass die Teilung nicht schwierig ist. Zugegeben, es adressiert 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 other39s Antworten. Da einige der anderen Antworten eine Aufteilungsoperation erfordern, sind sie ähnlich unvollständig, da sie nicht zeigen, wie man dies effizient auf einem PIC16 erreichen kann. Ndash Martin Apr 20 12 at 13:01 Es gibt eine Antwort für eine echte gleitende durchschnittliche Filter (aka boxcar Filter) mit weniger Speicherbedarf, wenn Sie nicht Bedenken Downsampling. Es heißt 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, 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 umzustandsmuster zu halten. Offensichtlich können Sie eine bessere Leistung erzielen, wenn Ihr stateize und decimationFactor Potenzen von 2 sind, so dass die Division und Restbetreiber durch Verschiebungen und Masken ersetzt werden. Postscript: Ich bin einverstanden mit Olin, dass Sie immer einfache IIR-Filter vor einem gleitenden durchschnittlichen Filter beachten sollten. Wenn Sie nicht die Frequenznulls eines Boxcar Filters 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 (wobei ein High-Sample-Rate-Input und Mittelwertbildung für die Verwendung durch einen Low-Rate-Prozess) dann ein CIC-Filter kann genau das, was Sie suchen. (Vor allem, wenn Sie stateize1 verwenden und den Ringpuffer insgesamt mit nur einem vorherigen Integrator-Wert vermeiden können). Hierbei handelt es sich um eine eingehende Analyse der Mathematik hinter dem ersten Auftrags-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 Integern und keine Teilung mit dem folgenden Code implementiert werden (könnte einige Debugging, wie ich aus dem Speicher war.) Dieser Filter nähert sich einem gleitenden Durchschnitt von Die letzten K-Samples durch Setzen des Wertes von alpha auf 1K. Führen Sie dies im vorherigen 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. (Ill überprüfen Sie den hier aufgeführten Code, sobald ich eine Änderung bekomme und Beantworten Sie diese Antwort, wenn nötig.) Beantwortet Jun 23 12 um 4:04 Heres ein einpoliger Tiefpassfilter (gleitender Durchschnitt mit Cutoff-Frequenz CutoffFrequenz). Sehr einfach, sehr schnell, funktioniert super und fast kein Speicher oben. Hinweis: Alle Variablen haben Umfang über die Filterfunktion hinaus, mit Ausnahme der übergebenen newInput Hinweis: Dies ist ein einstufiger Filter. Mehrere Stufen können zusammenkaskadiert werden, um die Schärfe des Filters zu erhöhen. Wenn Sie mehr als eine Stufe verwenden, müssen Sie den DecayFactor (bezogen auf die Cutoff-Frequency) anpassen, um zu kompensieren. Und offensichtlich alles, was Sie brauchen, ist die beiden Linien irgendwo platziert, sie brauchen nicht ihre eigene Funktion. Dieser Filter hat eine Rampenzeit, bevor der gleitende Mittelwert des Eingangssignals entspricht. Wenn Sie diese Rampenzeit umgehen müssen, können Sie MovingAverage einfach auf den ersten Wert von newInput anstelle von 0 initialisieren und hoffen, dass der erste newInput kein Ausreißer ist. (CutoffFrequencySampleRate) 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 Doppelzimmer. Wenn du mit Ganzzahlen haften musst, kannst du DecayFactor und Amplitude Factor in gebrochene Ganzzahlen umwandeln, in denen der Zähler als Integer gespeichert ist und der Nenner eine ganzzahlige Potenz von 2 ist (also kannst du dich nach rechts verschieben Nenner anstatt sich während der Filterschleife zu teilen). Zum Beispiel, wenn DecayFactor 0,99, und du willst ganze Zahlen verwenden, kannst du DecayFactor 0,99 65536 64881 einstellen. Und dann, wenn du dich von DecayFactor in deiner Filterschleife vermehrst, verschiebst du einfach das Ergebnis 16. Für weitere Informationen dazu ein exzellentes Buch thats Online, Kapitel 19 auf rekursive Filter: dspguidech19.htm 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, dass Sie wollen die vorherigen, etwa 6 Punkte gemittelt zusammen, tun es diskret, youd fügen Sie 6 Elemente und teilen durch 6, so Sie können den AmplitudeFactor auf 16 und DecayFactor auf (1.0 - AmplitudeFactor) einstellen. Antwortete am 14. Mai 12 um 22:55 Alle anderen haben sich gründlich über den Nutzen von IIR vs. FIR und auf Power-of-Two Division kommentiert. Id nur gerne einige Implementierungsdetails zu geben. Die unten funktioniert gut auf kleinen Mikrocontrollern ohne FPU. Theres keine Multiplikation, und wenn Sie N eine Macht von zwei halten, ist die ganze Teilung Single-Cycle-Bit-Shifting. Grundlegende FIR-Ringpuffer: Halten Sie einen laufenden Puffer der letzten N-Werte und eine laufende SUM aller Werte im Puffer. Jedes Mal, wenn ein neues Sample hereinkommt, subtrahieren Sie den ältesten Wert im Puffer von SUM, ersetzen ihn mit dem neuen Sample, fügen Sie das neue Sample zu SUM hinzu und geben Sie SUMN aus. Modifizierter IIR-Ringpuffer: Halten Sie einen laufenden SUM der letzten N-Werte. Jedes Mal, wenn ein neues Sample kommt, SUM - SUMN, fügen Sie das neue Sample hinzu und geben Sie SUMN aus. Antwortete am 28. August 13 um 13:45 Wenn ich dich gerade richtig lese, beschreibst du einen ersten IIR-Filter, der den Wert, den du subtrahierst, nicht auf den ältesten Wert, der herausfällt, sondern stattdessen der Durchschnitt der vorherigen Werte ist. Erstklassige 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 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 für 30 niedrig sitzt. Eine erste Ordnung IIR-Filter Ndash supercat 28. August 13 um 15:31 wird eine Welle, die scharf beginnt zu steigen und allmählich aus der Nähe (aber nicht auf) der Eingabe Maximum, dann scharf beginnt zu fallen und allmählich aus der Nähe (aber nicht auf) die Eingabe Minimum. Sehr unterschiedliches Verhalten Ndash supercat Eine Frage 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 Sie beschreiben, kann Ihnen nur ein Rechteck in der Zeit geben - ein sinc in freq - und Sie können die Seitenkeulen verwalten. Es lohnt sich, ein paar ganzzahlige Multiplikatoren zu werfen, um es zu einem schönen symmetrischen, abstimmbaren FIR zu machen, wenn man die Uhrzeiger ersparen kann. Ndash Scott Seidman Aug 29 13 bei 13:50 ScottSeidman: Keine Notwendigkeit für Multiplikationen, wenn man einfach jede Stufe der FIR entweder den Mittelwert der Eingabe auf diese Stufe und ihren vorherigen gespeicherten Wert ausgibt und dann die Eingabe speichern (falls man hat Der numerische Bereich, man könnte die Summe eher als Durchschnitt verwenden). Ob das besser als ein Kastenfilter ist, hängt von der Anwendung ab (die Sprungantwort eines Kastenfilters mit einer Gesamtverzögerung von 1ms, zum Beispiel, wird eine böse d2dt Spitze haben, wenn die Eingangsänderung und wieder 1ms später, aber das Minimum haben wird Möglich ddt für einen Filter mit insgesamt 1ms Verzögerung). Ndash supercat Als mikeselectricstuff sagte, wenn Sie wirklich brauchen, um Ihren Speicherbedarf zu reduzieren, und Sie dont mind Ihre Impulsantwort ist ein exponentielles (anstelle eines rechteckigen Pulses), würde ich für einen exponentiellen gleitenden durchschnittlichen Filter gehen . Ich benutze sie ausgiebig. Bei dieser Art von Filter brauchst du keinen Puffer. Sie müssen nicht n hintere Proben speichern. Nur einer. Also, Ihre Speicheranforderungen werden durch einen Faktor von N reduziert. Auch brauchst du keine Teilung dafür. Nur Multiplikationen Wenn Sie Zugriff auf Gleitkomma-Arithmetik haben, verwenden Sie Gleitkomma-Multiplikationen. Andernfalls machen ganzzahlige Multiplikationen und verschieben nach rechts. Allerdings sind wir im Jahr 2012, und ich würde Ihnen empfehlen, Compiler (und MCUs) zu verwenden, mit denen Sie mit Gleitkommazahlen arbeiten können. Abgesehen davon, dass mehr Speicher effizienter und schneller (Sie müssen nicht Elemente in jedem kreisförmigen Puffer zu aktualisieren), würde ich sagen, es ist auch natürlicher. Denn eine exponentielle Impulsantwort passt besser der Art, wie sich die Natur verhält, in den meisten Fällen. Beantwortet Apr 20 12 at 9:59 Ein Problem mit dem IIR-Filter, der fast von Olin und Supercat berührt wird, aber anscheinend von anderen nicht beachtet wird, ist, dass die Abrundung einige Ungenauigkeiten (und potenziell Biastruncation) einführt. Unter der Annahme, dass N eine Potenz von zwei ist und nur ganzzahlige Arithmetik verwendet wird, beseitigt das Verschiebungsrecht systematisch die LSBs der neuen Probe. Das heißt, wie lange die Serie jemals sein könnte, der Durchschnitt wird diese niemals berücksichtigen. Nehmen wir z. B. eine langsam abnehmende Reihe an (8,8,8, 8,7,7,7,7,7,6,6) und nehmen an, daß der Durchschnitt in der Tat 8 am Anfang ist. 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 an das Gegenteil denken. 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 Vorspannung korrigieren, indem Sie 12N2 hinzufügen, aber das wird nicht wirklich das Präzisionsproblem lösen. In diesem Fall bleibt die abnehmende Reihe für immer bei 8, bis die Probe 8-12 (N2) ist. Für N4 zum Beispiel wird jede Probe über Null den Durchschnitt unverändert halten. Ich glaube, eine Lösung dafür 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 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. Meinst du mit zwei durchschnittlichen Werten, mit dem Ergebnis der ersten in die Sekunde in jeder Iteration eingegeben. Was ist der Vorteil dieses MittelsSimple gleitenden Durchschnitt DurchschnittswerteSimple gleitenden Durchschnitt Sie sind ermutigt, diese Aufgabe entsprechend der Aufgabenbeschreibung zu lösen, mit jeder Sprache, die Sie vielleicht kennen. Berechnen der einfachen gleitenden Durchschnitt einer Reihe von Zahlen. Erstellen Sie eine stateful functionclassinstance, die eine Periode annimmt und gibt eine Routine zurück, die eine Zahl als Argument annimmt und gibt einen einfachen gleitenden Durchschnitt ihrer Argumente so weit zurück. Ein einfacher gleitender Durchschnitt ist ein Verfahren zum Berechnen eines Durchschnitts eines Stroms von Zahlen durch nur Mittelung der letzten 160 P 160 Zahlen aus dem Strom, 160 wobei 160 P 160 als Periode bekannt ist. Es kann implementiert werden, indem man eine Initialisierungsroutine mit 160 P 160 als Argument, 160 I (P), 160 anruft, die dann eine Routine zurückgeben sollte, die bei Aufruf mit einzelnen, aufeinanderfolgenden Mitgliedern eines Stroms von Zahlen den Mittelwert von (up To), die letzten 160 P 160 von ihnen, nennen wir diese 160 SMA (). Das Wort 160 Stateful 160 in der Aufgabenbeschreibung bezieht sich auf die Notwendigkeit von 160 SMA () 160, sich an bestimmte Informationen zwischen Anrufen zu erinnern: 160 Die Periode, 160 P 160 Ein bestellter Container von mindestens den letzten 160 P 160 Zahlen von jedem von Seine individuellen Anrufe. Stateful 160 bedeutet auch, dass sukzessive Aufrufe zu 160 I (), 160 der Initialisierer, 160 getrennte Routinen, die 160 nicht 160 teilen gespeicherten Zustand, so dass sie auf zwei unabhängige Datenströme verwendet werden könnte, Pseudocode für eine Implementierung von 160 SMA 160 ist: Diese Version verwendet eine persistente Warteschlange, um die aktuellsten p-Werte zu halten. Jede Funktion, die von init-moving-average zurückgegeben wird, hat ihren Zustand in einem Atom, das einen Warteschlangenwert hält. Diese Implementierung verwendet eine kreisförmige Liste, um die Zahlen innerhalb des Fensters am Anfang jedes Iterationszeigers zu speichern, bezieht sich auf die Listenzelle, die den Wert hält, der gerade aus dem Fenster herausgeht und durch den gerade addierten Wert ersetzt wird. Mit einem Closure bearbeiten Momentan ist dieses sma cant nogc, weil es eine Schließung auf dem Heap zuteilt. Einige Escape-Analysen könnten die Heap-Zuweisung entfernen. Verwenden einer Struct-Edit Diese Version vermeidet die Heap-Zuordnung der Schließung, die die Daten im Stack-Frame der Hauptfunktion hält. Gleiche Ausgabe: Um die Gleitkomma-Annäherungen zu vermeiden, die sich aufhäufen und wachsen, könnte der Code eine periodische Summe auf dem gesamten kreisförmigen Warteschlangen-Array ausführen. Diese Implementierung erzeugt zwei (Funktions-) Objekte, die den Status teilen. Es ist idiomatisch in E, um die Eingabe von der Ausgabe zu trennen (aus dem Schreiben lesen), anstatt sie zu einem Objekt zu kombinieren. Die Struktur ist die gleiche wie die Implementierung von Standard DeviationE. Das Elixir-Programm unten erzeugt eine anonyme Funktion mit einer eingebetteten Periode p, die als Periode des einfachen gleitenden Durchschnitts verwendet wird. Die Run-Funktion liest numerische Eingabe und übergibt sie an die neu erstellte anonyme Funktion und überprüft dann das Ergebnis auf STDOUT. Die Ausgabe wird unten gezeigt, mit dem Durchschnitt, gefolgt von der gruppierten Eingabe, die die Grundlage für jeden gleitenden Durchschnitt bildet. Erlang hat Schließungen, aber unveränderliche Variablen. Eine Lösung ist dann die Verwendung von Prozessen und eine einfache Nachricht übergeben basierte API. Matrixsprachen haben Routinen, um die Gleitende für eine gegebene Folge von Gegenständen zu berechnen. Es ist weniger effizient zu schleifen wie in den folgenden Befehlen. Kontinuierlich fordert eine Eingabe an. Die am Ende einer Liste L1 hinzugefügt wird. L1 kann durch Drücken von 2ND1 gefunden werden, und Mittelwert finden Sie in ListOPS Drücken Sie ON, um das Programm zu beenden. Funktion, die eine Liste mit den gemittelten Daten des bereitgestellten Arguments zurückgibt Programm, das bei jedem Aufruf einen einfachen Wert zurückgibt: Liste ist die Liste, die gemittelt wird: p ist die Periode: 5 gibt die gemittelte Liste zurück: Beispiel 2: Verwenden des Programms movinav2 (i , 5) - Initialisierung der gleitenden Durchschnittsberechnung und Definieren der Periode von 5 movinav2 (3, x): x - neue Daten in der Liste (Wert 3) und Ergebnis wird auf Variable x gespeichert und angezeigt movinav2 (4, x) : X - neue Daten (Wert 4), und das neue Ergebnis wird auf Variable x gespeichert und angezeigt (43) 2. Beschreibung der Funktion movinavg: Variable r - ist das Ergebnis (die gemittelte Liste), die zurückgegeben wird Variable i - ist die Indexvariable und zeigt auf das Ende der Unterliste, in der die Liste gemittelt wird. Variable z - eine Helpervariable Die Funktion verwendet die Variable i, um zu bestimmen, welche Werte der Liste in der nächsten Durchschnittsberechnung berücksichtigt werden sollen. Bei jeder Iteration zeigt die Variable i auf den letzten Wert in der Liste, der in der Durchschnittsberechnung verwendet wird. Also müssen wir nur herausfinden, welcher der erste Wert in der Liste sein wird. Normalerweise müssen wir p Elemente betrachten, also wird das erste Element dasjenige sein, das von (i-p1) indiziert wird. Bei den ersten Iterationen aber wird die Berechnung gewöhnlich negativ sein, so dass die folgende Gleichung negative Indizes vermeiden wird: max (i-p1,1) oder die Gleichung, max (i-p, 0) 1. Aber die Anzahl der Elemente auf den ersten Iterationen wird auch kleiner sein, der korrekte Wert wird sein (Endindex - Startindex 1) oder die Gleichung (i - (max (ip, 0) 1) 1) und dann , (I-max (ip, 0)). Die Variable z hält den gemeinsamen Wert (max (ip), 0), so dass der Anfangsindex (z1) und die Ziffern werden (iz) Mitte (Liste, z1, iz) die Liste der Wert, der gemittelte Summe ( .) Summiert sie Summe (.) (Iz) ri wird sie lokalisieren und das Ergebnis an der entsprechenden Stelle in der Ergebnisliste speichern fp1 erstellt eine Teilanwendung, die den (in diesem Fall) den zweiten und dritten Parameter festlegt. Ich werde Ihnen zeigen, wie man den einfachsten möglichen digitalen Filter quittieren durchschnittlichen Filterquot zu implementieren. Obwohl es sehr einfach zu implementieren ist, aber immer noch in vielen Anwendungen das ist mehr als gut genug. Zum Beispiel reduzieren zufälliges Rauschen aus Signal. Natürlich, wenn es ganz einfach ist, hat es Probleme wie. Es hat keine sehr scharfe Filter Response. Kanal 1 Eingang. Sweep von 20Hz bis 6Khz, Kanal 4 (grün) 15 Punkt gefilterter Ausgang, M (Red) Ausgabe im Freq Domain Samstag, 1. Oktober 2016 Dieses Projekt ist der letzte Teil in der Herstellung eines wirklich leistungsfähigen Solar Lichts. In diesem Projekt haben wir LTC3478 basierte Philips lumileds Treiber und BQ24650 basierte MPPT Solar Li-Ion Ladung Controller. Wir verwenden insgesamt 3 9 Watt jede LED Driver Boards und One Ladesteuerung, um 6 Cell 7.6V 20000mah Li-Lion Akku aufzuladen, Es gibt 4 LED-Balken-Grafik-Display, um die Schätzung der Akkuladung und eine einzige Taste zur Steuerung Onoff, Different Level zu zeigen Der Helligkeit. Und wähle einen aus. Alle oder wenige LED-Boards zu leuchten. Es gibt nicht viel zu beschreiben in der Zeit von schmeatic und Firmware wie alle Firmware und Schmeatic aer bereits auf meinem github account. User Interface Panel ist aus PCB mit 4 Batterie Status LED ein Port für Solarpanel Connector und ein Steuerschalter gemacht. Wenn die Batterie eingeschaltet ist LED-Status entsprechend angezeigt und wenn die Batterie entladen wird, wird der Status der LED entsprechend aktualisiert. In der Ergänzung zu dem kleinen Solar-Beleuchtungsprojekt, an dem ich arbeite, habe ich diesen kleinen Solarlader-Controller zum Laden von Lithium-Ionen-Akku (Li-Ion) erstellt. Circuit verwenden Texas Instrument BQ24650 im Herzen der Schleife, um die Ladung zu kontrollieren. Da die Schaltung einen externen MOSFET hat, so dass maximal 160 Ladestrom auf wirklich hohe Werte eingestellt werden kann. 160Circuit akzeptieren Solar Panel Werte von 5V bis 28V. Ich habe es mit 12V nominal getestet (17Volt offener Stromkreis) 160. und 24 Volt nominal Solarpanel bei Batterieladestrom bis 4A. Derzeit in meinem Haus installiert seit ein paar Monaten Aufladen einer 20000 mah Li-Ionen-Akku. Circuit hat große 4-polige Hochstromkapazität Molex-Stecker für Solarpanel. 6-poliger Stecker für Batterie und Lastschalter. Es ist auch möglich, NTC für die Batterietemperaturüberwachung anzuschließen. BQ24650 kann die Temperatur der Batterie automatisch überwachen. Microcontroller hat 3 PWM-Ausgang für LED-Dimmer und 6-gpio-Pin-Header für einen besseren Status-LED und einen User Interface Key gewidmet. Hallo zu Deutsch Leser. Das ist mein erster Artikel auf Deutsch. Ich habe viel aufrufe aus Deutschland, ich bin auch auf Deutsch und ich bin auch nicht auf Deutsch. Ich bin auch auf Deutsch und Englisch Meine erfahrungen auf deutsch kurze ist.160 160 160 160So beginnen wir. Heutzutage arbeite ich an einem Projekt. MPPT Solar li-ion Laderquot. Bei diesem projekt brauche ich eine160sehr160vollmacht 25W LED leicht. Aber 25W ist viel fur ein160LED-Triber. Es erforden viele kentnisse ein 25 W LED-Triber zu entwerfen. Hauptsorge auf die Projket quotMPPT Solar-lon Laderquot ist zu Lernen wie der MPPT Larder Arbeitet und wie die Software Algorithmus ist. Das Projekt ist ein teil von einem Projekt wurde publiziere ich spter.160 160 160 160 Zuerst arbeitete ich ein 160little Solar Beleuchtung Projekt , Ich brauche eine wirklich helle wahnsinnige 25W 160LED Beleuchtung. Aber Problem war für 25W es eine Menge Power für LED und es erfordert einige Fähigkeiten, um eine solche hohe Wattage LED-Treiber zu machen. Primäres Ziel dieses Projektes ist es, eine Abfahrt Wissen über MPPT Ladung Controller und MPPT Lade-Algorithmen zu bekommen. Dieses projekt ist Teil des projekts Dass ich später posten werde. 160160160 Dieser Beitrag wird als 4. Teil in Serie von einem Linux-fähigen ARM Board zu Hause sein. Klicken Sie auf First. Zweites und Drittes, um zu vorherigen Teilen zu gehen, also lasst uns beginnen. Was ist ein Bootloader, warum brauchen wir it160 ein Bootloader ist ein Programm, das das erste ist, das von der CPU ausgeführt wird. Es trennt einige sehr spezifische Zweck, um einige sehr wesentliche Dinge vor dem Laden des Hauptprogramms (kann OS) in den Hauptspeicherplatz zu konfigurieren. Deshalb heißt es Bootloader. Je nach Bedarf Bootloader kann eine andere Aufgabe (wir werden sie hier abdecken). Es gibt verschiedene Formen und Größen der Bootloader. Sie alle dienen fast dem gleichen Zweck. Mit Mikrocontrollern. Manchmal lädt es eigentlich nicht das Hauptprogramm in den Speicher, sondern übergibt den ausführenden Zeiger auf das Hauptprogramm, damit das Hauptprogramm direkt aus dem Speicher laufen kann, wo es ist. Board mit 4,3 Zoll LCD läuft Qt5 Anwendung, um JPEG Bild und Zeit anzuzeigen
No comments:
Post a Comment