LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PICAM SDK, Call Library Function, crashes LV

Solved!
Go to solution

@rolfk wrote:

 

The way to go for this without creating a wrapper DLL is to configure this parameter as a pointer sized integer passed by reference and then using LabVIEW::MoveBlock() or similar calls to copy out the information from that pointer. And obviously call Picam_DestroyCameraIDs() afterwards for this pointer or you create memory leaks.


I see. Can you point me to a document/post/white paper explaining the procedure how to do this? Thanks very much!

 

edit: I have found this page, I try to figure out how to implement it in my case: https://forums.ni.com/t5/Developer-Center-Resources/Dereferencing-Pointers-from-C-C-DLLs-in-LabVIEW/...

0 Kudos
Message 11 of 89
(1,750 Views)

Timeout for further edit, anyway 🙂

So under the above mentioned link, I wonder if the section "Special Case: Dereferencing Arrays" is the appropriate procedure in my case. Now I just try to hit my head to figure out how to implement it 🙂 Nice to feel, how much i am lost in this, potential to learn a lot!

Any hint is welcome, thanks! 🙂

0 Kudos
Message 12 of 89
(1,746 Views)

This is how I would go about this. The Call Library Nodes that call into LabVIEW are correctly setup. The others you will have to properly update.

PICAM Get Camera ID.pngPICAM Get Available Camera IDs.png

Rolf Kalbermatter
My Blog
Message 13 of 89
(1,737 Views)

Thanks! I will test it tomorrow morning! 🙂

0 Kudos
Message 14 of 89
(1,727 Views)

rolfk:

 

Thanks very much, I managed to make a working version based on your example! 🙂 I had to replace those strings with clusters each containing 64 U8 numeric controls, in order to match with my TypeDefs...

Can you have a look if I do everything fine? If you tell me the highest LV version number you can open, I can backsave the lvlib and attach it here zipped (in case you need the typdefs/subVIs).

 

PICAM.lvlib_Get_Available_camera_IDs.png

 

 

0 Kudos
Message 15 of 89
(1,708 Views)

The cluster should not be necessary. The string parameter is configured to have an incoming minimum size equal to the size parameter, which is 64. Since the parameter is configured as a C String pointer, LabVIEW also will automatically scan the returned string for a NULL character and terminate it there, then converting it into the LabVIEW string handle.

The advantage in this way is that you directly end up with real LabVIEW string handles to return from the VI.

Rolf Kalbermatter
My Blog
Message 16 of 89
(1,694 Views)

@rolfk wrote:

The cluster should not be necessary. The string parameter is configured to have an incoming minimum size equal to the size parameter, which is 64. Since the parameter is configured as a C String pointer, LabVIEW also will automatically scan the returned string for a NULL character and terminate it there, then converting it into the LabVIEW string handle.

The advantage in this way is that you directly end up with real LabVIEW string handles to return from the VI.


That is true that it would be more comfortable to use strings directly in this cluster, but then I get more difficulties in some other steps. Namely, if I want to use the "Picam_OpenCamera()" function, then I need to use again the MoveBlock "trick". If I use my recent typedef cluster with those two cluster element (each having 64 U8 elements), then I can just easily feed this data into a single CLN.

PICAM_API Picam_OpenCamera(
const PicamCameraID* id,
PicamHandle* camera);

So the state machine which I will create later for this CCD camera operation will have the following steps:

  1. Use the Get_Available_cameraIDs
  2. User can select which camera to be used from the resulted array list
  3. The state machine will feed this selected PicamCameraID (PicamCameraID.ctl typdef) value into the OpenCamera VI (Picam_OpenCamera() function) (single CLN inside this VI)
  4. Setting parameters, doing acquisition, etc...
  5. Releasing resources, closing handle and library resources

 

0 Kudos
Message 17 of 89
(1,688 Views)

So I can just directly feed back the cameraID into the Open_camera.vi, and using single CLNs in these VIs:

 

PICAM.lvlib_TESTER.png

Message 18 of 89
(1,684 Views)

@rolfk wrote:

The way to go for this without creating a wrapper DLL (....)


Just a note, that there is a LabVIEW toolkit available for purchase, called SITK: http://www.rcubedsw.com/sitk-with-labview.html

I installed the trial version, and as I see it polluted my user.lib palette root level with its VIs! Smiley Mad

Anyway, I also found that this toolkit put a new DLL file into my LV2017 folder, called "LabVIEW_interface.dll" or something like that. So I guess the developer(s) of this toolkit went on the wrapper route, and calling the wrapper dll via the CLNs...

 

My project developing the required functionalities for the Princeton CCD via the PICam library going well, I think it will not be a problem any more thanks to you rolfk and nathand! 🙂 Therefore, we decided we do not purchase the above mentioned toolkit, unless we get into real troubles during the next step of our project: developing a similar lvlib for a Horiba CCD camera...

 

I have already all the camera ID functions, error handling, temperature setpoint/reading. I have only left some other functions to create, like gain/readout speed, ROI definition and finally the acquisition control/data read out. I had a quick look at these function definitions, and I was happy because I did not see (so far) the evil "pointer to pointer" types 😄

 

After the project when we do the real hardware tests with the PI and Horiba cams in the laser-Raman system, and the results are satisfying, I will publish these LV libraries under the community docs site. Some people might find them useful in the future...

Message 19 of 89
(1,673 Views)

May I ask for some more help please? 🙂

Practically all the functions we need are implemented (and successfully tested) now, the only missing part is to specify a single ROI before camera acquisition.

I list here the function prototype, and the C tpydef structs (piint is I32):

 

typedef struct PicamRoi
{
piint x;
piint width;
piint x_binning;
piint y;
piint height;
piint y_binning;
}

Then, another struct is definied, based on the above one:

typedef struct PicamRois
{
PicamRoi* roi_array;
piint roi_count;
}

And I need to call the following function from LabVIEW, using CLN(s):

Picam_SetParameterRoisValue(
PicamHandle camera,
PicamParameter parameter,
const PicamRois* value);

The "camera" is the opened camera handler, the "parameter" is an U32 with value of 67436581 (based on the header file), but I just cannot figure out, how to input the "PicamRois*" parameter, which is a struct containing an array struct (we only want to use a single ROI by the way) plus a I32 counter (number of definied ROIs).

 

I tried different configurations, see like this below, but I feel this will not work with my "intuitive" try-and-fail method 😄 I reached to a point where at least LV is not crashing after the DLL call, and I get an error info back from the DLL: "InvalidParameterValue". So it can be due to either because I specify wrong ROI parameter set (i think not, the specified values seem to be OK), or wrong data format...

 

I attached the subVI, and the two LV typdef controls.

Thanks!

 

PICam.lvlib_SetROI.png

 

 

EDIT: for sure I am doing it wrong, since I cannot give a LabVIEW array to the DLL, since in C arrays are fixed sized. I guess I need to use again MoveBlock functions with CLN, I just having difficulty to figure out exactly how 🙂 I also found this: https://lavag.org/topic/16106-managing-structures-with-array-of-structures-as-dll-input-parameter/

 

EDIT2: would it be difficult to create a little wrapper DLL, which contains a C function, which translates the LabVIEW cluster into a format what the picam.dll can handle fine? Is there any whitepaper at ni.com how to do this? Anyway, i also start to google for this.

Download All
0 Kudos
Message 20 of 89
(1,663 Views)