LabVIEWForum.de - Mehrere Instanzen einer funktionalen globalen Variablen?

LabVIEWForum.de

Normale Version: Mehrere Instanzen einer funktionalen globalen Variablen?
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo,

ich habe eine sub-vi konstruiert die ich als funktionale globale Variable verwende. Im wesentlichen besteht sie aus 2 als Schieberegister verwendeten arrays, zur Aufnahme von x-y Werten. Ziel ist, dass in einer Hauptschleife Daten gemessen werden, und live in einer parallelen, aber langsamer laufenden Schleife die Daten graphisch dargestellt werden, und außerdem gewisse mathematische Funktionen (laufender Mittelwert, Steigung...) auf die arrays angewendet werden.
Das funktioniert soweit auch ganz gut. Trotzdem wäre ich auch dankbar über Hinweise darüber wie man alternativ vorgehen könnte.

Nun habe ich allerdings eine weitere Anwendung, bei der ich mehrere verschiedene Signale erfassen muss. Meine Frage ist nun, ob es möglich ist ähnlich wie bei objektorientierter Programmierung, mehrere "Instanzen" dieser subVI zu schaffen und wenn ja wie?

Vielen Dank im Vorraus,
Johannes
' schrieb:mehrere "Instanzen" dieser subVI zu schaffen und wenn ja wie?
Im Prinzip sollte das auch funktionieren. Mir fallen auf Anhieb mehrere Möglichkeiten ein:

Erstens: Ein Array im SubVI.
Du kannst ein Array machen mit sovielen Clustern (das sind die bisherigen Schieberegister), wie du Instanzen haben willst. Dann rufst du dieses SubVI mit dem zusätzlichen "Instanz-Parameter" ArrayIndex auf.

Zweitens: invariantes/reentrantes SubVI
Man kann ein SubVI (siehe Einstellungen VI) so einstellen, dass pro Erscheinen im Sourcecode auch tatsächlich ein ausführbares SubVI gestartet wird. Damit ist eine Instanzierung als solche möglich. Im Falle einer funktionalen globalen Variablen ist folgendes zu bedenken: Ich will eine bestimmte Instanz ja mehrmals aufrufen - was mit dem invariant aber an sich nicht geht, da öfteres Vorkommen im Sourcecode. Daher müsste man jede einzelne Instanz über den VI-Server per Referenz öffnen und dann mittels dieser Referenz überall im Sourcecode darauf zugreifen.

Beide Möglichkeiten haben den Vorteil, dass man die Anzahl der Instanzen nur Laufzeit festlegen kann. Mir fällt noch eine dritte Möglichkeit ein, bei der die Anzahl an sich bereits zur Entwicklungszeit festgelegt wird: Ein SubVi machen mit so vielen Cases, wie Instanzen sein sollen. In jedem Case das selbe bereits bestehende SubVi als invariant. Das neue SubVI hat dann noch einen Eingang Instanznummer.

Ob es mit LVOOP eine einfachere Lösung gibt, weiß ich nicht. Ich würde die mit dem Array im SubVI machen.
Erst einmal danke für deine Antwort.

Auf deine erste Möglichkeit bin ich vorher auch schon selber gekommen, und ich denke es ist im konkreten Fall auch die einfachste/eleganteste Lösung. Falls sich jemand dafür interessiert habe ich es einfach mal hochgeladen:
[attachment=16350]

Aber aus reiner Neugier, bzw. da es eventuell später doch mal nützlich sein könnte, wollte ich doch auch noch die 2. Variante verstehen.

Jetzt habe ich nur das Problem dass ich nicht weiss wie ich "mittels dieser Referenz überall im Sourcecode darauf zugreifen" kann. Ich habe eigentlich gedacht dass das mittels der "Call by reference node" vi geht. Aber wenn ich eben diese verwende wird unabhängig davon welche RefNum ich an den reference Eingang lege immer die als letzte geöffnete vi benutzt.

Ich habe mal meinen aktuellen Versuch hochgeladen, falls jemand die Zeit hat zu suchen wo der Fehler liegen könnte wäre ich sehr dankbar. Einfach die XYBuffer_test.vi öffnen und eventuell zu den subvis durchclicken.

