LabVIEWForum.de - Nur ausgewählte Kanäle scannen.

LabVIEWForum.de

Normale Version: Nur ausgewählte Kanäle scannen.
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo zusammen!

Zuerst einmal grundsätzliches zu meinen Problem.
Benutze eine PCI-1202 (Pci-Karte) von ICPDAS zum Erfassen von analogen Signalen.
Da die Karte nicht über den DAQ-Assistenten angesprochen werden kann, benutze ich die Funktionen des Treibers (direkter Zugriff auf die Scan-Funktionen über die dll-Datei).
Der Ablauf zum Scannen eines Kanals ist folgender.
Ich benötige grundsätzlich 3 Funktionen, die in einer bestimmten Reihenfolge aufgerufen werden müssen. Dazu benutze ich eine Stacked Sequence.
Die erste Funktion dient dazu einen Kanal zum Scannen vorzubereiten. (Funktion addToScan)
Dann folgt eine Methode Savescan, der ich ein leeres Array zum Speichern der Messdaten zur Verfügung stellen muss. Der Rückgabewert dieser Funktion enthält die gescannten Daten, wobei zu diesem Zeitpunkt noch nicht gescannt wurde. Daher wird dieser Rückgabewert als Sequence Local in der Stacked Sequence kurzzeitig "gespeichert".
Im nächsten Schritt wird die Methode startscan aufgerufen, die den scan dann letztendlich durchführt. Einen Schritt weiter kann ich dann die Sequence Local auslesen und und die gescannten Daten verarbeiten.So weit so gut.. Bis hierhin klappt noch alles.
Nun scanne ich nicht einen Kanal sondern max. 16 Kanäle, wobei ich abhängig von einer Konfiguratio bestimmte Kanäle scannen möchte und andere nicht. Gesagt getan...
Nun geht es darum den o.g. Aufruf der Scan-Funktionen mit meiner Konfiguration abzustimmer. Also habe ich die ersten beiden Frames der Stacked Sequence, wo ich die Methoden addToScan und saveScan aufrufe, um eine Case-structure erweitert. Abhängig von einer boolschen Variablen (nämlich ob dieser Kanal gescannt werden soll) rufe ich dann innerhalb der case structure die beiden Methoden auf. Jetzt zum eigentlich Problem. Der Rückgabewert der Funktion saveScan muss ich nun über die CaseStructure tunneln, um sie als SequenceLocal zu speichern und sie später auszulesen. Das Problem: es kommen nun keine Daten mehr an, nachdem ich die Methode startScan aufgerufen habe. Das hört sich vieleicht unheimlich kompliziert an, ist aber recht simpel.
Es dreht sich eigentlich nur um die Funktion saveScan, die als Rüchkabewert die gescannten Daten liefert, welche aber zum Zeitpunkt des Funktionsaufrufes noch nicht zur Verfügung stehen. Welche daher als Sequence Local gespeichert und nach dem Aufruf der startScan-Funktion einen Frame später, die gescannten Daten enthält. Rufe ich die Funktion savescan aber innerhalb einer case Structure auf und tunnele den Rückgabewert durch die CaseStructure, um diese als SequenceLocal zu speichern, klappts nicht mehr. ...und ich hab keine Ahnung warum.
ich konnte das Vi jetzt leider nicht bereitstellen, da jede ScanFunktion über ein SubVi aufgerufen wird. Wenn also jemand wirklich Interesse an meinem Problem hat, oder meine Beschreibung nicht ganz verstanden hat (ist auch leider schwierig zu erklären , wie ich finde), dem schicke ich gerne ein Beispiel per mail.
Hoffe jemand hat eine Idee oder einen Tip,
Danke
Tom
kann das sein, dass du versuchst alle 16 Kanäle in die "Scan-Liste" mit aufzunehmen aber nur eine ausgewählte Anzahl von Kanälen einlesen wirst? Ich vermute mal stark, dass das zu einem Buffer-Overflow auf der Karte führt, NI Karten beenden dann z.B. die Erfassung mit einer Fehlermeldung. Gibt es eine Funktion in der DLL mit der du den Fehler auslesen kannst?
Danke für die Antwort!
Wie ich schon befürchtet habe bin ich nicht ganz verstanden worden.
Ich weiss auch nicht wie ich es besser erklären soll.
Also 1. bekomme ich keinen Fehler. Ich füge auch nur die Kanäle zu meiner "Scanliste" hinzu, die ich auch scannen möchte.
Diese lese ich dann auch nur aus.

