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!
09.12.2010, 17:29 (Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2011 13:35 von Dennis.Moser.)
Pünktlich zum Feierabend treten wiedermal Probleme auf ;
hat jemand a) ne Idee, wie man es lösen kann?
und b) warum dies so ist?
Ich hab eine State-Maschine in der 2 Eventstrukturen in unterschiedlichen Cases stecken. (siehe Programm in Anhang)
Wenn ich nun das Array im Programm beim ersten mal antippe funktioniert es Problem los. Beim zweiten mal passiert dann einfach gar nichts mehr.
Wieso und wie ist dies behebar?
Und das zweite Problem, wenn ich den Knopf "nächster Zustand" drücke, dann geht er zwar in den nächsten Zustand aber er springt auch gleich noch in den allernächsten.
Oder anders formuliert, offenbar liest Labview den Befehl aus, wechselt in den neuen Zustand liest hier nochmal aus und setzt erst dann den Knopf wieder zurück.
(Hab es bereits über einen EEigenschaftsknoten gemacht, den er zunächst ausliest, dann den entsprechenden Code durchführt, anschließend die Werte über den Eigenschaftsknoten wieder zurück setzt und dann erst in den nächsten Zustand springt. Das kann doch aber nicht die schönste Lösung sein?)
Wäre super wenn mir jemand ein paar Tips geben könnte.
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
Problem Ereignisstruktur
Es wird dringend davon abgeraten, 2 Eventstrukturen in einem VI zu verwenden.
Ändere das mal ab, dann sollte es tun.
Gruß Markus
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
wusste ich doch irgendsowas mal gelesen zu haben :-).
Theoretisch müsste es doch aber funktionieren, weil doch durch den Case vorgegeben ist, in welchem Zustand er sich gerade befindet. So dass nur jeweils ein Evet ausführbar ist.
Warum geht es dennoch nicht?
Un wie verhält es sich mit dem zurückschalten? (Wenn man auf den nächsten Zustand drückt, wird der Zustand ja erst ausgelesen, dann springt er in die nächste Whileschleife, wo die Taste immernoch gedrückt ist. (Wertänderung (zur Ausführung des Events) wird zwar dann nicht anerkannt, aber sie steht immernoch auf True, dann wird erst zurück gesetzt.)
Hm, dann muss ich mir wohl doch eine komplett andere Programmstruktur überlegen..
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
Problem Ereignisstruktur
So sieht's aus.
Gruß Markus
' schrieb:Hm, dann muss ich mir wohl doch eine komplett andere Programmstruktur überlegen..
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
Zitat:Theoretisch müsste es doch aber funktionieren, weil doch durch den Case vorgegeben ist, in welchem Zustand er sich gerade befindet. So dass nur jeweils ein Evet ausführbar ist.
Warum geht es dennoch nicht?
Du gibst nur vor, welche Eventstruktur überhaupt zum Zuge kommt. Wenn jetzt aber ein Event für die andere Struktur auftritt, blockiert diese Struktur dein Programm, da sie das Event abarbeiten will, aber nicht darf...
NI ist etwas weniger streng und empfiehlt nur, nicht zwei Eventstrukturen in der gleichen Schleife zu verwenden - bei Dir ist aber auch das der Fall. Das eigentlich Tödliche ist vor allem der unendlich lange Timeout bei beiden Eventstrukturen. Das Programm kann nur jeweils an einer der beiden Strukturen auf ein Ereignisse warten. Das Programm könnte nur dann notdürftig funktionieren, wenn die Ereignisse immer streng alternierend an Struktur 1 /Struktur 2 eintreffen würden, aber wer kann das garantieren?
Bei der Ereignisstruktur entstehen dadurch manchmal Mißverständnisse, das sie mit einem Interrupt gleichgesetzt wird. Der entscheidende Unterschied ist aber: Ein Interrupt unterbricht das Programm an einer beliebigen Stelle. Ein Ereignis wird hingegen nur ausgeführt, wenn in dem datenflußorientierten LV-Programm die Eventstruktur an der Reihe ist ausgeführt zu werden. Die Verwechslung mit einem Interrupt führt dann zu eine falschen Erwartungshaltung bezüglich des Funktionierens - so auch hier.
Anzeige
10.12.2010, 16:55 (Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2011 13:35 von Dennis.Moser.)
Solangsam glaub ich es zu verstehen :-)
Dennoch muss ich nochmal nachhaken….
Die Eventstruktur wird also immer ausgeführt egal wo sie ist? (D.h. der Eventstruktur ist es egal in welchem Case sie ist.) Das Event wird registriert und solange gespeichert bis man in das jeweilige Case eintritt?
Das würde dann auch das kleine Programm im Anhang erklären.
Zum Programm:
Über den Sinn oder Unsinn lässt sich streiten, um was es mir geht ist:
Wenn ich Zufallszahlen mit Start erzeuge und anschließend auf Stop drücke, geht er in den Zustand Meldung wo eine Meldung auftaucht. (Er arbeitet nun den Case also ab.) Aber nach der Abarbeitung des Cases wird Stop nicht sofort wieder zurück gesetzt, so dass die Eventstruktur das Stop auch nochmal verarbeitet und somit eine zweite Meldungen hintereinander auftaucht. Erst dann wird Stop wieder zurückgesetzt.
Hab ich das mit der Eventstruktur richtig verstanden, dass das Event registriert wird egal wo es auftritt?
Und welche Möglichkeit gibt es das im Programm beschrieben Verhalten zu ändern?
(Die Möglichkeit die mir einfallen würde, wäre über den Eigenschaftsknoten „manuell“ das Stop bereits im Case wieder zurückzusetzen.)
' schrieb:Die Eventstruktur wird also immer ausgeführt egal wo sie ist? (D.h. der Eventstruktur ist es egal in welchem Case sie ist.) Das Event wird registriert und solange gespeichert bis man in das jeweilige Case eintritt?
Also nochmal: Ein Ereignis wird immer vorgemerkt, egal an welcher Stelle sich das Programm gerade befindet. Kommt es zu mehreren Ereignissen, ohne daß das Ereignis behandelt wurde, dann kommen die vorgemerkten Ereignisse in eine Warteschlange. Ist schließlich die Ereignsnisstruktur mit der Ausführung an der Reihe, dann wird nur ein Ereignis behandelt, und zwar das welches am länsten gewartet hat. Damit die Queue nicht immer länger wird, sollte die Ereignisstruktur also öfter aufgerufen werden als Ereignisse hinzukommen.
Fast jedes Programm besteht fast ausschließlich auf Warten auf irgendetwas. Wenn irgendwo im Programm ein Wait ist, oder ein Warten auf Daten, dann verzögert sich entsprechend die Ereignisbehandlung. Ereignisse werden hingegen sofort behandelt, wenn das Warten ein Warten auf den Timeout an der Ereignisstruktur ist. Jedes Warten im Programm sollte also möglichst so programmiert sein, daß es ein Warten an der Ereignisstruktur ist.
Selbst das Warten auf Daten, seriell oder DAQmx, kann man so konfigurieren, daß z.B nicht DAQmx-Read selbst auf die Daten wartet, sondern daß an der Ereignisstruktur gewartet wird, bis ein benutzerdefiniertes Ereignis "gewünschte Daten stehen im Empfangsbuffer bereit" eintrifft. Wenn das Ereignis eintrifft, werden die Daten ohne Warten gelesen - sie sind ja schon da. Der Vorteil ist offensichtlich: Das Warten von DAQmx Read ist kaum unterbrechber, ebensowenig wie die Wait-Funktion. Das Programm ist in dieser Zeit für den Benutzereingriff tot. Ein Warten an der Ereignisstruktur kann hingegen durch jedes Ereignis, also Stop usw., unterbrochen werden.
Dieselbe Problematik wie mit Waits an den falschen Stelle hat man auch bei mehreren Ereignisstrukturen in einer Programmschleife. Das Programm kann nur an einer der beiden Strukturen auf ein Ereignis warten. Ein Ereignis in der anderen Struktur kann erst behandelt werden, nachdem in der ersten Struktur entweder ein Ereignis eingetroffen ist oder der Timeout überschritten wurde. (Eine besondere "Gemeinheit" von NI ist, daß eine nicht angeschlossenen Zeit ein Timeout von Unendlich ist)