(23.11.2015 14:56 )m.werle schrieb: -> Unzyklische, unendlich lange Beaufschlagung
Ja, gut. Ich weis bescheid.
Zitat:Die Whileschleife hat übrigens auch keinen Timer, ich glaube das Timing wird lediglich von dem DAQmx-Read-VI bestimmt.
Das stimmt nur zum Teil.
Das Timing, also die tatsächliche Zyklusdauer der While-Schleife, ergibt sich dadurch, dass alles, was in der Schleife steht, abgearbeitet wurde. Das klingt zwar einfach, ist es aber nicht. Wenn alles in der Schleife schneller abgearbeitet ist, als der DAQmx deine gewünschte Anzahl von Daten zur Verfügung stellen kann, dann dauer die Schleife genau solange, wie der MAX braucht um diese Anzahl von Daten zu sampeln. Wenn die Verarbeitung aber langsamer ist, als Anzahl*Abtastrate, dann dauert die Schleife eben solange wie die Verarbeitung braucht - nur dass dann irgendwann der DAQmx-interne Puffer überläuft. Du solltest also zur Überprüfung die Dauer der While-Schleife messen. Der Wert muss kleiner gleich der Updaterate sein. Oder du überprüfst die Anzahl der Daten im DAQmx-Puffer. Der Wert darf zwar schwanken, aber nicht hochlaufen.
Zitat:Im Blockpanel meines Sample-VIs bestimme ich über die Eingänge des DAQmx-Read-VIs wie schnell (Updaterate) und wie viel Samples/Update (Samplerate) ich auslese. Richtig?
Im Prinzip richtig.
Zitat:Du würdest die Prüfalgorithmen ebenfalls ins Sample-VI packen, aber die Eventstructur, in welcher ich die Reaktion auf einen anschlagenden Prüfalgorithmus hineinschreiben möchte, in ein anderes VI auslagern? (z.B. über Melder oder Queue die Info: Alarm XY ausgelöst)
Ja.
Zitat:Mein Sample-VI soll nur einmal eingestellt werden (Updaterate + Samplerate). Dann soll die Datenerfassung einfach konstant im Hintergrund laufen.
Das ist sinnvoll.
Zitat:Die Parameter zum Initialisieren des Sample-VI sind alle in der FGV gespeichert. Stellt der User während der Programmlaufzeit im Menü die Einstellungen um, so muss er das Sample-VI Neustarten, damit diese wirksam werden.
Ein Neustart ist zwar programmtechnisch gesehen nicht unbedingt notwendig (Parameteranpassungen kann man auch online machen). Wenn das aber applikationsspezifisch so vorgesehen ist, wird es so gemacht ...
Ja, und jetzt halt zu den unangenehmen Sachen: Race-Conditions.
Siehe Bild RaceConditions: Auch FGVs, gerade wenn sie so verwendet werden, wie du es (bisher) tust, müssen sequenziert werden. Bedenke folgendes: genau in dem Moment, wenn die eine Sequenz die Daten aus der FGV herausgelesen hat und im Bundle bearbeitet, macht eine parallele, also nicht sequenzierte Task genau das selbe. Frage: welche Daten stehen letztendlich in der FGV und was ist mit den Daten der anderen Sequenz?
Siehe Bild GanzBöseRaceCondition:
Theoretisch können die FGV-Zugriffe in den beiden Bildern gleichzeitig auftreten. Welche Daten stehen am Schluss in der FGV? Das Problem hierbei ist, dass es hier zu RaceConditions nur ganz, ganz selten kommt - und weil das so selten vorkommt, findest du das im Debugger nicht.
Die Lösung an sich ist ganz einfach:
Einen weiteren Case (Enumerator) in der FGV definieren, und die Daten per Variant in die FGV schieben: Die FGV aufrufen und in ihr arbeiten kann immer nur einer - der andere muss warten.
Siehe Bild RaceCondition II (schade, dass du kein LV2014 hast, da kann man so schöne Pfeile mit Hinweisen machen).