Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading Analog Inputs with a software timer on a cDAQ

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

0 Kudos
Message 1 of 8
(4,510 Views)

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!

0 Kudos
Message 2 of 8
(4,483 Views)

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?

0 Kudos
Message 3 of 8
(4,470 Views)

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.

Alex Person
NI-RIO Product Support Engineer
National Instruments
0 Kudos
Message 4 of 8
(4,438 Views)

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);

 

}

0 Kudos
Message 5 of 8
(4,432 Views)
Sorry, I was using the DAQmx C Reference but it sounds like you got the functions worked out.  Change the second read attribute to read relative to the most recent sample instead of the first sample.  I think that should do the trick.
Alex Person
NI-RIO Product Support Engineer
National Instruments
0 Kudos
Message 6 of 8
(4,418 Views)

I changed it to most recent sample and I'm still having the same problem. What am I  missing?

0 Kudos
Message 7 of 8
(4,411 Views)
Sorry, I missed one other thing.  In your read function, you need to change the numSampsPerChan parameter from DAQmx_Val_Auto to 100.  This will cause it to wait until it has 100 new values available and read the entire buffer.
Alex Person
NI-RIO Product Support Engineer
National Instruments
0 Kudos
Message 8 of 8
(4,389 Views)