[attachment=16349]
LabVIEW Version: 8.0
' schrieb:Trotzdem wäre ich auch dankbar über Hinweise darüber wie man alternativ vorgehen könnte.
Hier mal das gewünschte alternative Beispiel. Es handle sich um 2 Haupt-Vis, das eine ist ein Datenerzeuger, das andere ein Datenverbraucher. Du mußt sie beide aufrufen und starten. (Du kannst aber auch, welches ist egal, das ein VI zum Sub-VI des anderen machen, indem Du das einem mit dem anderen aufrufst.)
Ob sie beide gleich schnell laufen, oder eines schneller als das andere oder umgekehrt, ist egal, es funktioniert immer.
Es ist egal welchse Du stoppst, es wird dann immer das andere mitgestoppt.
Das Ganze ist unendlich modifizierbar. Sicherlich ist es jetzt nicht genau das was Du brauchst, nur eines ist sicher: Die Datenübertragung über Funktionale GV ist nicht der Königsweg. Sondern die richtigen Stichworte sind: Queues (oder Melder), Erzeuger-Verbraucher Struktur (Producer-Consumer).
Ich kann nur empfehlen: Mache Dich hier schlau, und dann mache mit den neuen Erkenntnissen an Deinem Projekt weiter. Es tut sich einem eine ganz neue Welt auf - zumindest kann ich das von mir so sagen.
Lv80_img[attachment=16359]
[attachment=16360]
Hi Lucki,

danke für deine Antwort, das sieht echt interessant aus, ich werde bei Gelegenheit mal probieren meine Anwendung entsprechend umzuschreiben. Ich habe aber auch gleich schon 2 Fragen dazu:

1) Spricht irgendetwas dagegen die 3 queue vi's in der Schleife zu einer "prepend or shift" vi zusamenzufassen?
Oder alternativ das Schieberegister mit NaN zu initialisieren und dann nur zu schieben? In einer größeren vi fände ich dass es die Gesamtübersicht verbessern würde zusätzlich Werte mit einer einzigen sub vi speichern zu können.

2) Wenn ich auf den Stopp Knopf der einen vi clicke wird ja die 2. vi über die Fehlermeldung gestoppt. Irgendwie widerstrebt es mir ein bischen willentlich Fehlermeldungen zu produzieren (Ich weiss aber selber nicht genau warum). Ist das eine weit verbreitete Methode um verschiedene vi's zu schliessen?

Ach ja, ich wäre natürlich weiterhin an Antworten zur Instanzierung von functional globals interessiert.
' schrieb:1) Spricht irgendetwas dagegen die 3 queue vi's in der Schleife zu einer "prepend or shift" vi zusamenzufassen?
Nein, absolut nicht. Allerdings ist man bei NI auch schon auf die Idee gekommen, daß das sinnvoll wäre, und deshalb gibt es in LV8.6 genau diese Queue-Funktion zusätzlich. Die nennt sich: "Element hinzufügen, verlustbehaftet"
Der Unterschied:
Nicht verulstbehaftetes hinzufügen:
Wenn die Queue voll, wird bis zum Timeout (oder unbegrenzt lange) gewartet, bis (in einer anderen Schleife) ein Element entfernt wurde.
Verlustbehaftetes Hinzufügen (ab LV8.6):
Das neue Element wird immer ohne Timeout hinzugefügt, bei volle Queue wird das älteste Element entfernt.
Zitat:2) Wenn ich auf den Stopp Knopf der einen vi clicke wird ja die 2. vi über die Fehlermeldung gestoppt. Irgendwie widerstrebt es mir ein bischen willentlich Fehlermeldungen zu produzieren (Ich weiss aber selber nicht genau warum). Ist das eine weit verbreitete Methode um verschiedene vi's zu schliessen?
Es geht schon, aber es ist schon klar, daß es sich hier nicht um ein robustes Design handelt.
Wenn das Sub-VI wegen eines anderen Fehlers beendet wird, (also nicht wegen eines beabsichtigten Stops), dann erfährt des Haupt-VI nichts davon und sendet weiter seine Daten (bzw. versucht sie zu empfangen).
Eine profesionelle Lösung zur Fehlerbehandlung wurde von Johnson/Jennings vorgeschlagen: Sammlung aller Fehlerrdaten aller parallel laufenden Sub-Vis in einer gesonderten Fehler-Queue, und zentrales Auslesen der Queue im Haup-VI.
Das hat allerdings mit dem zentralen Stoppen nicht direkt etwas zu tun. Und jetzt wurde ich zum Essen gerufen, also abrupter Stop hier und jetzt.

Gruß Ludwig
:rofl:Guten Appetit. Wink

Gruß Markus

' schrieb:Und jetzt wurde ich zum Essen gerufen, also abrupter Stop hier und jetzt.
Referenz-URLs