10-07-2011 01:38 AM
Hi, I am programing in C++ to control the DAQ card and I am using USB-6251 Mass Terminal and DAQmx 9.3.5. Below is my code
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",SampleRate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,BuffSize)); DAQmxErrChk (DAQmxCreateTask("",&taskHandle)); DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle,chan,"",DAQmx_Val_Cfg_Default,min,max,DAQmx_Val_Volts,NULL));
then in a loop, I try to check the available sample number as
DAQmxErrChk(DAQmxGetReadAvailSampPerChan(taskHandle,read));
The number of samples per channal is set to be 100,000 and when I trace how many samples are available, I got the following result:
available AI number is 5461 available AI number is 10098 available AI number is 15088 available AI number is 20102 available AI number is 25115 available AI number is 30105 available AI number is 35119 available AI number is 40109 available AI number is 45123 available AI number is 50110 available AI number is 55100 available AI number is 60114 available AI number is 65104 available AI number is 70093 available AI number is 75107 available AI number is 80097 available AI number is 85111 available AI number is 90100 available AI number is 95114 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0
every time the last valid value varies, but it never hit 100,000. Then I modifed my code to include DAQmxSetReadRelativeTo as following to avoid the possible overwritten error.
DAQmxErrChk (DAQmxCreateTask("",&taskHandle)); DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle,chan,"",DAQmx_Val_Cfg_Default,min,max,DAQmx_Val_Volts,NULL)); DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",SampleRate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,BuffSize)); DAQmxErrChk (DAQmxSetReadRelativeTo(taskHandle,DAQmx_Val_MostRecentSamp));
and this time, the available data number returned becomes always zero!
available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0 available AI number is 0
So would anyone please tell me why this could happen? Am I doing this the correct way?
10-11-2011 03:05 AM
Would anyone please help me with it?
10-11-2011 09:07 AM
Without seeing the rest of your code, I can only guess what your problem may be. Since you are doing a continuous acquisition, setting 'samples per channel' should effectively set the buffer size to 100,000. Looking at your traces, it appears that you approach this number. If you don't actually read data from the buffer, I would expect that once the buffer fills up, you'll overflow your device's onboard FIFO. This would cause an error and likely cause your task to be done. At this point querying the number of available samples per channel may return zero. Are you seeing errors? If you call DAQmxIsTaskDone, what is the result?
Can explain what you need to accomplish with this code? Generally you would want to set the buffer size to be bigger than the number of samples you wish to acquire. If you would like to read 100,000 samples I would generally set the buffer size to be 3 to 4 times that size. Additionally, I typically would not call DAQmxGetReadAvailSampPerChan. If you call DAQmxRead with the number of samples you want to read, it wait for those samples to be available and then read them for you. The advantage to this approach is that DAQmx can read data out of the buffer in smaller increments within the same read call. The call will not return until it has read all requested samples, but it 'free up' samples that it has already read from the buffer. This can help to prevent the over written error.
So, my first suggestion would be to see if you can eliminate the call to DAQmxGetReadAvailSampPerChan and let DAQmxRead handle this for you. If you do need to use this, then I'd suggest that you increase the buffer size or break your read into multiple smaller increments. Please let me know if you have questions.
Hope that helps,
Dan
10-11-2011 08:32 PM
Actually I did use
DAQmxErrChk(DAQmxSetBufInputBufSize(task,sizeperchan));
to set the buffer to be 3 times bigger than the actually data per channel, and the problem remains.
I have tested if using DAQmxIsTaskDone, but after some pre-set time period (10 sencods), the task still not finished. No error is reported.
What I am trying to do is to continuously sample data, display, and do some calculations. The reason I don't want to use DAQmxRead directly is that the task is performed in a thread and I don't want DAQmxRead to block the thread. however, the strange thing was that when I tested it, the DAQmxRead did work correctly to read all sampled data. Now the issue is to find out why DAQmxRead worked while DAQmxIsTaskDone and DAQmxGetReadAvailSampPerChan didn't, even though the buffer size is set to be big enough. Any ideas?
10-12-2011 11:38 AM
Since you've configured your task as continuous, I would not expect the task to be done unless an error occurs. I suggested using DAQmxIsTaskDone because it may return errors where DAQmxGetReadAvailSampPerChan may not.
When you configure a larger buffer, what happens when you query DAQmxGetReadAvailSampPerChan? Are you still seeing the behavior originally described? Did you call DAQmxSetBufInputBufSize after you configured timing?
I would call things in the following order:
DAQmxCreateTask
DAQmxCreateAIVoltageChan
DAQmxCfgSampClkTiming
DAQmxSetBufInputBufSize
DAQmxStart
DAQmxGetReadAvailSampPerChan
DAQmxIsTaskDone
Dan
10-12-2011 08:02 PM - edited 10-12-2011 08:02 PM
I called the functions just the same order as yours. As you mentioned, since the task is continous sampling, the DAQmxIsTaskDone should always return FALSE, isn't it? After I configure large buffer, the DAQmxGetReadAvailSampPerChan return value depends on whether I set DAQmxSetReadRelativeTo or not as I pointed out in the first post. As DAQmxGetReadAvailSampPerChan always returns incorrect result, is there any other way that I can know the number of samples are ready?
10-13-2011 10:03 AM
For a continuous acquisition, DAQmxIsTaskDone should return FALSE, unless an error (such as a FIFO overflow) occurs. If such an error were to occur, DAQmxIsTaskDone should return TRUE as well as the error which was the reason for doneness. The reason I suggusted you use it is because I don't believe that DAQmxGetReadAvailSampPerChan will return such an error.
If you set DAQmxSetReadRelativeTo, and use DAQmx_Val_MostRecentSample I am not suprised that DAQmxGetReadAvailSampPerChan would return zero. Essentially you are telling DAQmx that you want to start reading the newest sample. As such, there is no newer data to read. Generally if you set DAQmxSetReadRelativeTo with the value DAQmx_Val_MostRecentSample, you would specify a negative offset with DAQmxSetReadOffset (value would be the negative of the number of samples you wished to read). This is useful to applications which wish only to read the newest data, and which don't expect to read all of the data produced by the device.
As I understand what you are trying to accomplish, I would not call DAQmxSetReadRelativeTo (this will default to DAQmx_Val_CurrReadPos). I would use a buffer at least 3x the the size of your read. When configured like this, what behavior do you see?
Dan
10-13-2011 08:33 PM
Hi, Dan, thanks for the info. The reason I set DAQmxSetReadRelativeTo is to avoid error 200279. I have added the DAQmxSetReadOffset and set a negative offset value of the sample per channel, but an error occurs as listed below when I called DAQmxGetReadAvailSampPerChan.
Invalid combination of position and offset. The position and offset specified a sample prior to the first sample acquired (sample 0).
Make sure any negative read offset specified will select a valid sample when combined with the read position.Property: DAQmx_Read_RelativeToCorresponding Value: DAQmx_Val_MostRecentSampProperty: DAQmx_Read_OffsetCorresponding Value: -500000
Task Name: _unnamedTask<7>
Status Code: -200277
It happens only when the first batch of data is not ready, and if I use break point to wait for a while, all the following check works fine. So any suggestion to solve this error?
10-18-2011 03:29 PM
David,
Sorry for the delay in response. The -200277 error you receive on your first read attempt seems reasonable, since you are essentially requesting data from before the start of the acquisition. In this case the simple solution would be to throw the error away and re-try.
If you are using DAQmxSetReadRelativeTo (mostRecentSample) and setting a negative offset, then I did want to make sure you understood that DAQmx makes no guarantee that you'll read every sample produced by the device, or that you won't read the same sample more than once. If this is OK for your application, then I would suggest that you throw away the -200277 error. If that's not desired, then perhaps there are other mechanisms by through which you can accomplish what you need (for instance DAQmx does support event call backs based on data transfer - see DAQmxRegisterEveryNSamplesEvent).
Hope that helps,
Dan