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!
03.09.2012, 16:57 (Dieser Beitrag wurde zuletzt bearbeitet: 03.09.2012 21:08 von jg.)
ich bin neu hier, da ich gerade an einem kleinen Programm zur Temperaturmessung mit Thermoelementen am NI 9211 Modul verzweifle wende ich mich an euch.
Meine Aufgabe ist es den letzt möglichen Temperaturwert bei Bedarf auszugeben. Später soll das Programm als SubVI laufen und immer bei Aufruf die aktuellste Temperatur ausgeben. Wenn ich dazu die Messung jedes mal neu starte und einen Wert auslese dauert dies meinen Versuchen zufolge länger, als wenn ich die Messung zu einem noch nicht relevanten Zeitpunkt starte und dann nach ausreichend Zeit mit DAQmx read die Werte auslese. Gemäß dieser Idee habe ich mein Programm, siehe Screenshot, aufgebaut. Zu Testzwecken lasse ich die while-Schleife alle 3 Sekunden durchlaufen. Meiner Theorie zufolge müsste DAQmx read den Puffer mit den Werten der letzten 3 Sekunden auslesen, wenn ich davon wieder den letzten Wert nehme sollte ich doch die aktuellste Messung gewonnen haben. Leider funktioniert das nicht, irgendwie hinken die Werte genau um diese 3 Sekunden hinterher. Ich finde leider nicht was ich übersehen habe.
Vielen Dank schon mal für eure Hilfe
03.09.2012, 17:01 (Dieser Beitrag wurde zuletzt bearbeitet: 03.09.2012 17:05 von GerdW.)
Gegenfrage:
Wenn du nur 5 S/s brauchst, warum lässt du dann die Wartefunktion nicht einfach weg und fragst nur einen Messwert ab? Das DAQmxRead übernimmt dann das Warten auf den nächsten Messwert, der im 0,2s-Takt aufgenommen wird!
So brauchst du nicht erst ein Array zerpfriemeln und hättest immer den aktuellsten Wert zur Verfügung...
P.S.:
Bilder kann man auch zuschneiden, dann hat man nicht 80% weiße Fläche auf dem Bildschirm...
P.P.S:
Dein an eine Statemachine angelegter VI-Entwurf sieht zwar schon gut aus, trotzdem hättest du auch einen Blick in die DAQmx-Beispiele werfen können: DAQmx-Init vor der Schleife, in der Schleife nur das DAQmxRead und nach der Schleife dann DAQmx-DeInit. Diese Standard-Abfolge erspart dir einige Case-Strukturen...
Mit dem Modul NI9211 sind bei aktivierter interner Kaltstellenkompensation keine viel höheren Samplingraten möglich. Das Warten um 200 ms wollte ich eigentlich verhindern.
Ziel ist es, das VI später als SubVI zu verwenden, welches immer den aktuellsten Wert zurückliefert. Dabei liefe das aufrufende Haupt-VI schneller und würde mit der von dir vorgeschlagenen Methode ausgebremst, denk ich mal, oder? In dem Haupt-VI würde die Temperatur auch nicht zwangsläufig bei jedem Schleifendurchlauf abgefragt, sondern getriggert von einem nicht periodischen Signal, aber wenn die Abfrage kommt, dann sollte es der aktuellste Wert sein und das aufrufende VI nicht ausbremsen. Die Wartezeit war nur exemplarisch, um prinzipiell zu prüfen ob mein Ansatz funktioniert, was er leider nicht tut.
Am besten mach ich das dann wohl als FGV, fällt mir gerade ein, was es ja bis auf ein Schieberegister für den letzten Temperaturwert schon ist. Entweder es stehen neue Daten im Puffer bereit oder es wird der letzte Wert genommen.
Nur versteh ich eben nicht warum in dem Test-VI im Bild die Temperaturwerte mit 3 Sekunden Verzögerung angezeigt werden, irgendwie hab ich da einen Denkfehler. Die Anzeige des Arrays "data" wird alle 3 Sekunden aktualisiert und sollte zu diesem Zeitpunkt doch den letzten Temperaturwert, der maximal vor 200 ms aufgenommen wurde enthalten. Dies kann ich so aber leider nicht beobachten, erst mit einer Verzögerung von einem Schleifendurchlauf werden die Werte dann angezeigt.
P.S.:
Bilder werden in Zukunft zugeschnitten und nicht doppelt eingefügt
P.P.S.:
Danke für den stilistischen Hinweis
Zitat:Ziel ist es, das VI später als SubVI zu verwenden, welches immer den aktuellsten Wert zurückliefert.
Das wird dir mit dem gezeigte VI nicht gelingen, da dieses in einer Endlosschleife festhängt (bis der User mal "Boolean" drückt)!
Parallele Aufrufe sind dagegen problemlos möglich...
Zitat:Nur versteh ich eben nicht warum in dem Test-VI im Bild die Temperaturwerte mit 3 Sekunden Verzögerung angezeigt werden
THINK DATAFLOW!
Die Abfrage der Daten dürfte nur ~50ms dauern. Parallel dazu wartest du bis zum nächsten Vielfachen von 3s, d.h. bis der Schleifendurchlauf beendet wird, vergehen noch einmal ~2950ms und deine Daten sind dann schon fast 3s alt...
um das VI als SubVI nutzen zu können, werde ich es noch dementsprechend umbauen, also eine True-Konstante an die Schleife hängen.
Hm nur das mit dem Dataflow ist mir noch nicht klar.
Wenn die Abfrage der Daten durchgeführt wird, also in den ersten ~50ms, sollten doch auch die Anzeigefelder sofort aktualisiert werden, richtig? Das würde doch bedeuten, dass zu dem Zeitpunkt, wenn die Anzeige aktualisiert wird, der aktuellste und die Temperaturwerte der letzten 3 Sekunden im Array stehen. Dem ist aber leider nicht so.
Nächste Erklärung:
Du startest einen DAQmx-Task mit einer Samplerate von 5S/s im Modus "kontinuierlich". Der läuft los und nimmt munter Messwerte auf und legt die in einen Puffer. Du leerst den Puffer in (mehr oder weniger) unregelmäßigen Abständen und bekommst dann immer die bis dahin aufgelaufenen Werte. Hast du mal kontrolliert, wieviele Werte du auf diese Art eigentlich bekommst?
Vorschlag:
- Wie oben genannt: Einzelwertabfrage verwenden. Ist bei der Samplerate ausreichend schnell...
- Verzichte auf die Wartefunktion und lese exakt 15 Werte per DAQmxRead. Dann dauert der Leseaufruf auch 3s und du bekommst die Werte der letzten 3s (solange du nicht noch irgendwo anders dein VI bremst und sich der DAQmx-Puffer langsam mit alten Werten füllt)...
in den ersten 3 Sekunden ist das Array leer (ok), danach kommt reproduzierbar einmalig nur ein Messwert an (unlogisch?) und ab dem nächsten Durchlauf sind dann immer 15 Werte im Array (ok; 3*5=15).
Ich kann mich von meinem Konzept, das ganze als SubVI einzusetzen und dann zu beliebigen Zeitpunkten (mal nach einer, mal nach drei Sekunden), schnellstmöglich um das Haupt-VI nicht auszubremsen, den letzten Temperaturwert auszulesen, noch nicht trennen Wenns nicht klappt, mach ichs doch in einer parallelen Schleife mit Einzelabfragen und einer lokalen Variable.
04.09.2012, 09:43 (Dieser Beitrag wurde zuletzt bearbeitet: 04.09.2012 09:45 von GerdW.)
Zitat:in den ersten 3 Sekunden ist das Array leer (ok), danach kommt reproduzierbar einmalig nur ein Messwert an (unlogisch?) und ab dem nächsten Durchlauf sind dann immer 15 Werte im Array (ok; 3*5=15).
Hier siehst du das Problem, wenn man den aktuellen Puffer abfragen will, ohne (vorher) zu wissen, wieviel Daten da schon drinstehen:
- Ich würde schon beim ersten Schleifendurchlauf Messwerte haben wollen. Warum sollte es ok sein, wenn ich gar keinen Messwert bekomme?
- Im zweiten Durchlauf bekommst du "reproduzierbar" nur einen Messwert: dies ist aufgrund der variablen Wartezeit des ersten Schleifendurchlaufs überhaupt nicht sichergestellt. Außerdem würde mich auch hier das von anderen Iterationen abweichende Verhalten stören: warum sollte ich hier nur einen Messwert erhalten, wenn ich doch 15 erwarte?
- ab dem 3. Durchlauf bekommst du 15 Messwerte. Schön. Dummerweise scheinen dies (aufgrund der ersten zwei Iterationen) immer "zu alte" Messwerte zu sein.
Außerdem: "in den ersten 3 Sekunden" ist die falsche Ausdrucksweise. Der erste Schleifendurchlauf wird nur sehr selten 3s benötigen. Überlege dir warum, wird auch bei der CLAD-Prüfung immer wieder gern gefragt...
Alle diese Probleme lassen sich ganz einfach lösen: statt den Puffer abzufragen stellst du einfach ein, dass du 15 Messwerte haben willst und lässt dafür die Wartezeit weg!
Zitat:Ich kann mich von meinem Konzept, das ganze als SubVI einzusetzen und dann zu beliebigen Zeitpunkten (mal nach einer, mal nach drei Sekunden), schnellstmöglich um das Haupt-VI nicht auszubremsen, den letzten Temperaturwert auszulesen, noch nicht trennen
Das Konzept ist scheiße (tut mir leid, aber so ist es): Solange du mit "Kontinuierlicher" Messwerterfassung arbeitest, musst du auch kontinuierlich abfragen, anderenfalls handelst du dir über kurz oder lang einen BufferOverflow-Fehler ein.
Was ist so schlimm daran, eine parallele Schleife zu starten? Bei 5S/s braucht die kaum Rechenzeit und du hast immer den aktuellsten Messwert zur Verfügung, egal ob per lokaler Variable, FGV oder Notifier...
- beim ersten Durchlauf könnte ich mir vorstellen, dass noch kein Wert im Puffer ist, weil seit Start der Messung erst wenige, vielleicht zu wenige ms vergangen sind.
- Was beim zweiten Schleifendurchlauf los ist versteh ich eben nicht
- Exakt 3 Sekunden wärens nur bei "Wait till next multiple", denk ich mal.
Ok überzeugt ich machs in einer parallelen Schleife. Da dieses, wenn auch kleine Modul, in mehreren Programmen eingesetzt werden soll wollte ich es eben als Sub-VI machen aber anscheinend ist dies hier schlecht.
Zitat:Ok überzeugt ich machs in einer parallelen Schleife. Da dieses, wenn auch kleine Modul, in mehreren Programmen eingesetzt werden soll wollte ich es eben als Sub-VI machen aber anscheinend ist dies hier schlecht.
Was spricht dagegen, die parallele Schleife in ein subVI zu packen?