02-01-2010 05:44 AM
My Delphi program, which works fine under NI-DAQmx 8.9.0f4 on one set of hardware, is failing under 9.0.0f2 on what I have been assured is equivalent hardware. The error is "Some or all of the samples requested have not yet been acquired...". This happens even at slow digitization rates, and I am coming to suspect that the API has changed subtly in the transition from version 8 to 9. How likely is this? Now that I have access to the source code on the new hardware (NI PXI-1044 with embedded PXI-8110 computer) is there something I can do to check this?
Solved! Go to Solution.
02-01-2010 10:51 AM - edited 02-01-2010 10:51 AM
Hi francisb-
Which DAQ hardware are you using? Are you using an external signal for the sample clock or a start trigger? There was no intended API change that would suddenly introduce timeout errors into your operation, but more insight into your hardware and software setup would help us make suggestions on what might be going wrong.
02-08-2010 04:15 AM
02-10-2010 09:30 AM
Hi Francis-
I'm not familiar with ContinuousAI.c. Can you point me to that code?
In the meantime, let's talk about the DAQ parameters you're using in your code. How many channels on each device are you addressing? What sample rate are you using? And since you mention continuous AI, I assume you're looping on a DAQmxRead call to retrieve data. How many samples per loop are you attempting to read? What timeout are you specifying for DAQmxRead?
The error you're seeing is generically a timeout error. It could mean that you literally aren't waiting long enough for the requested samples to be acquired or that, for some reason, either your trigger or sample clock is not being recognized at the rate you expect it to. A quick glance at your code might help us make more recommendations.
02-10-2010 10:42 AM
Hi Tom,
The original C example file is:
National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Synchronization\Multi-Device\Continuous AI\ContinuousAI.c
Here is my own Delphi code which follows the same series of calls (edited to show just the relevant lines):
StopADCs; DisableFPUExceptions; for device := 1 to NumDevices do begin // NumDevices = 4 or 8 CheckError( DAQmxCreateTask( '', ADCTask[device]) ); // NCHANNELSPERBOARD = 65 (64 for camera plus 1 extra analog input) channels := DeviceName[device] + '/AI0:' + IntToStr(NCHANNELSPERBOARD-1); CheckError( DAQmxCreateAIVoltageChan( ADCTask[device], PChar(channels), nil, refmode, // DAQmx_Val_RSE or DAQmx_Val_NRSE vmin, vmax, DAQmx_Val_Volts, nil) ); CheckError( DAQmxCfgSampClkTiming( ADCTask[device], PChar(''), srate, // 100, 200, 500 or 1000 Hz DAQmx_Val_Rising, DAQmx_Val_ContSamps, Floor(srate)) ); end; // register master task callback CheckError( DAQmxRegisterEveryNSamplesEvent( ADCTask[1], DAQmx_Val_Acquired_Into_Buffer, NFRAMESPERCALLBACK, // 10 0, @EveryNCallback, nil) ); // synchronise board acquisition for device := 1 to NumDevices do begin CheckError( DAQmxSetRefClkSrc( ADCTask[device], PChar('PXI_Clk10') )); CheckError( DAQmxSetRefClkRate( ADCTask[device], 10000000.0 )); end; // 'committing' supposed to reduce delay between starting tasks for device := 1 to NumDevices do begin if CheckError( DAQmxTaskControl( ADCTask[device], DAQmx_Val_Task_Commit )) then begin EnableFPUExceptions; Exit; end; end; for device := 1 to NumDevices do begin if CheckError( DAQmxStartTask( ADCTask[device])) then Exit; ADCActive[device] := true; end; EnableFPUExceptions;
Then the callback routine is:
function EveryNCallback(thandle: LongInt; evType: LongInt; nSamples: LongWord; callbackData: Pointer): LongInt; cdecl; // camera 1 (4 boards x 64 channels) for device := 1 to 4 do begin rc := DAQmxReadBinaryI16( ADCTask[device], 10, 0, DAQmx_Val_GroupByScanNumber, @ADCBuffers[device, 1], 1000, nread, nil ); // <---- Error here at all sampling rates if rc <> 0 then begin DAQmxGetErrorString(rc, RunErrorDesc, LONGSTR-1); RunError := true; DAQmxStopTask(ADCTask[device]); end; NSampsRead := nread; end; // if no error... // Process data in ADCBuffers // Repeat above for camera 2 if attached (NumDevices=8)
Hope this provides all the info you need. I can post more code if necessary.
Francis
02-10-2010 10:49 AM
Hi Francis,
Does your program still call DAQmxCfgDigEdgeStartTrig() for all of the slave tasks? If you don't do that, the devices won't start acquiring data at the same time, and since you're passing 0 for the timeout parameter to DAQmxReadBinaryI16(), out-of-sync devices could definitely cause timeout errors.
Also, you must make sure to start the slave devices before the master device, so that they are already waiting for a trigger when the master device starts.
Brad
02-10-2010 01:22 PM
In addition to what Brad mentioned, consider increasing your sample interval. A sample interval of 10 (assuming the comment is accurate) is rather small for an acquisition rate of 1kHz. This would mean that you need to be calling DAQmxRead to read 10 samples 100 times each second (times four devices). I wouldn't be surprised if your system cannot keep up while the callbacks and the small read sizes (therefore, read overhead impact is maximized) are taxing your system.
You might try something like 1000 samples for the interval at 1 kHz.
02-14-2010 12:06 PM
Hi Tom,
That appears to have done the trick! I haven't soak-tested data acquisition yet, but it certainly runs for minutes without any errors.
Many thanks for your suggestion.
Francis
02-14-2010 12:14 PM