LabVIEWForum.de
Zwei Queue-Frage an die Experten - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+--- Thema: Zwei Queue-Frage an die Experten (/Thread-Zwei-Queue-Frage-an-die-Experten)

Seiten: 1 2


Zwei Queue-Frage an die Experten - Cruzaderz - 26.01.2011 23:00

Heyho!

Zwei Fragen bereiten mir gerade Kopfzerbrechen - ich schildere mal am besten zuerst was ich lese und was draus werden soll:

- 8 Kanäle DAQ als 2D Array mit je 1000 Werten / 1000 Hz in while-Schleife mit Sanduhr->1000
- 1 Kanal Durchfluss mit einem Wert Aufruf in while-Schleife mit Sanduhr->1000
- 2 Kanäle DAQ als 2D Array mit je 9 Werten / 9 Hz in while-Schleife mit Sanduhr->1000
- Mehrere verschiedene Werte über RS232 - am liebsten jede sek, kann aber auch mal länger dauern...

Nun die entscheidende Frage: Queues sind klar - funktioniert halt nach FIFO-Prinzip. Aber was passiert, wenn ich z.B. eine gemeinsame Verbraucherschleife mit 1 Hz takte aber irgendeine Datenquelle mal zuviel oder zuwenig Daten ausspuckt. Im Queue-Beispiel laufen die Daten dann ja hinterher, weil sie nicht abgefragt werden, so würde man es auch vermuten. Was passiert aber wenn ich die Verbraucherschleife aus genau dem Grund schneller als die Quellen laufen lasse? Geraten dann meine verarbeitenden Objekte aus dem Tritt, weil mal Daten kommen und mal nicht? Wie löst man so etwas am besten - mit mehreren Verbraucherschleifen, deren Ergebnisse man dann erst am Ende zusammen fasst...?!

Und die zweite Frage zu eben diesem Thema: Für jede Datenquelle sollte man ein eigenes Queue nehmen, eben weil die Inhalte unterschiedlich sind, richtig? Oder kann man ein großes Queue definieren, in dem mehrere zusammen gefasste aber unabhängige Queues laufen.?!

Danke und Gruß,
Dennis

PS: Anbei ein Screenshot um zu zeigen wie ich jetzt angesetzt habe. Da fehlt aber noch einiges an Erzeugern und noch viel mehr an Verbrauchern...Wink


Zwei Queue-Frage an die Experten - Cruzaderz - 26.01.2011 23:43

Okay - hätte ich auch gleich drauf kommen können: While Schleife daneben, 100 ms-Takt und den Iterator auf eine Anzeige in der Verbraucherschleife gegeben. Klappt, d.h. zählt schnell und nicht im Takt der anderen Quellen. Die while-Schleife ist also so schlau die Inhalte unabhängig voneinander im Takt der eintreffenden Daten auszuführen, richtig?!


Zwei Queue-Frage an die Experten - RHeil - 27.01.2011 09:24

Eine oder mehrere Qs ist Geschmackssache.

Mit mehreren Qs kannst Du die Struktur in etwa so machen wie in Deinem Beispiel gezeigt.
Du könntest aber auch eine einzige Q für alles nehmen, wenn Du als Datentyp z.B. einen Message-Cluster verwendest (also einen Cluster aus einem Command-Enum und einem Daten-Variant) und das dann in der Consumer Loop entsprechend behandelst (Case-Struktur).

Auf alle Fälle würde ich keine Wartezeit in die Consumer Loop stecken (so wie Du es ja schon gemacht hast).

Bei mehreren Qs würde ich aber den einzelnen Q-Abfragen ein Timeout geben und den Timeout-Fall abfangen (d.h. die Daten ignorieren bei Timeout).
Dieser Timeout sollte für alle Qs gleich sein und maximal der kürzesten Dauer zwischen zwei aufeinanderfolgenden Paketen entsprechen.
Damit ist die Q dann indirekt getimed.

So wie Du es jetzt machst, bestimmt die langsamste Q den Takt der Schleife, d.h. in der schnelleren baut sich ein Puffer auf.
(Mach Dir mal klar was hier passiert: Die Schleife wird als ganzes wiederholt, wenn ihr kompletter Inhalt einmal abgearbeitet ist. Solange noch auf eine der Qs gewartet wird, wird auch die andere nicht ausgelesen, selbst wenn dort schon 1000 Werte drin sind.)

