08-04-2010 03:43 PM
Hi,
I am using a USB DAQPad-6015 to acquire data from 8 analog channels and using an external clock (200Hz). I am also retrieving data from a library function node call which schedules a callback function to run at approximately 1000Hz. The function prototype accepts a pointer to an array, and the array contents are updated each time the callback function is run. Thus in labview I initialize an array and pass this as a parameter and am able to retrieve the data.
Using an event structure I am sampling the data from the library function node every time the DAQ takes a sample (so at 200Hz). I expect to see no repeated values from the dll data, but this isn't the case.
I am not sure why this happens. I thought possibly acquiring data from the analog channels takes priority over the scheduled callback function -- thus it might not be running at 1000Hz as I expect -- but I'm wondering if there could be any other explanation.
Any help would be much appreciated.
I've attached a simplified version of the VI and the output data.
08-04-2010 04:14 PM
Your callback function will not be updating the array at all -> LabVIEW is a by-value/dataflow language so your DLL call will simply get a copy of the data at that exact point in time and once the wire moves on, the call back pointer is meaningless (from a LabVIEW persepective).
I dont know of any way to get LabVIEW to work with C callbacks - do you have the source of the C Dll / can you modify it to allow the data to be polled by LabVIEW? If not you will probably need a wrapper DLL.
08-04-2010 05:00 PM
But the data in the array is updated after the library function is first called. I think somehow LabVIEW is accessing this from a memory address. The attached excel file shows the results from the data, and the value is updated every couple of samples. I'm just confused why it isn't updated every sample.
I do have the source for the C dll though. I'll see if I can modifty it as you suggested.
The actual callback function is the following:
extern "C" __declspec(dllexport) HDCallbackCode HDCALLBACK updateDeviceCallback(void *pUserData)
{
hdBeginFrame(hdGetCurrentDevice());
/* Get the current location of the device (HD_GET_CURRENT_POSITION)
We declare a vector of three doubles since hdGetDoublev returns
the information in a vector of size 3. */
hdGetDoublev(HD_CURRENT_POSITION, gServoDeviceData.m_devicePosition);
hdGetDoublev(HD_CURRENT_JOINT_ANGLES, gServoDeviceData.m_deviceAngles);
DevDataArray[0] = gServoDeviceData.m_devicePosition[0];
DevDataArray[1] = gServoDeviceData.m_devicePosition[1];
DevDataArray[2] = gServoDeviceData.m_devicePosition[2];
DevDataArray[3] = gServoDeviceData.m_deviceAngles[0];
DevDataArray[4] = gServoDeviceData.m_deviceAngles[1];
DevDataArray[5] = gServoDeviceData.m_deviceAngles[2];
memcpy(pUserData, &DevDataArray, 6*sizeof(HDdouble));
hdEndFrame(hdGetCurrentDevice());
return HD_CALLBACK_CONTINUE;
}
Thanks for your reply!
08-05-2010 09:44 AM
I tried writing an additional function in the dll that can be called to poll the data, and it is able to get correct data most of the time, but sometimes has some large 'spikes' in the data -- this is even at low frequencies like 10 Hz -- not much better my previous approach. At 100Hz I still see repeated values for several samples.. I guess this means the callback function isn't truly running at 1000Hz as it should be.
08-05-2010 04:08 PM
It may be unreasonable to expect code to run at 1 kHz. A 1 ms loop rate is pretty quick. Have you tested the C code separately to see if it can run at that rate?
08-05-2010 05:18 PM
Hi Tanya, thanks for your reply.
I have tested the C code separately and it is able to run at 1kHz. The issue arises as soon as I introduce analog data acquisition.
08-06-2010 10:30 AM
If your dll is thread safe, try setting your 'Call Library Function Node' to 'Run in any thread'. Currently your dlls are set to 'Run in UI thread'. This could improve the execution speed.