LabVIEWForum.de
CCD Kamera mit externem Trigger über DLL ansteuern - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: CCD Kamera mit externem Trigger über DLL ansteuern (/Thread-CCD-Kamera-mit-externem-Trigger-ueber-DLL-ansteuern)



CCD Kamera mit externem Trigger über DLL ansteuern - aschi - 16.06.2009 15:00

Hallo zusammen

Im Zusammenhang mit meiner Bachelorthesis möchte ich eine CCD Linien Kamera ansteueren. Zur Hardware wird ein SDK (haupsächlich für die Entwicklung mit C++) mitgeliefert, jedoch ist es auch möglich die mitgeliertete DLL mit LV nutzen.

Die Kamera hat folgende Funktionen:

Continous Frame Grabbing: Hier wird mit maximal möglicher Geschwindigkeit, Frames eingelesen und vom Computer abgeholt (maximal 4 frames im Speicher der Kamera)
Dazu habe ich ein Beispielprogram in LV und dieses Funktioniert einwandfrei.

Der andere Modus (für mich der entscheidende) ist das Frame Grabbing beim anstehen eines externen Triggers.
Dafür habe ich das Beispiel Programm ein wenig angepasst und ein DLL Call für die Funktion SetCameraWorkmode eingefügt. Soweit so gut. Wenn ich jetzt das VI starte passiert eine Weile gar nichts und dann stürzt LV entweder sofort ab oder beendet das VI mit der Meldung, dass LabVIEW-Speicher überschrieben worden sei, und LabVIEW das VI nicht weiter ausführen kann.
Ich habe heraus gefunden, dass die C-Funktion GetCurrentFrame, wenn kein externer Trigger anliegt und damit kein Frame im Speicher liegt, natürlich einen Leeren Pointer zurück gibt und deshalb das "MoveBlock" vi einen Fehler verursacht. Deshalb habe ich eine Entscheidung eingefügt, dass im Fall, dass die GetCurrentFrame Funktion einen leeren Pointer zurück gibt, das "MoveBlock" VI nicht ausgeführt wird. Danach möchte ich aber erneut schauen ob ein externer Trigger angekommen ist und damit auch ein neues Frame im Speicher ist.

LabVIEW stürtz aber trotzdem ab und diesmal kriege ich keine Fehlermeldung.

Dasselbe Problem tritt übrigens auf wenn ich im Countinous Mode die anzahl der Frames beschränke, nach einer bestimmten Zeit wird also auch hier der Speicher leer sein und zu den gleichen Resultaten führen wie oben Beschrieben.

Angehängt habe ich das angepasste LV Beispiel Programm (LV Version 8.6) und die DLL mit Headerfile und ein PDF in dem die Übergabeparameter der Funktionen beschrieben sind, das Problem dürfte jedoch sein, dass sich das VI ohne die Hardware nicht ausführen lässt, da zu beginn geprüft wird ob eine gültige Device angeschlossen ist, und die Wahrscheinlichkeit, sehr klein ist, dass jemand genau über die passende Hardware verfügt... Vieleicht kann mir ja dennoch jemand Helfen, und sagen ob das überhaupt so machbar ist, oder ob ich komplet auf dem Holzweg bin.

Freundliche Grüsse

Dominic

Lv86_img


CCD Kamera mit externem Trigger über DLL ansteuern - jg - 16.06.2009 18:26

Hallo,

ich denke, hier liegt ein möglicher Fehler:

Wenn ich auf die Schnelle richtig verstehe, dann liefert die Funktion "GetCurrentFrame" ein Array des letzten Frames zurück + zusätzliche 8 Worte. Dann müsste das Array aber in der Größe 3656, nicht 3648 vordefiniert sein!?

Dann, die Funktion gibt doch schon ein Array zurück, wieso noch das Umkopieren?

Gruß, Jens


CCD Kamera mit externem Trigger über DLL ansteuern - aschi - 17.06.2009 06:57

Hallo Jens

