Hallo liebes LabVIEWForum,
ich möchte Messdaten erfassen und diese in einem Diagramm darstellen. Darüber hinaus möchte ich diese Messwerte abspeichern und dafür die Messdauer selber bestimmen. Durch das LV-Forum bin ich auf eine Variante mit einer Ereignisstruktur aufmerksam geworden, leider entspricht die Messdauer nicht der die ich eingestellt.
Die Messdauer beträgt, unabhängig von der eingestellten Messdauer, weniger als 1 Sekunde.
Könnte vielleicht jemand einen Blick auf das Programm werfen und mir einen Tipp geben.
Viele Grüße
Gifo
Hallo Gifo,
einige Fehler:
- im Timeout-Event liest du aus der Messwerte-Queue, dummerweise aber nur genau einen Eintrag. Egal, wieviele Daten du schon in die Queue geschoben hast: du holst nur das älteste Datenpaket heraus…
- in den anderen Events fehlen jede Menge Drähte, man merkt dies an den ganzen "default if unwired"-Ausgangstunneln…
Lösung:
Mach einfach eine Case-Struktur um deine Speicherfunktion (statt der Event-Struktur). Wenn Button gedrückt, dann speichern, sonst Daten verwerfen:
Code:
data := ReadQueueElement
IF Button THEN
Save(data)
ENDIF
(Etwas vereinfacht, aber Grundprinzip: Die Zeitmessung bzw. Freigabe des Speicherns kann mit der Funktion ElapsedTime gesteuert werden…)
Hallo GerdW,
danke erstmal für den Tipp. Das mit den "default if unwired"-Ausgangstunneln hatte ich dummerweise vergessen, ich hatte aber schon gelesen das dies zu Problemen führen kann. Das mit der Case-Struktur wäre natürliche eine einfache Lösung, ich möchte jedoch, dass die Messung für eine bestimmte Messdauer durchgeführt wird. Das heißt sie soll von allein abbrechen und nicht durch einen Tastendruck (Stopp). Kann ich daher die Schleife mit einem Warten-Baustein verwenden wie in dem Bild dargestellt oder gibt es dabei Probleme?
[
attachment=54665]
Hallo Gifo,
Zitat:Kann ich daher die Schleife mit einem Warten-Baustein verwenden wie in dem Bild dargestellt
Nein.
Zitat:oder gibt es dabei Probleme?
Ja: THINK DATAFLOW!
Durch die Wartezeit würde die Schleife mit der nächsten Iteration warten - du willst aber munter weiter iterieren und Messdaten speichern…
Nochmal die Lösung: Verwende ElapsedTime!
[
attachment=54666]
Das Snippet als Anregung nutzen, um die ElapsedTime-Funktion kennenzulernen und zu verstehen wie man sie anwendet…
Hallo GerdW,
ich habe versucht deinen Vorschlag umzusetzen jedoch habe ich ein Problem den Case zu starten während das Programm läuft. Wenn ich das Programm starte und der Start-Schalter dort bereits auf "true" Steht dann geht es. Dieses Verhalten leuchtet mir auch ein aber ich verstehe nicht warum der Schalter nicht noch ein zweites Mal abgefragt wird.
Könntest du mir bei dem Problem nochmal auf die Sprünge helfen?
Viele Grüße,
Gifo
Hallo gifo,
Zitat:ich verstehe nicht warum der Schalter nicht noch ein zweites Mal abgefragt wird.
Ich aber schon: du hast es genau so programmiert, dass der Schalter nur ein einziges Mal abgefragt wird!
THINK DATAFLOW!
Wann wird der Schalter abgefragt?
Solche Dinge findet man mühelos dank Highlight-Execution-Debugging heraus!
Zum VI:
Du hast dich aber nicht an mein Beispiel-Bild gehalten:
- AutoReset ist bei dir TRUE, ich hatte FALSE gezeigt.
- Bei mir läuft die Zeit weiter hoch, bei dir erfolgt ein Reset über den Schleifenzähler.
- Du wertest nirgends aus, ob die Zeit abgelaufen ist, um darüber das Speichern zu beenden.
Code:
IF not(TimeElapsed?) THEN
save(data)
ENDIF
Hast du das Beispiel oben so wie ich es gepostet habe nachprogrammiert und getestet? Und auch verstanden?
Wann leuchtet die "Time Elapsed?"-LED in meinem Beispiel? Wann leuchtet sie nicht? Wie lange leuchtet sie nicht?
Hallo GerdW,
erstmal vielen Dank, dass du einen Blick in mein Programm geworfen hast.
Zu deiner Frage, der Schalter wird beim Start des Programms abgefragt. Das bedeutet, dass der Schalter erst erneut abgefragt wird, wenn beide Schleifen abgearbeitet sind, d.h. in meinem Fall abgebrochen werden.
Ich habe dein Programm nachprogrammiert und ich denke, dass ich es auch verstanden habe.
- Time Elapsed leuchtet wenn die Zielzeit erreicht ist
- Time Elapsed leuchtet nicht, solange die Zielzeit nicht erreicht ist
- wie lange die Time Elapsed leuchtet hängt von der Zielzeit ab
Später habe ich dein Programm etwas geändert, da ich wollte, dass die Elapsed-Time nach jedem Speicherdurchgang zurückgesetzt wird und anschließend die Schleife beendet wird. Ich hatte davor den „Time has Elapsed“ –Ausgang genutzt, um damit die Schleife zu beenden. Leider hat dies beim ersten Mal nicht zum gewünschten Ergebnis geführt. Ich habe jedoch heute nochmal einen Versuch gestartet und siehe da es funktioniert.
[
attachment=54690]
Jetzt bleibt nur noch das Problem, dass der Schalter für den Case nur einmal abgefragt wird. Mein Gedanke ist, dass man diesen Schalter über eine Schleife Abfragt. Anschließend könnte man doch diese Schleife immer laufen lassen, wenn die Schleife (slave), in der Gespeichert wird, nicht läuft.
Oder gibt es da eine einfachere Lösung?
Hallo gifo,
Zitat:Jetzt bleibt nur noch das Problem, dass der Schalter für den Case nur einmal abgefragt wird. Mein Gedanke ist, dass man diesen Schalter über eine Schleife Abfragt. Anschließend könnte man doch diese Schleife immer laufen lassen, wenn die Schleife (slave), in der Gespeichert wird, nicht läuft.
Das Problem hier ist die Art und Weise, wie du die beiden LV-Elemente "Schleife" und "Case-Struktur" anordnest.
Wenn du die Case-Struktur innerhalb der Schleife hättest (statt wie jetzt außerhalb), könnte man dein Problem wohl sehr einfach lösen!
Um das mal in Pseudocode auszudrücken:
Code:
REPEAT
IF Start-Button THEN
save data with timelimit
ENDIF
UNTIL Stop-Button
Pseudocode und PAPs können bei der Erstellung von Programmen sehr hilfreich sein…
Hallo GerdW,
wenn ich dann aber den Schalter von der Case-Struktur auch in der Schleife habe, dann wird dieser ja ständig abgefragt und mein Case wird geschlossen noch bevor die Zeit verstrichen ist.
Vielleicht sollte ich dazu sagen, dass der Schalter als Taster
arbeiten soll oder zu mindestens nach verstrichener Zeit wieder in seinen Urzustand zurück soll.
Viele Grüße,
Gifo
Hallo gifo,
Zitat:Vielleicht sollte ich dazu sagen, dass der Schalter als Taster arbeiten soll oder zu mindestens nach verstrichener Zeit wieder in seinen Urzustand zurück soll.
Ja, solche Randbedingungen sollte man erwähnen…
- "Schalter als Taster": da muss man dann wohl auf eine steigende Flanke des Schalter-Wertes achten (ptByPt_BooleanCorssing)
- "nach verstrichener Zeit…": da muss man den Schalter über eine lokale Variable zurücksetzen…