Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
ich möchte in einer Globalen Funktion einen Ringpuffer realisieren.
Die Pufferfukition funktioniert soweit hervorragend aber....
Die Idee war im Hauptprogramm durch den Case "Read" mittels Index "Start" und der Länge einen bestimmten Bereich aus dem Puffer lesen zu können.
Problem: So wie ich es programmiert habe wird durch das Rotate Array immer alles verschoben, wenn ich mir im Hauptprogramm eine bestimmte Stelle (Index) merken möchte bringt das nichts weil sich das Datenfeld immer verschiebt.
Zitat:Die Idee war im Hauptprogramm durch den Case "Read" mittels Index "Start" und der Länge einen bestimmten Bereich aus dem Puffer lesen zu können.
Wie genau ist dein "bestimmter Bereich" definiert? Willst du lesen ala " gib mir das viertletzte Sample und die 5 vorhergehenden" oder eher wie "gib mir das Sample von Zeitpunkt t1 und die 5 vorhergehenden"? Da ist ein Unterschied!
Du hast einen Ringbuffer, der die letzten N Samples zwischenspeichert. Du willst jetzt ab Position x beginnend y Samples lesen: einfach ArraySubset mit x als Index und y als Länge aus dem Buffer lesen. (Wenn x+y>N ist, dann bekommst du entsprechend weniger Samples zurück - der Buffer hat ja nur N Samples gespeichert.)
Also:
- neue Samples eintragen: erst den Buffer um eine Position nach hinten verschiebe, dann das neue Sample an Position 0 eintragen. (Du machst das momentan anders herum, kann je nach Einsatzfall vielleicht passender sein.)
- Samples lesen: mit Index/Länge aus dem Buffer lesen…
Zitat:Kann ich nicht glauben, da du IMMER mit einem vorinitialisierten Array von NaN-Werten in das Schieberegister gehst.
Anfängerfrage: Ist es nicht wichtig das Array vor zu initialisieren da ich sonst eins von undefinierter Größe habe?
Zitat:Wie genau ist dein "bestimmter Bereich" definiert? Willst du lesen ala " gib mir das viertletzte Sample und die 5 vorhergehenden" oder eher wie "gib mir das Sample von Zeitpunkt t1 und die 5 vorhergehenden"? Da ist ein Unterschied!
Ich möchte bei von Zeitpunkt t1 einen bestimmten Bereich lesen.
Zitat:Du hast einen Ringbuffer, der die letzten N Samples zwischenspeichert. Du willst jetzt ab Position x beginnend y Samples lesen: einfach ArraySubset mit x als Index und y als Länge aus dem Buffer lesen. (Wenn x+y>N ist, dann bekommst du entsprechend weniger Samples zurück - der Buffer hat ja nur N Samples gespeichert.)
Hmm aber ist das nicht genau das Problem?
Beispiel:
ich möchte die Funktion im Programm öfter verwenden.
Sagen wir ich habe eine Puffergröße von 50000 Werten
Im Hauptprogramm erkenne ich ein bestimmtes Ereignis (Folge von bestimmten Werten) und möchte einen Zeiger auf den Wert setzen wo das Ereignis aufgetreten ist. ---Idee - ich merke mit den Index---
Später springe ich an die Stelle mit dem Index den ich mir gemerkt habe und lese von da 2000 Werte um diese auf bestimmte Kriterien hin zu bewerten. (Wichtig ist das, da die Bewertung nur in bestimmten Fällen gemacht werden muss)
Natürlich werde ich den Puffer groß genug wählen sodass alle Daten solange vorhanden sind wie das Hauptprogramm zum rechen braucht.
An ander Stelle im Programm möchte ich, sagen wir noch 200 Werte lesen die von einem anderen Ereignis ausgelöst wurden. Auch da, so die Idee, merke ich mir den Index.
Im Moment wird der mir doch immer verschoben auch wenn ich das Array erst rotiere und denn einen Wert hinzufüge.
Oder habe ich deinen Kommentar falsch verstanden?
Gruß Max
12.09.2016, 16:02 (Dieser Beitrag wurde zuletzt bearbeitet: 12.09.2016 16:03 von GerdW.)
Zitat:Anfängerfrage: Ist es nicht wichtig das Array vor zu initialisieren da ich sonst eins von undefinierter Größe habe?
Ja, das ist wichtig.
Aber muss man das Array bei jedem Aufruf deiner FGV erneut initialisieren?
Zitat:Im Moment wird der mir doch immer verschoben auch wenn ich das Array erst rotiere und denn einen Wert hinzufüge.
Ja, der Index wandert immer mit.
Zitat:Oder habe ich deinen Kommentar falsch verstanden?
Ja. Meine Kommentare bezogen sich auf den mitwandernden Index!
Du willst auf eine absolute Zeitangabe mit einem festen Index zugreifen.
Du hast einen Ringbuffer erstellt, der mit wandernden Indices arbeitet.
Siehst du das Problem? Du hast eine Lösung programmiert, die nicht zu deinem Problem passt!
Lösungen:
- Ringbuffer erstellen, bei dem die Indices nicht wandern.
- Nicht auf einen festen Index zugreifen.
Zitat:- Ringbuffer erstellen, bei dem die Indices nicht wandern.
- Nicht auf einen festen Index zugreifen.
Muss ich dafür die Idee mit Rotare-Array komplett verwerfen und mir was neues überlegen?
Oder habt ihr auf Anhieb eine Idee wie ich mein Programm dahingehend verändern kann?
13.09.2016, 07:41 (Dieser Beitrag wurde zuletzt bearbeitet: 13.09.2016 07:42 von GerdW.)
Zitat:Muss ich dafür die Idee mit Rotare-Array komplett verwerfen und mir was neues überlegen?
Nö.
Du könntest für jedes Event, welches dich interessiert, einen eigenen Pointer/Index verwalten, der bei neuen Samples automatisch mit hochgezählt wird…
Zitat:Oder habt ihr auf Anhieb eine Idee wie ich mein Programm dahingehend verändern kann?
Einen echten Ringbuffer verwenden: auf das RotateArray verzichten und intern einen Pointer/index verwalten, der bei jedem neuen Sample hochzählt und am Ende des linearen Buffers dank Q&R automatisch wieder auf den Anfang zurückspringt. Hier musst du dir nur pro Event einen Index merken - und diesen wieder als ungültig markieren, wenn der Ringbuffer die alten Daten wieder überschrieben hat…
Zeichne dir das doch einfach mal auf einem Blatt Papier auf - dann sieht man doch sehr schnell, wie das funktioniert!
Zitat:Du könntest für jedes Event, welches dich interessiert, einen eigenen Pointer/Index verwalten, der bei neuen Samples automatisch mit hochgezählt wird…
Habe ich versucht Vi im Anhang.
Ich Initialisire es von Anfang an auf Puffersize und dekrementiere den Index jeden Umlauf bis 0.
Wird 0 ereicht setze ihn dann wieder auf Puffersize.
Somit bleibt der Index immer da wo das Ereigniss stattgefunden hat, so die Therorie.
In der Praxis funktioniert das bei mir nicht.
Ich habe dran rumgedoktert aber finde den Fehler nicht.
Hat wahrscheinlich was mit dem Indizieren zu tun, da habe ich noch Verständnissprobleme.
Zitat:Einen echten Ringbuffer verwenden: auf das RotateArray verzichten und intern einen Pointer/index verwalten, der bei jedem neuen Sample hochzählt und am Ende des linearen Buffers dank Q&R automatisch wieder auf den Anfang zurückspringt. Hier musst du dir nur pro Event einen Index merken - und diesen wieder als ungültig markieren, wenn der Ringbuffer die alten Daten wieder überschrieben hat…
echter Ringpuffer? gibt es dazu fertige Vi's? Kann man irgendwo nachlesen wie man sowas programmiert?
Ich habe hier im Forum nach anderen Möglichkeiten für Ringpufferspeicher gesucht aber die suchfunktion hat mir nichts wirklich brauchbares angezeigt..
Was heißt Q&R?
13.09.2016, 12:38 (Dieser Beitrag wurde zuletzt bearbeitet: 13.09.2016 12:51 von GerdW.)
Zitat:Somit bleibt der Index immer da wo das Ereigniss stattgefunden hat, so die Therorie.
In der Praxis funktioniert das bei mir nicht. Dodgy
Ich habe dran rumgedoktert aber finde den Fehler nicht.
Hat wahrscheinlich was mit dem Indizieren zu tun, da habe ich noch Verständnissprobleme.
Beispiel:
- Dein Event findet bei (Ringbuffer-)Index x statt.
- Es werden neue Samples eingetragen, der Ringbuffer-Index wird weitergezählt: x-1, x-2, x-3, …
- Etwas später willst du die zugehörigen Daten auslesen: du willst ab "Start" lesen und berechnest daraus den Index "Start + aktueller Ringbuffer-Index". Dummerweise zeigt der Ringbuffer-Index jetzt auf irgendwas wie "x-y": du wolltest doch die Eventdaten von Index x lesen!?
- Weiteres Problem: durch die Addition Start+Index kann dein resultierender Index außerhalb des gültigen Bereichs landen…
- Weiteres Problem: ich finde es bedenklich, wenn eine FGV bei einem error an error-Input keine neuen Daten speichert oder herausgibt. Gibt es einen Grund, dies zu unterbinden?
Zitat:Beispiel:
- Dein Event findet bei (Ringbuffer-)Index x statt.
- Es werden neue Samples eingetragen, der Ringbuffer-Index wird weitergezählt: x-1, x-2, x-3, …
- Etwas später willst du die zugehörigen Daten auslesen: du willst ab "Start" lesen und berechnest daraus den Index "Start + aktueller Ringbuffer-Index". Dummerweise zeigt der Ringbuffer-Index jetzt auf irgendwas wie "x-y": du wolltest doch die Eventdaten von Index x lesen!?
Hmm aber sagen wir ich hebe ein Datenfeld A B C D und es findet bei x(WertA) statt.
Es werden neue Samples eingetragen B C D und jedes mal wird das Array um -1 rotiert, der Ringbuffer-Index wird weitergezählt: x-1, x-2, x-3
Dann steht mein Index doch immer noch auf A so wie es sein sollte oder steh ich auf dem Schlauch?
Zitat:- Weiteres Problem: durch die Addition Start+Index kann dein resultierender Index außerhalb des gültigen Bereichs landen…
- Weiteres Problem: ich finde es bedenklich, wenn eine FGV bei einem error an error-Input keine neuen Daten speichert oder herausgibt. Gibt es einen Grund, dies zu unterbinden?
Ja habe ich schon drüber nachgedacht ich denke ich werde die Addition weglassen da ich den Offset eigentlich nicht brauche.
Die Errors werde ich zu einem späteren Zeitpunkt noch bearbeiten, da ich mich im Moment noch nicht damit befasst habe und noch nicht weiß wie das alles genau funktioniert. (Errormeldungen hinzufügen ohne Datenfluss vom vorherigen Errorcluster zu unterbrechen usw...)