Außerdem hoffe ich sehr, dass Dein Screenshot nur Konzept-Code zeigt und dass Du ohnehin vorhattest, noch einen ordentlichen Weg zum Beenden der Schleifen zu implementieren. Sonst wäre alles was in Deinem Bild rechts von den Schleifen liegt sinnlos.

Hier mein üblicher Hinweis zu diesem Thema:
Der Stop-Knopf ("Abort Execution") in der Symbolleiste ist eine Art "Not-Aus" für Debug-Zwecke.
In einer sinnvollen Anwendung hat der nichts verloren.
Entsprechendes gilt für "Run Continously".


Zwei Queue-Frage an die Experten - Cruzaderz - 29.01.2011 00:17

Heyho!

Ganz herzlichen Dank für deine Antwort - ich habe oben also quatsch erzählt und wie du sagst bestimmt mittlerweile die langsamste Abfrage den Takt der Anderen. Genau das wird jetzt zum ProblemSad. Das Problem mit einem Timeout zu lösen ist eine gute Idee, allerdings habe ich meine Verbraucherschleife wohl so kreuz und quer programmiert, dass sie insgesamt nun etwas über eine sek dauert. Es wäre auch unschön Daten bestimmter Sensoren zu verlieren, da die in der Zeitebene korreliert werden und der Sprung die Transformation vermutlich aus der Bahn werfen würde. Ich werde mir den Datenfluss daher nochmal gaaaaanz ausführlich zu Gemüte führen und ggf. in diesem Thread nochmal um Hilfe rufen. Auf jeden Fall ist das VI inzwischen zu groß für einen ScreenshotWink(Und hat zu viele Sub-VIs, DAQs etc., um es hier sinnvoll einzustellen)

Mit dem Stop-Button hast du recht - der kommt als letztes hinzu. Wie macht man das am elegantesten - eine Schleife mit Knöpfchen und 10 andere, die dieses per lokaler Variable angebunden haben?!

Viele Grüße,
Dennis


Zwei Queue-Frage an die Experten - Cruzaderz - 29.01.2011 01:18

Soooo... Übeltäter gefunden - ein DAQ mit 1000 Werte / 1000 Hz hat ab und zu mal etwas gelaggt obwohl er auf "kontinuierlich" läuft. Jetzt steht er auf 1050 Hz und macht keinen Ärger mehr. Die paar ms nimmt auch die Korrelation nicht übelWink

Die Vorgehensweise mit dem Timing versteh' ich aber leider noch nicht ganz. Wo es noch klemmt ist das Verwerfen der "nachhängenden" Werte - soll ich das mit "Queue leeren" machen? Momentan hängen z.B. 5 Geräte einem nach, d.h. die Queue-Längen sind dargestellt 1/1/0/1/1/1. Wie könnte ich sie am einfachsten wieder synchronisieren?

Viele Grüße,
Dennis


Zwei Queue-Frage an die Experten - Cruzaderz - 29.01.2011 02:42

Okay, jetzt muss ich doch nochmal die Experten fragen, sonst bastel' ich da morgen früh noch dran rumWink

...obige Frage habe ich mir vorerst quick&dirty selbst beantwortet, indem 3 der 5 Datenquellen aus der Hauptschleife raus in eigene Schleifen gewandert sind. Jeder Datenwert bekommt im Erzeuger den Timerwert Huckepack als Cluster angehängt und ist der kleiner als 1000 zu dem in der Schleife tut's der case, ansonsten geht das Datenpaket ins Leere und das nächste wird gelesen. Ist aber wie ich selbst schon schreibe eigentlich richtig unschön gelöst - besser wäre eine Art "echte" synchronisation. Ich beschreibe mal die äußeren Umstände:

Erzeuger:

1)DAQ 1000 Werte 1000 Hz (Jetzt 1050 Hz, da mit 1000 Hz 1002-1008 ms Dauer)
2)DAQ 9 Werte 9 Hz - der macht zuverlässig 1000 ms
3)RS232 lesen und schreiben in einem Rutsch (beides wichtig)
4)RS232 lesen (Daten in diesem VI unwichtig)
5)USB counter lesen - macht auch deutlich mehr als 1 Hz, also kein Timingproblem
6)Schleife, die Impulse im Sekundentakt erzeugt mit wählbarer Pause und Schaltdauer

Verbraucher:

- 4,5,6 sind unkritisch weil 4 und 5 nur begleitende Informationen sind und 6 alleine arbeitet und nur ein Bit des LPT umschaltet.

- 1 und 2 sind Temperaturdaten und 3 der zugehörige Thermostat, der einen Stellwert bekommt und seine Temperatur und die Stellwertantwort zurück gibt. Hierbei werden entweder die Werte von 1 oder die von 2 via FFT korreliert und der Thermostat entweder nach 1 oder 3 geregelt. Erfreulicherweise dauert die gesamte Schleife wenn alle Daten anliegen weniger als 1000 ms, obwohl Interpolationen und FFTs drin stecken. Wenn man etwas arbeitet steigen die Puffer der Queues aber schnell auf 5-8 an, um dann bald wieder auf 0-1 abzusinken.


...Am wichtigsten sind mir halt die Temperaturverläufe von 1 und 2, weil die in die Korrelation gehen und ehrlich gesagt auch auf dem Papier zum brechen aussehen, wenn ein Stück fehlt und der Graph nen Sprung macht. Daher würd' ich die gerne möglichst durchgängig lesen und verarbeiten, wofür man ihnen aber bestenfalls auch den Zeitpunkt der Erfassung mitgeben sollte. Die dann aber wieder synchron verarbeiten etc. - ui ui ui, ich glaube das VI ist inzwischen weit über das vorhandene Wissen hinaus. Ob das noch glatt läuft...Sad. Vielleicht könnt ihr mir da etwas auf den Weg zurück helfen?!

Und ich hab' nun doch mal das Main-VI angehängt. Wenn eure Kritik bzw. hoffentlich Vorschläge aber über die Queues hinaus gehen sollten wir den Thread am besten umbenennenWink. Gibt bestimmt einiges, was man eleganter lösen kann, daher bin ich für jeden Hinweis dankbar. Und @RHeil ganz unten ist auch der besagte STOP-Button Lol(und - btw. - ein Case, der nur als Platzhalter für noch nicht eingebaute Panelobjekte dient).

Viele Grüße,
Dennis

Lv86_img


Zwei Queue-Frage an die Experten - Lucki - 29.01.2011 09:19

Habe mir das letzte VI mal kurz angesehen. Man weiß ja nicht, wie die Datenerfassung funktioniert, die Hardware scheint nicht von NI zu sein und entprechend gibt es hier keine DAQmx-Treiber.
Aber angenommen, es wäre eine DAQmx-Datenerfassung, dann würde ich dieses dazu sagen:

1.) zu den Queues
Richtig ist, daß eine Erzeuger-Verbraucher-Struktur mit dazwischengeschaltetem FIFO-Buffer sinvoll oder sogar notwendig ist. Es ist nur so: Diese Struktur hat man bei der DAQmx-Datenerfassung immer, auch ohne daß der Programmierer etwas dazu tut. Erzeuger ist die Messkarte. Sie erzeugt die Daten nach Initialisierung und Start durch das Proamm autark und tut sie einen FIFO-Puffer. Der Verbraucher (der PC mit LV-Programm) liest die Daten mit DAQmx Read aus, so wie er sie braucht, also z.B. 1 oder 100 Daten pro Read, oder alles auf einmal (bei endlicher Samplezahl). Es macht keinen rechten Sinn, hier nochmals eine zweite Erzeuger-Verbraucher-Struktur mit Queue (d.h. mit zweitem FIFO-Puffer) in Kette zu schalten. Allerdings gebe ich zu, daß ich das früher selbst so gemacht habe, bevor ich das alles so richtig durchschaut hatte. Und es mag auch besondere Fälle geben, in denen das sinnvoll ist.

