Hallo!
Ich habe folgendes Problem und mir fällt kein Algorithmus dazu ein.
Ich muss eine Anzahl von Ereignissen innerhalb der letzten Stunde
zählen.
Timer usw hab ich ja schon programmiert.
So, wenn in der ersten Stunde die Ereignisse eintreten, ist das kein
Problem. Nur, wenn die Stunde rum ist, wie muss ich dann weiter machen??
Zum Beispiel:
In den ersten 5min der Messung tritt 20 mal dieses Ereignis ein.
In der ersten Stunde insgesamt 200.
In den 5min nach der ersten Stunde sind es 5.
Dann muss die aktuelle Anzahl nach 1 Stunde und 5min 185 betragen.
Meine Fragen:
- Was soll ich nach Erreichen der 1. Stunde mit dem Timerwert machen?
- Wie kann ich wirklich nur die Ereignisse innerhalb der letzten stunde
zählen?
>- Wie kann ich wirklich nur die Ereignisse innerhalb der letzten stunde>zählen?
Timeoutzähler pro Ereignis. Wenn eine Stunde abgelaufen ist, Ereignis
löschen und Speicher freigeben.
Hmm, naja - als erstes brauchst du eine Zeitbasis, um überhaupt das
Vergehen einer Stunde erkennen zu können. Da du nicht weißt, wieviele
Ereignisse insgesamt auftreten können, wäre eine Liste als Datenstruktur
ganz sinnvoll. In dieser Liste stehen aufsteigende nach Zeitstempeln
geordnet deine Ereignisse. Alte stehen am Anfang, neue werden hinten
angefügt. Bei jedem Tick deiner (wie auch immer gearteten Zeitbasis)
werden die Ereignisse, deren Lebenszeit abgelaufen ist, vom Listenanfang
entfernt.
So sollte die Liste zu jedem diskreten Zeitpunkt nur Elemente enthalten,
die innerhalb der letzten Stunde aufgetreten sind.
Wenn eine zeitliche Auflösung von einer Minute ausreicht, kommt dabei
niemand ins Schwitzen. Da du keine Angaben über die maximale Anzahl der
Ereignisse, ihren minimalen zeitlichen Abstand usw. gegeben hast, ist
das zwar eine naive, aber in Grenzen sinnvolle Lösung...
Grüsse
Oder wenn du viele Ereignisse hast und die zeitliche Auflösung nicht so
wichtig ist:
Ereignisse pro Minute
Ein Array von 60 uint32_t, ein total, ein Array index.
Nach jeder Minute wird das Gesamtergebnis um den Array Inhalt an der
aktuellen Position reduziert, die Anzahl der letzten minute in das Array
geschrieben, auf das Gesdamtergebnis addiert und der Array index erhöht.
Array index läuft natürlich immer nur von 0-60 in der Runde.
Hat ne fixe Speicherlast für eine fixe Auflösung und braucht nur ein
paar Takte pro minute.
Geht natürlich auch pro Sekunde mit einen Array von 3600 ints
Hallo, wie viel Speicher hast du? Wie oft tritt das Ereignis auf? Wie
geanu muss die Zeitliche Auflösung sein?
Wenn du es nur Minuten ganau brauchst würde ich ein Arry nehmen und jede
Minute das den Index erhöhen. (Ringbuffer)
Wenn du es genauer brauchst aber es weniger Ereignisse sein würde ich
eine Liste nutzen, Jedes Ereignis bekommt ein Element.
Hallo,
einen Ringspeicher verwenden. Den Wert jede Minute Speichern dann müssen
nur 60 Werte gespeichert werden. Oder alle 5min oder 10min je nachdem
wie genau man es brauch.
Gruß
Uli
Okay, ich werde es mal versuchen, den Zeitwert immer in einem Array
abzuspeichern. Hm, frühestens könnte jede 0,5 sekunden ein Ereignis
eintreten :D Aber nur theoretisch...1 sekunde möglich, aber auch nur
selten.
Am liebsten wäre mir, wenn man es dann direkt sehen würde.
Dann versuche ich es mal mit einem Riesen-Array mit ner Größe von 3600
:D
jörg k- schrieb:> Dann versuche ich es mal mit einem Riesen-Array mit ner Größe von 3600
Naja Riesengroß ist das nicht in einem PC oder MC mit SDRam ist das
nicht viel. Auf einem Atmega oder MSP340 mit 4k ist das gewaltig mit.
Wenn du ein Byte in 2Bit Felder aufteilst kannst du eine 2 sec (max 4
Ereignisse) Auflösung erreichen und hast nur 450 Byte verbraucht. Sind
schonmal mehr als 80% gespart :)
jörg k- schrieb:> Okay, ich werde es mal versuchen, den Zeitwert immer in einem Array> abzuspeichern.
Wenn nur selten Ereignisse auftreten (wobei durchaus mal zwei kurz
hintereinander dabei sein dürfen, nur eben nicht permanent), dann ist
das ein probater Weg.
Wenn die Ereignisse aber meistens dicht aufeinanderfolgen, dann
verbrauchst du so unnötig eine ganze Menge Speicher, besser ist dann ein
Ringbuffer, der die Ereignisse pro Zeitintervall zählt. Wenn höchstens
ein Ereignis pro 0,5 Sekunden auftritt (deine Angabe), und du ca. 1kB
Speicher erübrigen kannst, kann man das z.B. so machen:
1
#include<stdint.h>
2
#include<stdbool.h>
3
4
boolevent_occurred;// wird gesetzt, wenn ein Event auftritt
Wenn ein Event auftritt, muss event_occurred auf true gesetzt werden,
ausserdem muss (z.B. via Timer) dafür gesorgt werden, dass
every_half_second() genau jede halbe Sekunde aufgerufen wird.
Je nach Plattform und restlichem Code müssen die Variablen natürlich
noch zumindest teilweise volatile deklariert werden.
Andreas
wow,
also mit dem ersten quelltext klappt es jedenfalls!!
Mit dem Speicher muss ich mal gucken. Werde dann sicherlich auch die
speichersparende Variante versuchen!!
Besten Dank für die Beispiele!