LabVIEWForum.de - Auf Benutzereingabe in einer State-Machine warten, ohne diese zu blockieren

LabVIEWForum.de

Normale Version: Auf Benutzereingabe in einer State-Machine warten, ohne diese zu blockieren
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
Guten Tag,

bisher habe ich leider keine Lösung für mein Problem finden können, da viele Ansätze auf Event-Cases oder globalen Variablen basieren. Da dies allerdings für mich nicht in Frage kommt bzw. ich diese Lösungen nur ungern benutzen möchte, frage ich hier erstmal nach.

Nun aber zur Beschreibung:

Vereinfacht gesagt, kann man mit meinem Programm nach Interfaces scannen, ein Protokoll für jedes Interface auswählen und dann Daten von den Interfaces abholen.
Diese Funktionalität ist mit einer state-machine realisiert. Die Protokollauswahl geschieht in einem Sub-VI.

Soweit so gut, nun zum Problem:

Das Sub-VI für die Protokollauswahl soll nicht warten, bis der Benutzer dort "DONE" gedrückt hat, sondern solange nichts gedrückt wurde "FALSE" ausgeben. Dieses "FALSE" wird dann im Haupt-VI ausgewertet, damit weitere cases folgen können und das Programm nicht festhängt. Diese Funktionalität ist erwünscht, um z.B. von den Interfaces kommende Daten parallel zu sammeln, während Protokolle im Sub-VI geändert oder Interfaces abgewählt werden (Protokoll = "none").

Mein Lösungsansatz:

Das Sub-VI für die Protokollauswahl beinhaltet ebenfalls eine state-machine, welche von außen gesteuert werden kann. Die cases sehen wie folgt aus:

1. - FP öffnen, Interfaces inkl. der Protokolle in Auswahlliste schreiben
2. - done gedrückt ? NEIN: "FALSE" ausgeben | JA: Protokollauswahl schreiben, "TRUE" ausgeben, FP schließen & VI schließen

Das Haupt-VI wertet das "TRUE/FALSE" aus und bestimmt so den nächsten case für das Sub-VI und seine eigenen nächsten cases. Solange "DONE" im Sub-VI also nicht gedrückt wurde, schreibt das Haupt-VI wieder den Befehl für case 2, sodass das Sub-VI beim nächsten Durchlauf wieder dort landet und schaut, ob der Benutzer nun "DONE" gedrückt hat. Währenddessen macht jedoch das Haupt-VI weiter seine Aufgaben. Das Sub-VI soll solange also offen bleiben, quasi wie ein Dialog.

Problem ist, dass das Sub-VI jedes Mal neu gestartet wird, wenn aus meiner Haupt-state-machine der state für das Sub-VI übergeben wird. Ich habe das mit einem Zähler im Sub-VI überprüft. So wird mein Case 1 natürlich nur einmal aufgerufen, danach landet das Sub-VI stets in Case 2, bis man "DONE" drückt. Die Auswahlliste wird also nur beim ersten Durchlauf beschrieben, danach ist sie immer leer. Außerdem flackert es natürlich wie sau.

Vielleicht klappt es garnicht so, wie ich denke und bei jeder Übergabe des cases für das Sub-VI wird es automatisch neu aufgerufen ?! Habe schon sämtliche Dinge in den VI-Settings ausprobiert, aber irgendwie hilft alles nischt. Sad

Ich hoffe, dass ich mein Problem einigermaßen verständlich schildern konnte. Bilder hochladen kann ich leider nicht, sonst würde ich das tun.

Mit sonnigem Gruß,
Gigantbohne
Versuche ein uninitialisiertes Schieberegister, um die Daten aus Case 1 zwischen den Aufrufen zu speichern.

Aber besser wäre es das Sub.vi parallel zu deiner Statemaschine laufen zu lassen. Aber das würde dann wahrscheinlich auf ein Lösung raus laufen, die du nicht haben willst.
Hallo bohne,

du musst dein subVI bzw. dessen FP ja nicht jedesmal öffnen und schließen!

- Öffnen, wenn eine (erneute) Auswahl vom User erfragt werden soll
- Schließen, wenn "Done" gedrückt wurde

Das FP kann man über PropertyNodes anzeigen und schließen…
Vor einiger Zeit habe ich mal dieses Code Beispiel gepostet, es behandelt das Öffnen und Schließen von Sub-Vis als Popup, während das Main-V weiter läuft. Studiere das mal, und melde Dich, wenn es dazu Fragen gibt.
Ich danke allen erst einmal für die schnellen Antworten !

@wladimir s
Das mit dem Shift-Register ist eigentlich eine gute Idee, jedoch wird in meinem Sub-VI eine queue ausgelesen und in Listen geschrieben und später von den Listen, nach dem "done"-Druck wieder auf eine andere queue geschrieben. Mit dem shift-register erweist sich das also als schwierig. Das Ding parallel zu meiner state-machine in meiner while-loop laufen zu lassen würde natürlich funktionieren, dann bräuchte ich das Sub-VI allerdings nichtmehr. Gerade das wollte ich ja haben, damit es übersichtlicher wird.

Es soll also genau so funktionieren, als wäre es eine zweite state-machine in meiner while-loop, die aus der ersten Kommandos bekommt und die zweite mit Kommandos befeuert. Das ganze eben bloß als Sub-VI.