Dank für die Antwort. Ich habe das mal geändert und getestet. Es funktioniert... *schäm*.
Das einzige was ein bisschen unschön ist, ist dass das getcurrentframe für kurze zeit hängen bleibt wenn kein frame im speicher ist. Da ich aber recht schnell, d.H. etwa 140 mal in der sekunde ein triggersignal zur kamera schicke, kommt dieser effekt nicht so stark zum tragen.

Was ich nicht ganz verstehe ist dein einwand mit dem Array. Die Funktion gibt doch, wie ich es verstehe, einen pointer auf ein array zurück. Da ja LabVIEW Pointer nicht handeln kann, muss ich doch mit dem MoveBlock VI anhand der Pointer und einem Zielarray ein Array erstellen... Sorry, das ist das erste Projekt, in dem ich mit DLL's zu tun habe, und als wir Pointer in der C-Programmierung angeschaut haben, hab ich wohl nicht so gut aufgepasst...

Danke schön

Grüsse

dominic


CCD Kamera mit externem Trigger über DLL ansteuern - jg - 17.06.2009 21:36

' schrieb:Was ich nicht ganz verstehe ist dein einwand mit dem Array. Die Funktion gibt doch, wie ich es verstehe, einen pointer auf ein array zurück. Da ja LabVIEW Pointer nicht handeln kann, muss ich doch mit dem MoveBlock VI anhand der Pointer und einem Zielarray ein Array erstellen... Sorry, das ist das erste Projekt, in dem ich mit DLL's zu tun habe, und als wir Pointer in der C-Programmierung angeschaut haben, hab ich wohl nicht so gut aufgepasst...
Aber du übergibst doch schon an den Funktionsaufruf ein Array der passenden Größe (hast du so vordefiniert). Dabei wird in Realität nur die Adresse dieses Speicherbereiches übergeben. Und somit liegt am Ausgang der Funktion das "geänderte" Array vor, aus meiner Sicht besteht kein Bedarf mehr, jetzt noch was per Moveblock zu kopieren. Wobei du sowieso den selben Speicher auf sich selbst kopierst...

Gruß, Jens


CCD Kamera mit externem Trigger über DLL ansteuern - rolfk - 20.06.2009 19:25

' schrieb:Aber du übergibst doch schon an den Funktionsaufruf ein Array der passenden Größe (hast du so vordefiniert). Dabei wird in Realität nur die Adresse dieses Speicherbereiches übergeben. Und somit liegt am Ausgang der Funktion das "geänderte" Array vor, aus meiner Sicht besteht kein Bedarf mehr, jetzt noch was per Moveblock zu kopieren. Wobei du sowieso den selben Speicher auf sich selbst kopierst...

Gruß, Jens

Jens die Arrayübergabe an die Funktion ist hier eigentlich falsch, hat aber keine gravierenden Folgen.

SDK_POINTER_API CCDUSB_GetCurrentFrame( int Device, unsigned short* &FramePtr);

Die Syntax is C++ (würde in Standard C einen Compilierfehler geben) und besagt dass der FramePtr ein unsigned short Pointer ist der als Referenz übergeben wird, d.h. es ist ein Pointer auf einen Pointer.
Warum es geht?

Nun die Funktion schreibt in den Arraybuffer an den ersten 4 Bytes (also 2 Words) den Pointer und gibt diesen Pointer auch zurück als Funktionsrückgabewert. Der anschliessende MoveBlock Aufruf kopiert die Daten vom Funktionsrückgabewertpointer in das LabVIEW Array und überschreibt damit einfach die 4 Bytes die von der Funktion zuvor als Pointerwert hineingeschrieben wurden.

Also ein Problem ist es nicht aber eigentlich sollte der zweite Wert der Funktion als ein pointersized Integer definiert werden der als Referenz also den Pointer darauf übergeben wird. Danach kann alternativ der Funktionsrückgabewert oder dieser Pointerwert als erster Parameter für MoveBlock verwendet werden.

Der Prototyp der korrekt konfiguriereten Call Library Node sollte eigentlich so aussehen:

uintptr_t CCDUSB_GetCurrentFrame(int32_t DeviceID, uintptr_t *FramePtr);

Rolf Kalbermatter