Ich habe hier den entsprechenden Sourcecode in C++ gefunden für das Scannen von 2 Kanälen, anhand ich die Problematik nochmal erkläre.
P1202_AddToScan(0,0,1,0,0,0); /* CH:0 */
P1202_SaveScan(0,data[0]); /* Ch0 und Array um die Daten zu speichern(IN/OUT Parameter als Pointer) */
P1202_AddToScan(1,0,1,0,0,0); /* CH:1 */
P1202_SaveScan(0,data[1]); /* Ch1 und Array um die Daten zu speichern(IN/OUT Parameter als Pointer) */
P1202_StartScan(200,DATACOUNT); // Total sampling rate: 8M/200 + Anzahl der Abtastwerte

Um das in LabVIEW umzusetzen habe ich eine stacked sequence mit 6 Frames. In denen ich analog zu dem code die funktionen in dieser reihenfolge aufrufe.
Dabei ist die Funktion SaveScan in LabVIEW anders umgesetzt, da es in LabVIEW ja keine Pointer gibt. also gibts hier einen Input-Parameter, der ein initialisiertes Array übergeben wird, und ein Outputparameter, den ich als sequence local speichere. Im 6. und letzten Frame lese ich dann die Daten über die sequence local aus.
Soweit funktioniert das auch. Jetzt würde ich aber gerne nur den ersten oder nur den zweiten Kanal (oder beide) auslesen. Also ein kleines KonfigurationsVI erstellt mit zwei boolschen Variablen, die Angeben welcher Kanal gescannt werden soll.
Dann habe ich die Frames in denen die Funktionen addtoscan und savescan aufgerufen werden mit einer case-structure versehen und die Funktionen in die case-structure verlagert. Die boolschen Variablen mit den entsprechenden Case-Structeres verbunden, sodass nur wirklich die Kanäle in die Scanliste aufgenommen werden, die ich scannen möchte. Ausserdem musste der Rückgabewert der FUnktion addToScan über die Case-Structure getunnelt werden, um diese als sequence local anzulegen. Und genau da scheint das Problem zu liegen. Denn nun kommen im letzten Frame, wo ich die "Rückgabewerte über die sequence local" mit den Abtastwerten auslesen, keine Daten mehr an.
Also der einzige Unterschied zwischen den beiden Varianten ist, dass der eine Rückgabewert über die case-structure getunnelt wird. Da ja ganeu dieses in c++ als pointer übergeben wird, sodass die Funktion einen zu beschreibenden Speicher zur Verfügung gestellt bekommt, verhält sich das in LabVIEW ewas anders und leider auch unerwartet. Wenn jemand Erfahrung hat mit der Einbundung von Funktionen einer dll-Datei, wo genau dieser Sachverhalt vorliegt, also wo der Übergabe-/Rückgabeparameter ein Pointer ist.
Genauer kann ich es nicht beschreiben. Kann das vi leider nicht hochladen, da man die dll-Datei benötigt.

Tom
Hi,

du kannst das VI ja mal als komplette zip-Datei inkl. dll hochladen. Aber grundsätzlich mal: Wenn wir mal ein Bild von dem hätten, wärs viel einfacher. Du schreibst einen Haufen voll Text, aber je länger desto schwerer ist da durchzusteigen. Ein oder zwei Screenshots würden helfen, und auch das VI inkl. SubVIs selber, auch wenn Teile fehlen. Es muss ja hier nicht laufen, die HW haben wir ja sowieso nicht. Aber der Aufbau wär ganz interessant...