@GerdW
Ich würde mich freuen, wenn es sich nicht jedes Mal öffnen und schließen würde, aber das tut es automatisch, sowie aus dem Sub-VI ein neuer Wert rauskommt oder einer für die case übergeben wird. Das will ich aber gar nicht ! Vielleicht habe ich einfach einen Denkfehler und das kann garnicht auf die Art und Weise klappen, wie ich mir das vorstelle ? Habe jedenfalls alle Properties durchsucht und auch einige ausprobiert, aber verhindern, dass es sich nach Abarbeitung eines cases schließt, konnte ich nicht. Habe in den VI-Einstellungen schon alle relevanten Häkchen entfernt.

@lucki
Danke für den Link. Ich hatte mir diesen Thread schon vor Eröffnung meines Threads angesehen, nun auch das Beispiel runtergeladen. Das sieht schon gut aus, allerdings arbeitet das Teil sowohl mit Event-Cases und ist dazu für mich noch nicht sofort auf einen Blick zu durchschauen. Ist nen schönes Ding, aber ich denke für mich etwas zu viel des Guten, da es ja doch schon etwas komplexer ist. Dann hätte ich alles von Grund auf anders bzw. so aufbauen müssen. Das geht jetzt natürlich nicht mehr, oder nur mit sehr viel Arbeit.

Ich bin ja eher der Meinung, dass ich irgendetwas übersehen habe und sich daher mein Sub-VI andauernd neu öffnet und schließt. Kann ja nicht so schwer aus einer while-loop mit zwei state-machines eine while loop mit einer state-machine und einem Sub-VI (welches die andere state-machine beinhaltet) zu machen, ohne dass sich das Sub-VI dauernd neu zu öffnet und schließt. Das Sub-VI soll eben, wenn nicht "done" gedrückt wurde intern im "idle" hängen, aber die zweite state-machine weiterarbeiten lassen. Hmmmmm...

Hat noch einer einen heißen Tipp ?
Okay habe mich weiter belesen und bin nun soweit, dass ich die Lösung vermute:

Ich muss einen asynchronen Aufruf via VI-Server starten und die Daten dann später irgendwie wieder abholen vom SubVI, oder so in der Art. Dazu muss ich erstmal eine strikte Referenz auf mein VI erzeugen, das Flag x80 setzen und jaaa ääähh Hmm
Hallo Bohne,

Zitat:Das Sub-VI soll eben, wenn nicht "done" gedrückt wurde intern im "idle" hängen, aber die zweite state-machine weiterarbeiten lassen. Hmmmmm...
Lösung: Parallel laufende Schleifen…
@GerdW
Okay, das könnte ich schon so machen, aber es gibt doch bestimmt einen eleganteren Weg. Eigentlich ist das SubVI nämlich keine state-machine. Ich habs bloß so umgebaut um somit zur Lösung zu kommen. Das SubVI hat ne while-Schleife, die eben auf "done" wartet. Kann ich dieses "done" von außen irgendwie auslesen, ohne zu warten bis das VI fertig ist ? Mit dem VI Server Zeugs klappt das ja ganz gut so wie ich mir das vorstelle, nur kann ich mit Flag x80 eben nur Werte reinschieben, nicht rausholen. Beim Rausholen muss ich dann flag x100 benutzen, und "Wait on asynchronous call". Damit hängt alles wieder...

Das Ding ist, ich hab mehrere solcher Sub-VIs. Ich müsste dann entweder alle zu state-machines umstricken, oder die SubVIs wieder auflösen und in parallele Schleifen packen. Beides ist irgendwie nicht so reizend.

Lucki hat da mal was zu geschrieben, was in Kombination mit der Refrenzmethode und flag x80 denke ich funktionieren würde. Weiß allerdings nicht, wie man das macht.

http://www.labviewforum.de/showthread.php?tid=1711

Beitrag #5 (weiß auch nicht, wie ich den Link poste, sodass man gleich dort landet... hab #5 ans Ende gepackt, weil der Pfeil hoch (ganz rechts unten hinter jedem post) ja #top an den Link hinzufügt, aber #5 klappt leider nicht. Wäre auch ganz nett zu wissen ;-) )
Hallo Bohne,

du brauchst dafür kein VI-Serverzeug, sondern ein ordentliches Konzept!
Sowas wie Producer-Consumer oder Actor-Framework.
Vor allem, wenn du nun noch mehrere parallel laufende Prozesse koordinieren willst!
Und mein Vorschlag braucht nur eine Propertynode!
Es gibt noch eine zweite Methode, ein SubVI anzuzeigen, ohne das HauptVi zu blockieren. Und zwar besteht die darin, das SubVI vom HauptVI aus ständig zu pollen Das SubVI darf dann keine eigenen Schleifen oder Waits enthalten, also nichts, was Zeit verbraucht. Damit das SubVI nicht flackert, darf dessen FP nicht nach jedem Aufruf geschlossen werden. Das Schließen des FP erfolgt erst dann, wenn es - z.B. mit dem Stop-Knopf am SubVI - geschlossen werden soll. Es muss dann auch das weitere Pollen vom HauptVI beendet werden.
Für ein Beispiel habe ich aber heute am Sonntag keinen Bock.
Seiten: 1 2
Referenz-URLs