2) Daten lesen in Schleife mit DAQmx Read.
Die Schleife synchronisiert sich selbst mit der Datenerfassung, denn wenn z.B 100 Werte gelesen werden und die sind noch nicht im FIFO-Puffer, dann wartet DAQmxRead, bis die Werte da sind. Unnötig, oder sogar gefährlich wegen Pufferüberlauf, sind zusätzliche Wait-VIs in der Schleife.


Zwei Queue-Frage an die Experten - Cruzaderz - 29.01.2011 13:10

Heyho!

Danke für die Tipps - so hatte ich es auch halbwegs verstanden. Initialisiert man 'ne kontinuierliche Datenerfassung wirft die (in meinem Fall) halt immer alles raus, was bis zu dem Zeitpunkt anliegt aber misst dabei im Hintergrund auch weiter. So haben die Punkte (in meinem Fall) dann echte 9 Hz und keine Lücken...

Genau diese DAQ ist von NI, genauer ist es eine USB-9213 im hi-res modus. Die DAQ mit 1000 Hz ist von Keithley (KPCI-3108) und IMHO auch die Ursache der Probleme. Sie hat zwar auch einen kontinuierlichen Modus, braucht aber scheinbar auch die Dauer der Datenerzeugung, bis sie die Daten liefert was in meinen Augen eben kein "echter" kontinuierlicher Modus ist. Die Karte war vor 4 Jahren eine der wenigen, die mit Testpoint spielten, daher sind die VIs noch von LV5.X. Ich werde sie gleich nochmal etwas zerlegen und mir Timings etc. anzeigen lassen - mag sein, dass ich noch nen kleinen Fehler drin habe. Ich werd' auch mal versuchen ähnlich der Keithley ihr "alle Werte im Puffer" zu entlocken weil es dann ja egal wäre was sie im Hintergrund tut. Aber eigentlich ist's traurig, dass ich hier so einen extra-Aufwand betreiben muss, oder?! 1000 Hz/1000 Werte/1* pro sek abgefragt... nach Onkel Adam dürfte da nichts auflaufen...

Viele Grüße,
Dennis


Zwei Queue-Frage an die Experten - Lucki - 29.01.2011 13:38

' schrieb:Aber eigentlich ist's traurig, dass ich hier so einen extra-Aufwand betreiben muss, oder?! 1000 Hz/1000 Werte/1* pro sek abgefragt... nach Onkel Adam dürfte da nichts auflaufen...
Es gibt da bei für das Auslesen der Daten mit Daqmx Read aus dem Empfangspuffer diese zwei Möglichkeiten (kontinuierliche Datenerzeugung angenommen):

1.) Mit Wait in der Schleife. Bei jedem Lesevorgang werden alle Daten aus dem Puffer gelesen
2.) Ohne Wait, es wird mit DAQmx Read immer eine bestimmte Anzahl Werte aus dem Puffer gelesen.

Der Nachteil von 1 ist, daß man keine konstante Anzahl von Werten liest. D.H das gelesene Array hat jedesmal eine etwas andere Größe und das kann die weitere Verarbeitung der Daten komplizierter machen.

Besser ist deshalb meist Methode 2, und es gibt keine Probleme, die Anzahl der von DAQmx Read pro Durchlauf gelesenen Werte so zu wählen, daß sich die gewünschte Leserate (Hier 1/sec) ergibt.

Wie schon gesagt, eine ganz schlechte, aber leider bei Anfängern immer wieder gesehene Methode ist es, 1 und 2 zu kombinieren, also eine bestimmte Anzahl von Werten zu lesen und extra noch ein Wait in die Leseschleife zu bauen.


Zwei Queue-Frage an die Experten - dimitri84 - 29.01.2011 14:08

' schrieb:Es ist nur so: Diese Struktur hat man bei der DAQmx-Datenerfassung immer, auch ohne daß der Programmierer etwas dazu tut. Erzeuger ist die Messkarte. Sie erzeugt die Daten nach Initialisierung und Start durch das Proamm autark und tut sie einen FIFO-Puffer. Der Verbraucher (der PC mit LV-Programm) liest die Daten mit DAQmx Red aus,...
Stimmt natürlich, nur: Kartenpuffer << RAM (Queue). Und als Bonus nutzt man mit einer Producer-Consumer die DualCores wunderbar aus.