Friday 2 June 2017

Circular Buffer Moving Durchschnitt

Ive verwendete es für ein Gedächtnisprotokoll mit einer eingeschränkten Größe. Beispielsweise würde die Anwendung Protokolleinträge schreiben, während Benutzeranforderungen verarbeitet werden. Immer wenn eine Ausnahme aufgetreten ist (die die Verarbeitung beeinträchtigen würde), würden die im Speicher befindlichen Protokolldatensätze zusammen mit ihr ausgegeben. Der Vorteil eines kreisförmigen Puffers ist, dass Sie nicht unendlich viel Speicher benötigen, da ältere Einträge automatisch überschrieben werden. Die Challange ist, dass Sie eine passende Größe für Ihr usecase finden müssen. Im obigen Beispiel wäre es sehr unglücklich, wenn der Protokolldatensatz mit den wichtigsten Informationen über die Ausnahme bereits überschrieben worden wäre. Einige Systemanwendungen verfügen über Tools, mit denen Sie den aktuellen Inhalt des Puffers auf Anforderung extrahieren können, und nicht nur, wenn er automatisch (wenn überhaupt) extrahiert wird. Ich glaube, ETW und die CLRs Stress-Protokoll. Unter vielen anderen Systemen Kernel oder Hochleistungs-Tracelogging, sind auf diese Weise implementiert. Das Konzept der Verwendung solcher Puffer für in-Speicher-Tracinglogging ist eigentlich ziemlich häufig (nicht zu sagen, dass dies die einzige Verwendung ist - sicherlich nicht), denn es ist viel schneller als schriftliche Aufzeichnungen zu einer Datei-Datenbank, die Sie vielleicht nie interessiert sein, es sei denn, ein Fehler auftritt. Und auf einer verwandten Anmerkung, konserviert es Festplattenraum. Circular Puffer sind gut für serielle Datenströme in eingebetteten Systemen. Mikrocontroller haben oft eine UART, um ein serielles Byte hereinzukommen, das in Ordnung gelagert werden muss und später behandelt werden (Bytes kommen oft schneller als sie gehandhabt werden können). Der Puffer teilt die erforderliche zeitkritische Reaktion (wenn die Bytes in Mikrosekunden kommen) wirksam auf die nicht zeitkritische Antwort auf die gesamte Nachricht (z. B. Anzeige der eingehenden Nachricht in Millisekunden), z. B .: 1) Auf Kann der Empfang eines Bytes der UART einen Interrupt erzeugen, auf den die Software reagiert, indem sie schnell das empfangene Byte aufnimmt und es auf das Ende des Puffers schiebt. 2) Hintergrund-Software-Routinen können dann regelmäßig überprüfen, ob der Puffer noch etwas in ihm noch und leer, wie erforderlich. Da die zirkuläre Puffergröße vordefiniert werden kann, ist die Größe dann begrenzt. Dies trägt dazu bei, die Raumeffizienz zu verbessern und Speicherbeschädigung bei einem Trade-Off zu beseitigen, wie viele Bytes empfangen werden können, bevor Daten verloren gehen. Ich weiß, das ist Betrug, aber wikipedia hat eine sehr gute Erklärung. Ein kreisförmiger Puffer, zyklischer Puffer oder Ringpuffer ist eine Datenstruktur, die einen einzelnen Puffer mit fester Grße verwendet, als ob er von Ende zu Ende verbunden wäre. Diese Struktur eignet sich leicht zum Puffern von Datenströmen. Ein Beispiel, das möglicherweise einen überschreibenden Zirkularpuffer verwenden könnte, ist mit Multimedia. Wenn der Puffer als der beschränkte Puffer in dem Erzeuger-Verbraucher-Problem verwendet wird, ist es wahrscheinlich erwünscht, daß der Erzeuger (z. B. ein Audiogenerator) alte Daten überschreibt, wenn der Verbraucher (beispielsweise die Soundkarte) Ein anderes Beispiel ist das digitale Wellenleitersyntheseverfahren, das kreisförmige Puffer verwendet, um den Klang von vibrierenden Saiten oder Blasinstrumenten effizient zu simulieren. In Bezug auf den Vergleich mit doppelt verbundenen Listen, ich glaube, es hängt wirklich davon ab, was Sie mit der Liste für. Die Implementierung von cirular Puffern scheint komplexer zu sein, bitte (wieder) beziehen sich auf die wiki Seite das erklärt Implementierung, Überlegungen usw. und zeigt auch Beispielcode. Beantwortet Mar 31 10 um 14: 25Eines der wichtigsten Anwendungen für die 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 zweistufigen Durchschnitts kann es ziemlich 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. 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 Schleife () wird zuerst eine Zufallszahl erzeugt und in einen Float umgewandelt, 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 wird myRA ist gelöscht, um neu zu beginnen. Um die Bibliothek zu verwenden, machen Sie einen Ordner in Ihrem SKETCHBOOKPATHlibaries mit dem Namen RunningAverage und legen Sie die. h und. cpp dort. Fügen Sie optional ein Beispielunterverzeichnis hinzu, um die Beispielanwendung zu platzieren. 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. ccindex. phptopic50473.msg1790086msg1790086 - Test ausführlich. Vorlagenklasse RunningAverage. h RunningAverage. cpp


No comments:

Post a Comment