07-04-2011 04:17 AM
Hello Again,
I tried everything so far and found out that the error 1097 is being thrown by the MoveBlock function (which is also called through a Library Function Node).
Just to review my configurations:
The prototype of the function located in the header file is LIBOPTO int OptoPCI_DAQ_HalfReady ( WORD id, BOOL *HalfReady );
That when converted to Labview (provided the .dll and .h files) results in int32_t OptoPCI_DAQ_HalfReady(uint16_t id, int32_t *HalfReady);
The calling convention is set as "C" (I changed to "stdcall", but got no positive results) and the parameters are defined as follow:
Is there any way to get the Boolean value directly from the OptoPCI_DAQ_HalfReady Function? If not, what is wrong with the MoveBlock Function?
Thanks again in advance
07-04-2011 04:33 AM
As far as I understood the HalfReady parameter will hold the boolean value. So you can just check if HalfReady is not 0 (assuming the return value is 1 (or -1) for true, 0 for false).
I'm a bit surprised though that LV uses a I32 for a boolean. I thought booleans are stored as U8.
Anyway, do you get a value back on the HalfReady parameter? What is the return value of the dll?
07-04-2011 04:47 AM
Well, I do get a value from the HalfReady parameter, but not sure if it makes sense. Provided that I must link an I32 to it as an input, the function just copies the value of this I32 to the output.
For an example, if I wire a constante I32 of value equals to 3, the output will be also 3.
If your question was related to the return value of the whole function, then I guess I will not be able to answer what the return value means, because I don't have the source code, only the prototypes and the .dll, therefore I am not aware how the function was coded. Anyway, I'm receiving from it the value 27, much different from the -1 common in error returns.
07-04-2011 09:11 AM - edited 07-04-2011 09:11 AM
It seems your pointer is not modified.
Are you sure the ID you wire to the U16 input is correct? Are you using another dll call to get the ID?
I don't know what is common for errors, but I have seen dll's that return 0 for success and any other return value is an error code.
Did you try changing the I32 to U8? I don't expect this to solve the problem, though.
07-04-2011 01:08 PM
LabVIEW does store booleans as U8. However, the DLL may use any representation it wants for a BOOL; if it follows Windows, conventions, that's a I32 (a standard integer), which is why the DLL import function configured it that way. See the "Call DLL" example provided with LabVIEW. Note that BOOL is I32, but BOOLEAN is U8.
How do you know that your DLL call is not working as desired? Do you know what value you expect to get back? Do you have any documentation for this function?
As I wrote before, you do not want MoveBlock. LabVIEW will handle the pointer referencing/dereferencing for you. You provide an input value, LabVIEW passes its address to the function call, and then when the function call returns, LabVIEW gets the data at that address and puts it on the wire. At no time do you ever have access to the actual address, so there is no way you could use MoveBlock. If you desperately did need to use MoveBlock (again, not necessary here) you would first need to allocate a pointer.
07-05-2011 04:32 AM
Well, I just found out that I overlooked some pretty obvious mistakes regarding hardware and right now I am not getting any error. But I am still not getting what I wanted from this functions.
The HalfReady should acquire the values from a sensor and when the reading buffer got full, the function should signal it by changing the value of the boolean variable to TRUE. However I've let the function running for a whole minute and nothing happened, given that the measuring time is just a fraction of second.
Therefore I am trying to rule Labview out as why am I not getting the proper value. But if you say that Labview will be able to managed this boolean pointer without sweating, I'll have to check with the sensor manufacturer.
Thank you guys and if I get anything new, I'll come here and share with you.
07-06-2011 05:15 AM
Well, just like nathand said, Labview handled the Boolean pointer just fine, but I encountered a more complicated (I think) problem now.
After the Boolean indicates true, the next step is to get the data read from the sensor buffer, where the information is stored, and transfer it to that PC, therefore, the last step. The buffer has the length of k*1024 (k >= 2 and dependent on the previous configurations) measurements.
To fetch this results, one should use the following function
LIBOPTO int OptoPCI_DAQ_Transfer ( WORD id, WORD *mprVal, double *mprValChan0, double *mprValChan1, double *mprValChan2, double *mprValChan3 );
And, as you can see, it receives a lot of pointers. But given that I am only using one channel, the pointers "mprValChan1-3" should be passed as NULL. That is the first question, is it possible to pass a null pointer in LabView?
The second question regards how to get the values from the pointers mprVal and mprValChan1. They are supposed to have a definite size, determined by k*1024, and according to the examples (in c++) giving by the manufacturer, I should scan every position of the mprValChan0(channel 1 results), such as:
for (int i=0 ; i< k*1024 ; i++)
{
tmp [i] = mprValChan1[i]);
}
But Labview used a U16 pointer to value (to mprVal) and 8-byte pointer to value (to mprValChan0), so I can not define the size these variables and neither scan through every position. Anyway I imagined that Labview would handle the dynamic allocation. But when I try to run the program, Labview crashes.
I imagined that might be a problem with the size of variable and tried to change the U16 variable to an array (configured it as Array Data Pointer) and defined the correct size and made that with the double as well, with the difference that I have initialized this array with dimension zero (closest to NULL, I thought), however then I get an error indicating malfunction of the procedure.
Any ideas on how to solve this?
07-06-2011 05:47 AM - edited 07-06-2011 05:50 AM
I'm not sure I understand correctly. Does the DLL only return one value at a time? Then you can just wire a pointer to a DBL constant to the input. If the dll returns an array you'll have to pass a pointer to an array to the DLL, but the array must already be allocated. To do so, create an array of correct size (can be initialized with 0's) and wire this to the dll input.
About the NULL pointers I'm not sure, if the DLL does not write to these locations you could just pass a pointer to an empty array or probably leave it unwired.
07-06-2011 07:05 AM
The dll function returns the pointer to a memory space, and each space contains one measurement, but, because of this, I can only read the first value, in the better case scenario
I tried to pass a pointer to an array - already initialized, with the correct size - but that failed for reasons that I am not aware of. Any ideas why is not working?
07-06-2011 07:51 AM
If the dll returns a pointer this is more difficult. I don't have experience with this, but in this case you might need MoveBlock or write a wrapper dll that gets the data and returns it as an array.