Zum Problem selber: Ich habe den Verdacht, dass das Problem am Tunnel der Case-Struktur liegt...hast du mal den Ablauf im Highlight-Modus ("Glühbirne") angeschaut und geprüft, wo was wann weitergeben wird? Ich könnte mir vorstellen, dass du im einen Fall der Case-Struktur nichts angeschlossen hast, und evtl. wird in diesen leeren Fall gesprungen und dann evtl. nur der Default-Wert weitergegeben...

Aber wie gesagt: Zeig mal was...

Gruss
A.
' schrieb:Wenn jemand Erfahrung hat mit der Einbundung von Funktionen einer dll-Datei, wo genau dieser Sachverhalt vorliegt, also wo der Übergabe-/Rückgabeparameter ein Pointer ist.

Wie Achim schon geschrieben hat, ich les das durch und mir raucht der KopfWacko

Wie die Übergabe zwischen DLL und LabVIEW laufen soll kannst du beim Konfigurieren der Call Library Node einstellen. Wenn du in LV ein Array mit einer bestimmten Länge initialisierst und das an den Eingang der CLN anschließt, dabei auswählst, dass der Parameter mit Call by Referenze übergeben wird, dann übergibt LV auch nur den Pointer zu dem Arry.

[attachment=4685]
Hab mir das heute morgen auch nochmal durchgelesen. Sorry, dass ich euch das zugemutet habeRolleyes
Ich hab im Anhang nun ein BeispielVI, dass mein Problem zeigt. Das MainVI heißt Program.vi.
Hier scanne ich zwei Kanäle. Kanal 1 unabhängig von einer case-structure und Kanal 2 innerhalb einer Case-Structure.
Für Kanal 1 bekomme ich Daten, für den zweiten kommt nix an.
Man beachte v.a.den zweiten und vierten Frame der inneren Stacked Sequence. Hab im 4. Frame der Einfachhalt halber eine boolsche Konstante benutzt.
Also nicht weiter beachten.

to i2dx: Bei mir sieht das Fenster für die EInbindung von dll-Funktionen anders aus. Liegt das an meiner LabVIEW-Version (7.1)?
Ich habe keine Möglichkeit etwas als Pointer zu übergeben. Siehe Screenshot im Anhang.

Danke!
Tom
' schrieb:to i2dx: Bei mir sieht das Fenster für die EInbindung von dll-Funktionen anders aus. Liegt das an meiner LabVIEW-Version (7.1)?
Ich habe keine Möglichkeit etwas als Pointer zu übergeben. Siehe Screenshot im Anhang.

ja, ich hab den Screenshot mit LV 8.20 gemacht.

Ich hab mal kurz in dein Programm reingeschaut, die DLL wird korrekt aufgerufen:

[attachment=4686]
Hallo!

So, hab das Problem doch letztendlich selber lösen können. Für all diejenigen die es interessiert:
Musste eigentlich nur die Initialisierung des Arrays, welches ich für die Speicherung der Abtastdaten benötige ausserhalb der case-Struktur durchführen.
Für den "true"-Fall habe ich das Array der FUnktion saveScan (innerhalb der case-Struktur) übergeben und im "false"-Fall habe ich das Array einmal durch die case-Struktur getunnelt und dann als SequenceLocal abgespeichert. Sehr Simpel eingentlich, aber ich verstehe dennoch nicht warum das auf diese Weise jetzt funktioniert.
Wenn sich das nocheinmal jemand anschauen möchte, vergleiche es mit meinem beigefügtem Beispiel vom letzten Post. (Frame 4 der inneren Stacked Sequence). Dort sieht man wie ich es vorher gemacht habe und es nicht funktioniert.

Grüße
Tom
Referenz-URLs