DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - Druckversion +- LabVIEWForum.de (https://www.labviewforum.de) +-- Forum: LabVIEW (/Forum-LabVIEW) +--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein) +---- Forum: Datenerfassung (DAQ) (/Forum-Datenerfassung-DAQ) +---- Thema: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format (/Thread-DAQ-Anzeige-in-seperatem-VI-und-Speicherung-in-TDMS-Format) |
RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - IchSelbst - 23.11.2015 23:57 (23.11.2015 14:56 )m.werle schrieb: -> Unzyklische, unendlich lange BeaufschlagungJa, 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). RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - m.werle - 24.11.2015 14:36 (23.11.2015 23:57 )IchSelbst schrieb: Ja, und jetzt halt zu den unangenehmen Sachen: Race-Conditions.Ok, Verriegelung eingebaut. Nach diesen ganzen Initialisierungen kommt eine Sequenz in der 100ms gewartet wird, danach wird die Schleife gestartet. Bzw. bei dem Clustern zur AVG/RMS/Peak-Wert-Berechung habe ich jetzt die Schieberegister eingebaut. Zitat:Siehe Bild GanzBöseRaceCondition:Den Teil hier verstehe ich allerdings nicht. Hier gibt es zwei Aufrufe der FGV, allerdings werden beim ersten Aufruf weder Werte im FGV geändert, noch entnommen. Das einzige, was als Datenausgang wichtig ist, ist der Clustertyp, also die Form in welcher die Daten im FGV gespeichert sind. Diese ändert sich aber im gesamten Programm nicht während der Laufzeit. Das ist nur für die "Bundle by Name" Funktion wichtig. Wo soll es hier zu einem Raceconditionfehler kommen? Ich lasse mir die AI-Signale ja als Waveform ausgeben. (Ist dann ein Cluster mit den Infos: t0 (Startzeit der Messung), dt (Zeitdifferenz zwischen zwei Samples) und Y (einem Array aus N Samples) Bei langen Betrieben führt das aber doch zu einer Ungenauigkeit, wenn nicht bei jedem Datenpaket ein eigener Zeitstempel dazu kommt, sondern die aktuelle Uhrzeit berechnet wird mit Jetztzeit = Startzeit + dt*N (mit N = Sampleanzahl) Vor allem, wenn der Timer der Messbox asynchron zum Timer meines Rechners läuft. Dann gibt es weniger/mehr Samples wie eigentlich eingestellt. Aktuell simuliere ich mit MAX ein AI-DAQ-Gerät. Dort habe ich einen Task eingestellt (Analoge Signalerfassung) im Kontinuierlichen Modus. Dazu gibt es noch zwei Einstellungen, die ich treffen kann: Samples to Read (Bufferspeicher) und Samplerate (Hz). Wenn ich in MAX den Task umstelle und oben links auf SPeichern drücke, scheint dies allerdings keine Auswirkung auf mein Labviewprogramm zu haben. Mein Sample-VI hat eine Zyklusdauer abhängig von der eingestellten Updaterate und Samplerate. (Scheint als wär die Samplerate des AI-Tasks des simulierten Geräts auf 1kHz eingestellt.) Bei einem zu lesenden Sample braucht mein Sample-VI 1ms. Bei einem vielfachen davon ein vielfaches. Bist übrigens ne risengroße Hilfe. ToDos: - DAQmx für die Erfassung der DI-Signale (Kann ich in MAX nicht sehen, welches der dort aufgelisteten simulationsfähigen Devices mir eine kontinuierliche DAQ von DI-Signalen erlaubt? :/ Heißt wohl durchprobieren...) - Prüfalgorithmen für diese programmieren. In welcher Form soll ich den Alarm speichern, wenn dieser aufgetreten ist? In einer Enum Variablen? Dann kann die Reaktion in einer Casestruktur abgehandelt werden. - Thema Datenlogging: Ist Speichern in TDMS Format überhaupt sinnvoll? Was ist mit Datalog-Dateien? Oder einer simplen txt-Datei? Die Daten sollen später zum Beispiel leicht in Excel importiert werden. Hab die Anweisung bekommen, dass einfach in eine txt-Datei zu packen, allerdings kennt sich von denen auch niemand groß mit den verschiedenen Datentypen aus. Wäre auf jedenfall recht kompatibel und wieder einfach auszuwerten. Anzeige-VI, Datenlogging: So die Datenerfassung und deren Anzeige soll immer laufen, das Datalogging lässt sich durch den Benutzer starten/stoppen. Ich habe ein Boolsches Control auf dem FP der Anzeige, bei True soll geloggt werden, bei False nicht. In meinem FGV habe ich die wichtigen Daten wie Speicherort, Dateiname und wie viel % der gesammelten Samples auch gespeichert werden sollen. Es ist bestimmt nicht sinnvoll in jedem Zyklus (während des Dataloggingprozesses) diese Informationen (Dateiname, Speicherort, etc.) aus dem FGV zu lesen. Soll ich in einer Eventstruktur im Anzeige-VI einen Value-Change der Boolschen Variable "Datalogging" feststellen und bei Start des Datalogging den Prüfalgorithmus einbauen, ob die Datei bereits besteht, sie gegebenfalls erstellen und dann die wichtigen Parameter (Dateiname, Speicherort, etc.) in lokale Variablen überschreiben? Jeden Zyklus gibts dann eine Caseabfrage: Datalogging? (False: Nichts tun; True: Neuen Datensatz an die Datei anhängen) RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - IchSelbst - 24.11.2015 15:30 (24.11.2015 14:36 )m.werle schrieb: Den Teil hier verstehe ich allerdings nicht. Hier gibt es zwei Aufrufe der FGV, allerdings werden beim ersten Aufruf weder Werte im FGV geändert, noch entnommen. Das einzige, was als Datenausgang wichtig ist, ist der Clustertyp, also die Form in welcher die Daten im FGV gespeichert sind. Diese ändert sich aber im gesamten Programm nicht während der Laufzeit. Das ist nur für die "Bundle by Name" Funktion wichtig. Wo soll es hier zu einem Raceconditionfehler kommen?Es geht ums Prinzip. Das Verfahren "Daten aus FGV lesen, diese Daten extern ändern, Daten nach FGV schreiben" ist per se Race-Conditions-anfällig. Das Problem "RaceCondition" tritt dann auf, wenn genau das selbe Verfahren (mit dem selben Datencluster) parallel - also z.B. in einem anderen VI - gleichzeitig(!) gemacht wird. "Gleichzeitig" auslesen scheint nur kein Problem, ist aber auch schon eines. Hauptproblem ist das zurückschreiben. Einer der beiden ist immer der Erste, der hat verloren, und einer ist der zweite, dessen Daten stehen letztendlich in der FGV. Grundsätzlich umgangen wird dieses Problem eben dadurch, dass die Änderung in der FGV stattfindet. Dann stehen nämlich zuerst die Daten des Ersten drinnen - die dann nämlich der zweite bereits ausliest ... Problem ist auch nicht der aktuelle Stand des Programmes, sondern die Änderung, die erst in zwei Wochen kommt: Dann fällt nämlich deinem Chef ein, dass er einen weiteren Parameter, diesmal online geändert, im Sample-VI haben will. Und den würdest du dann, weil's eben so ganz einfach geht, per FGV übertragen - und schon hast du den gleichzeitigen Zugriff in zwei VIs. Du siehst, dein Programm läuft wochenlang ohne erkennbaren Fehler und plötzlich nach einer Änderung funktionieren Sachen nicht mehr, die mit der Änderung gar nichts zu tun haben. Den Rest kuck ich mir heute Abend mal an. (24.11.2015 14:36 )m.werle schrieb: DAQmx für die Erfassung der DI-Signale (Kann ich in MAX nicht sehen, welches der dort aufgelisteten simulationsfähigen Devices mir eine kontinuierliche DAQ von DI-Signalen erlaubt? :/ Heißt wohl durchprobieren...)Ich gehe davon aus, dass jede DAQmx-Karte für DIs eine kontinuierliche Erfassung von DIs machen kann - zumindest habe ich noch nie das Gegenteil gehört. Zitat:Prüfalgorithmen für diese programmieren. In welcher Form soll ich den Alarm speichern, wenn dieser aufgetreten ist? In einer Enum Variablen? Dann kann die Reaktion in einer Casestruktur abgehandelt werden.Strikter Enum ist sehr gut. Enum einfach auf Case-Struktur geben. In der Case-Struktur lässt du den Standard-Fall weg! Wenn du jetzt einen Enum-Wert hinzufügst, bringt dir die IDE einen Fehler - und du weist ganz genau, welche Case-Strukturen du noch bearbeiten musst. Zitat:Thema Datenlogging: Ist Speichern in TDMS Format überhaupt sinnvoll? Was ist mit Datalog-Dateien? Oder einer simplen txt-Datei? Die Daten sollen später zum Beispiel leicht in Excel importiert werden. Hab die Anweisung bekommen, dass einfach in eine txt-Datei zu packen, allerdings kennt sich von denen auch niemand groß mit den verschiedenen Datentypen aus. Wäre auf jedenfall recht kompatibel und wieder einfach auszuwerten.Eigentlich würde mir TDMS am besten gefallen. Das ist einfacher als Textdateien. Zum Auswerten würde ich Diadem empfehlen. Dummerweise wollen immer alle mit Excel arbeiten. Auch Excel kann TDMS-Files importieren (allerdings nur bis zu einer maximalen Größe, glaub ich). Speziell für Excel würde man CSV-Dateien machen. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - IchSelbst - 24.11.2015 15:49 (24.11.2015 14:36 )m.werle schrieb: Soll ich in einer Eventstruktur im Anzeige-VI einen Value-Change der Boolschen Variable "Datalogging" feststellen und bei Start des Datalogging den Prüfalgorithmus einbauen, ob die Datei bereits besteht, sie gegebenfalls erstellen und dann die wichtigen Parameter (Dateiname, Speicherort, etc.) in lokale Variablen überschreiben?Genau, so macht man das: Ereignis-orientiert arbeiten. Ohne Ereignis tut man auch nichts - und beim Nichtstun macht man die wenigsten Fehler ... Zitat:Jeden Zyklus gibts dann eine Caseabfrage: Datalogging? (False: Nichts tun; True: Neuen Datensatz an die Datei anhängen)Genau. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - m.werle - 24.11.2015 16:37 Racecondition und FGV: Ich möchte vermeiden, dass ich Daten auslese verändere und danach die veränderten Daten wieder zurück ins FGV schreibe (Aktion 1), da in der Zwischenzeit ein anderes VI auf die selbe Weise darauf hätte zugreifen können und fälschlicherweise die unveränderten Daten entnimmt, wodurch Aktion 1 ignoriert worden wäre. Soweit verstanden. Zitat:Die Lösung an sich ist ganz einfach:Was für ein zusätzlicher Case? Diese grundsätzlichen Funktionen "Auslesen" und "Reinschreiben" kann ich ja nicht umgehen. Solange ich aus dem FGV nur Daten auslese, oder solange die reingeschriebenen Daten unabhängig von den vorigen Daten im FGV sind, kommts erstmal zu keinen Problemen, soweit ich das sehe. Bei dem Bild "GanzBöseRaceCondition" ist es ja beispielsweise auch egal, ob zwischen diesen Aufrufen irgendein anderes VI auf das FGV zugegriffen hat. 1. Aufruf: Liest das Cluster aus, um es für die Funktion "BundleByName" als "Clustertyp" zu benutzen. Welche Werte im Cluster stehen ist egal, es ist nur wichtig, welche Variablen überhaupt im Cluster stehen und wie diese heißen. 2. Daten reinschreiben: Hier wurde das "BundleByName" Cluster mit Variablen gefüttert und überschreibt so bestimmte Variablen im FGV. Dein Vorschlag ist nun Variant-Cluster einzulesen, und im FGV dieses Cluster zu typisieren und dann die richtigen Variablen zu überschreiben? oO Kontinuierliche Erfassung Digitale Signale DAQmx: Hatte in MAX ein paar simulierte Devices erwischt, die nur "On Demand" Signale erfassen konnten. Aber hat sich geklärt. Datalogging Dateiformat: Ich informier mich mal nochmal über TDMS, txt und CSV. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - IchSelbst - 24.11.2015 20:24 (24.11.2015 16:37 )m.werle schrieb: Was für ein zusätzlicher Case? Diese grundsätzlichen Funktionen "Auslesen" und "Reinschreiben" kann ich ja nicht umgehen.Anstatt Daten aus der FGV zu lesen, im Cluster IDC_AVG zu ändern und den geänderten Cluster wieder zurückzuschreiben, machst du folgendes: Die FGV bekommt einen neuen Enumerator-Wert "Set_IDCAVG" und einen Variant-Eingang, an dem der double-Wert IDC_AVG angeschlossen wird. Im FGV bekommt die Case-Struktur einen neuen Case "Set_IDCAVG". In diesem Case wird der Variantwert in einen Double gecastet und im Datensatz, der im Schieberegister liegt, gespeichert. Selbstverständlich kann man anstelle nur eines double-Wertes auch einen Cluster machen aus den drei AVG-Werten. Zitat:Bei dem Bild "GanzBöseRaceCondition" ist es ja beispielsweise auch egal, ob zwischen diesen Aufrufen irgendein anderes VI auf das FGV zugegriffen hat.Wenn zwischen diesen beiden Zugriffen auf die FGV jemand anders genau das selbe macht (Auslesen, Ändern, Reinschreiben irgendwelcher Daten aus dem selben Datensatz), dann ist die Arbeit des anderen umsonst: Dessen Daten werden vom ersten Prozess beim Zurückschreiben überschrieben. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - m.werle - 26.11.2015 09:49 (24.11.2015 20:24 )IchSelbst schrieb:Ok, jetzt hab ich die Umsetzung ganz kapiert.(24.11.2015 16:37 )m.werle schrieb: Was für ein zusätzlicher Case? Diese grundsätzlichen Funktionen "Auslesen" und "Reinschreiben" kann ich ja nicht umgehen.Anstatt Daten aus der FGV zu lesen, im Cluster IDC_AVG zu ändern und den geänderten Cluster wieder zurückzuschreiben, machst du folgendes: Die FGV bekommt einen neuen Enumerator-Wert "Set_IDCAVG" und einen Variant-Eingang, an dem der double-Wert IDC_AVG angeschlossen wird. Im FGV bekommt die Case-Struktur einen neuen Case "Set_IDCAVG". In diesem Case wird der Variantwert in einen Double gecastet und im Datensatz, der im Schieberegister liegt, gespeichert. Selbstverständlich kann man anstelle nur eines double-Wertes auch einen Cluster machen aus den drei AVG-Werten. Zitat:Zitat:Bei dem Bild "GanzBöseRaceCondition" ist es ja beispielsweise auch egal, ob zwischen diesen Aufrufen irgendein anderes VI auf das FGV zugegriffen hat.Wenn zwischen diesen beiden Zugriffen auf die FGV jemand anders genau das selbe macht (Auslesen, Ändern, Reinschreiben irgendwelcher Daten aus dem selben Datensatz), dann ist die Arbeit des anderen umsonst: Dessen Daten werden vom ersten Prozess beim Zurückschreiben überschrieben. Laufzeitfehler treten nur auf, wenn ich Werte(! nicht konstante Strukturen) aus dem FGV auslese, diese im Programm ändere und während dieses Prozesses, bevor ich die veränderten Werte wieder ins FGV geschrieben habe, ein anderes Programm die selben Werte (allerdings noch unverändert) aus dem FGV ausliest, verändert um sie anschließend ebenfalls wieder ins FGV schreiben möchte. Edit: Die Werte werden doch entnommen, nicht nur die Struktur. Der Rest dieses Beitrags ist zwar nicht direkt falsch, aber unwichtig... Programm A liest Wert X aus FGV, inkrementiert ihn. Programm B liest Wert X aus FGV, dekrementiert ihn. Programm A speichert inkrementierten X-Wert ins FGV zurück. Programm B speichert dekrementierten X-Wert ins FGV zurück. -> Laufzeitfehler. Das Inkrementieren von Programm A wurde einfach übergangen und war nutzlos. X ist am Ende eins kleiner wie am Anfang. Wenn beide Programme hintereinander gearbeitet hätten, wäre X gleich geblieben. Keine der Variablen, welche ich im FGV speichere, nutze ich auf diese Art und Weise. Ich habe lediglich Grenzwerte und Parameter gespeichert. Die werden vom User eingestellt und später während der Laufzeit ausgelesen. (Teilweise auch nur einmalig, deshalb müsste ich das Sample-VI auch schließen und neustarten, um eine Änderung gewisser Parameter auch wirksam werden zu lassen. Inline-Umsetzung könnte da komplizierter sein und ist auch gar nicht nötig.) Ein paar andere Variablen, wie das Steuersignal zum Beispiel oder ein paar Messwerte, werden zwar auch gespeichert. Hier kann es aber meiner Meinung nach auch nicht zu Laufzeitfehlern kommen. Wenn ausgelesen wird, dann für andere Funktionen. Wenn reingeschrieben wird, dann unabhängig davon, was vorher drin stand. Wenn deine vorgeschlagene Änderung die Performance verbessert, würde ich sie trotzdem gern umsetzen. Sonst spar ich mir die Arbeit. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - m.werle - 27.11.2015 13:15 Hab mein FGV mal nach deinem Vorschlag umgeändert. Hab festgestellt, dass die Funktion "Bundle by Name" zur Clusterbildung ja alle Werte überschreibt. Jetzt versteh ich auch, warum du meinst, dass es da zu bösen Raceconditions kommt. RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - GerdW - 27.11.2015 13:27 Hallo m., Zitat:Hab festgestellt, dass die Funktion "Bundle by Name" zur Clusterbildung ja alle Werte überschreibt.Falsch! Sie überschreibt/ersetzt NUR die Werte, die du namentlich auswählst! RE: DAQ-Anzeige in seperatem VI und Speicherung in TDMS Format - m.werle - 27.11.2015 15:06 In LV2010 werden alle Werte vom Input Cluster genommen, die ausgewählten Werte werden überschrieben, und das ganze ins Outputcluster geschrieben. |