LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PICAM SDK, Call Library Function, crashes LV

Solved!
Go to solution

Ok, I have found one silly mistake so far (fixed VI attached), I defined the "PicamAcquisitionErrorsMask" input as an array instead of U32 (Enum). So the system is not crashing anymore at the CLN function call, but now at the first MoveBlock call. I think the main issue can be that I try to read a pointer of the "initial_readout", but also a value of the "Readout_count". Hmm, maybe I try to read only the "first part", the first 8 byte as a pointer? And then feed this to the next MoveBlock CLN... (I do not need the "Readout_count", I know it is always 1).

 

PICam.lvlib_Acquire_CCD_data_BD.png

0 Kudos
Message 31 of 89
(2,049 Views)

You don't need the first MoveBlock call. Instead, pass in the PicamAvailableData cluster. For the second MoveBlock call, initialize the destination array (this allocates memory for it, otherwise you'll likely get a crash or at least an error) and configure the target parameter as passed by Array Data Pointer. I would configure it specifically as an array of U16 rather than using Adapt To Type. Here's a snippet showing the changes (except the reconfiguration of the second MoveBlock) in LabVIEW 2015, sorry I don't have 2014 installed.

Picam_Acquire.png

Message 32 of 89
(2,042 Views)

Thanks very much! No problem with the version, I have LV2017, I just post VIs usually in lower version to get larger number of possible contributors 🙂

I will test your snippet tomorrow morning!

0 Kudos
Message 33 of 89
(2,035 Views)
Solution
Accepted by Blokk

What Nathan said is basically correct. However is your DLL a 64-bit DLL?

Because if not, you need to make the pointer in the struct a 32 bit integer. On the LabVIEW diagram a pointer sized integer is always 64 bit since that allows to store both values fully. And if you pass such a pointer directly and configure it to be a pointer sized integer, then LabVIEW will do the right thing depending on the bitness of the current platform. However since you pass in a pointer in a cluster no such automagic can happen and you have to adjust the structure accordingly (This was the conditional compile structure in my earlier VI).

Now this API function looks suspiciously problematic and the header file does not give enough information to make sure we can understand how this API is meant to be called. Therefore you have to start reading the manual and try to interpret the more or less detailed description. And there you find that it is equally insufficient.

 

So then the only thing that remains is to get some sample code and try to infer the operation from that. So looking on internet I found this and that makes things more clear.

 

Basically you have several error/problems in your VI:

 

- Depending on the bitness a different cluster needs to be used where the readout pointer is either a 32 bit or 64 bit integer. However in this specific case it should work out fine since the second parameter is a 64 bit integer anyhow and therefore will be aligned to an 8 byte boundary so that the dummy filler int32 would be occupied by the superfluous 32 bits from the 64 bit pointer integer. And since Windows runs on x86 CPUs and they always use LSB Endianess the actual 32 bit pointer will end up in the lower 32 bit of the 64 bit integer and that is how LabVIEW treats pointer sized integers too. But I prefer to make it explicit as this is only specifically true for this particular case since the readout_count value is a 64 bit integer.

 

- MoveBlock is a LabVIEW manager function and they are ALWAYS cdecl.

 

- It is also thread save and since the call may potentially take some substantial time depending on the frame size of an image, it is best to configure the CLN to run in any thread to avoid blocking the LabVIEW UI thread unneccessarily.

 

- You can not pass a LabVIEW array handle into the MoveBlock() call, that function expects the pointer to the array.

 

- You need to allocate that array to the needed size before calling the MoveBlock() function, otherwise there is no memory for the MoveBlock() function to copy the data into.

 

- The array pointer contains readout_count number of frames, each starting on a multiple of readout_stride bytes from the beginning. This readout_stride can explicitly be equal or bigger than the actual frame_size. frame_size is something like picture_height * row_size * bytes_per_pix, where row_size can be again equal or bigger than the actual picture_width. This is called row padding.

 

- The errors is a single unsigned 32 bit integer passed by reference. Its errors are encoded as bits in the integer. You can't easily create an enum that represents this in a meaningful manner.

 

PICAM Acquire.png

Rolf Kalbermatter
My Blog
Message 34 of 89
(2,028 Views)

Amazing!

Thank you very much Rolf! 🙂

Actually I saved the link of your above response, and put it into the BD of the "Acquire_CCD_data.vi", for future reference. If someone inherits this code, they will know who made the relevant part.

 

Regarding to your question, we develop on Windows x64, but using LV 2017 32bit.

Below just a snippet, to show some real CCD data spit out by your VI (single frame, single readout, 100X100 ROI) 🙂

Thanks again!

 

PICam.lvlib_new1.png

0 Kudos
Message 35 of 89
(2,010 Views)

I attach the recent version of the PICam library (back saved to LV2014), some future reader might find it useful. The lvlib includes two example VIs demonstrating some common usage of the functions.

I did not have time to fully test the implemented functions, but I properly acquire data from the PIXIS400B CCD in the expected format. Feel free to modify/enhance/fix the library!

 

Message 36 of 89
(1,999 Views)

Hi Blokk

 

First of all, thank you very much for providing your code. I have a pixie 256 and it seems your program mostly works with it. I'm using 64 bit libraries. But I have a problem with SetROI. It complains about the "param" bit of the Picam_SetParameterRoisValue() function not connected in "TARGET_BITNESS==64" diagram. What should this pin be wired to? It seems you weren't using the 64bit drivers.

 

Screenshot 2019-08-27 at 20.07.32.png

0 Kudos
Message 37 of 89
(1,737 Views)

That's trivial. Connect the same constant to it as in the 32 bit case.

 

But the code won't work like that since the roi element in the cluster needs to be an U64 integer for the 64-bit case!

Rolf Kalbermatter
My Blog
Message 38 of 89
(1,723 Views)

Many thanks Rolf! Just for future users here's the block diagram that works.

 

Untitled.png

0 Kudos
Message 39 of 89
(1,701 Views)

Hello, this is not an actual reply, but rather a small question. I got involved into programming a PIXIS camera using picam32.dll library in LabView.

You've written " "parameter" is an U32 with value of 67436581 (based on the header file)". Could you please clarify how you determined that number? I checked the header file picam.h and there is no such a number in an explicit form.

 

Thanks!

0 Kudos
Message 40 of 89
(1,633 Views)