10-21-2009 03:06 PM
Hi,
I'm using a National Instruments cDAQ with a NI-9239 analog input module. What I want to do is whenever I call the ReadAnalog64 function to take 100 samples at 25kHz on two channels. I created a timer in my program that ever 100ms does this and updates the screen with the average of the 100 samples. However, I cannot seem to make it sample any faster than about ~150ms. Is there a way to do this that should be much faster?
Thanks,
Mark
10-23-2009 11:30 AM
Hi Mark,
How long does the acquisition and averaging take if you remove the timer? Have you already created the task before you begin the process of reading every 100ms or are you creating and closing the task every time you perform the read? Could you post either your code or a screenshot- it sounds like there probably just something that's not quite configured right that's slowing things down. Thanks!
10-23-2009 06:44 PM
If I put the read in an infinite loop it can read essentially as fast as it can sample (which is to be expected). However, that's not how I want to use it. I want to be able to go grab 100 samples whenever I want. Sometimes quickly in a row, and sometimes only once a second. I think the issue involves how I have to start and stop the task each time I want to take a sample. If I just start the task at the beginning of my program it complains that I didn't clear the buffer and the buffer overflows (unless I put it in an infinite loop and grab every sample). Here is an abreviated version of my code:
In MAX I have it setup for N samples - 100 samples - 50kHz on two Analog inputs.
//I removed the averaging and everything else just to see how fast it can do this
float analogin[200] = 0;
main()
{
nStatus = DAQmxLoadTask("AnalogVoltageIn", &ainHandle);
RunUserInterface ();
}
//I set the timer to 100ms
int CVICALLBACK Update (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
nStatus = DAQmxStartTask (ainHandle); //Commenting this out doesn't change the speed
nStatus = DAQmxReadAnalogF64 (ainHandle, DAQmx_Val_Auto, 1, DAQmx_Val_GroupByChannel, analogin,
AI_SIZE * 2, &sampread, 0);
nStatus = DAQmxStopTask (ainHandle); //Commenting this out doesn't change the speed
}
On the front GUI I display the timer's eventData2 which is the time since the last time it called to see how fast I can read data (that code is ommited)
Is there a better way that I can be doing this?
10-28-2009 11:26 AM
You need to get the task setup to use a circular buffer of 100 elements and read those whenever you specify to. The steps I used to set this up were:
1. Create task
2. Set timing to use sample clock with rate at 25k, sampling mode set to continuous samples, and number of samples per channel set to 100
3. Set DAQmx Read property OverWrite to "Overwrite Unread Samples"
4. Set DAQmx Read property RelativeTo to "Most Recent Sample"
5. Set DAQmx Buffer property Input.BufSize to 100
6. Start task
7. Read 1 channel N samples with Number of Samples to Read set to 100
8. Clear task
The functions to set the properties in C are:
DAQmxSetReadOverWrite(aiHandle, DAQmx_Val_OverwriteUnreadSamps)
DAQmxSetReadRelativeTo(aiHandle, DAQmx_ValMostRecentSamp
DAQmxSetBufInputBufSize(aiHandle, 100)
Let us know if this doesn't solve the issue.
10-28-2009 12:22 PM
Thank you for your response. The functions you gave me in C don't appear to be in the LabWindows/CVI IDE. Instead I used what appears to be their equivalents:
nStatus = DAQmxSetReadAttribute (ainHandle, DAQmx_Read_OverWrite, DAQmx_Val_OverwriteUnreadSamps);
nStatus = DAQmxSetReadAttribute (ainHandle, DAQmx_Read_RelativeTo, DAQmx_Val_FirstSample);
nStatus = DAQmxSetBufferAttribute (ainHandle, DAQmx_Buf_Input_BufSize, 100);
I updated my code as follows, but I am still getting a 'tried to read a sample that is no longer there message'. Your method is exactly the sort of thing that I want to do where I just read the latest sample as the system samples away at 25kHz so I still must be doing something wrong.
In MAX I have it setup for continuous - 100 samples - 25kHz on two Analog inputs.
//I removed the averaging and everything else just to see how fast it can do this
float analogin[200] = 0;
main()
{
nStatus = DAQmxLoadTask("AnalogVoltageIn", &ainHandle);
nStatus = DAQmxSetReadAttribute (ainHandle, DAQmx_Read_OverWrite, DAQmx_Val_OverwriteUnreadSamps);nStatus = DAQmxSetReadAttribute (ainHandle, DAQmx_Read_RelativeTo, DAQmx_Val_FirstSample);
nStatus = DAQmxSetBufferAttribute (ainHandle, DAQmx_Buf_Input_BufSize, 100);
nStatus = DAQmxStartTask(ainHandle);
RunUserInterface ();
}
//I set the timer to 100ms
int CVICALLBACK Update (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
nStatus = DAQmxReadAnalogF64 (ainHandle, DAQmx_Val_Auto, 1, DAQmx_Val_GroupByChannel, analogin,
AI_SIZE * 2, &sampread, 0);
}
10-28-2009 04:13 PM
10-28-2009 07:05 PM
I changed it to most recent sample and I'm still having the same problem. What am I missing?
10-29-2009 02:26 PM