Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

What are valid combinations of sampling rate and number of samples using a NI PCIe 6363 Device via the DAQmx API

Summary:

We have a system controlling a NI-PCIe 6363 Device via the NI-DAQmx library (see NIDAQmx.h, nidaqmx.lib).  I have successfully programmed the device for digital and analog I/O.  At this time, we have a single analog input that we are trying to control with a variety of combined (sampling rate and number of samples).

 

Question:

What are the valid combinations of {sampling rate, number of samples} given the following Setup?

 

Setup:

Here is the abstract C++ code configuration:

 

// internal clock is 10 MHz

int32 read = 0;

float64 dSamplingConvRate = 2000000.0;   // 2M Hz

 

// set of parameters that does work
float64 SamplingRate = 200000.0; // 200K Hz
uInt32 nSamples = 100000;        // 100K 

 

DAQmxCfgSampClkTiming(m_TaskHandle,
NULL, 
SamplingRate,
DAQmx_Val_Rising, 
sDAQmx_Val_ContSamps,
nSamples);

DAQmxSetAIConvRate(m_TaskHandle, dSamplingConvRate);
DAQmxSetSampTimingType(m_TaskHandle, DAQmx_Val_SampClk);
DAQmxSetStartTrigType(m_TaskHandle, DAQmx_Val_DigEdge);
DAQmxSetDigEdgeStartTrigSrc(m_TaskHandle, "/Dev1/PFI10");
DAQmxSetDigEdgeStartTrigEdge(m_TaskHandle, DAQmx_Val_Rising); 
DAQmxSetStartTrigDelay(m_TaskHandle, 0.0);
DAQmxSetStartTrigDelayUnits(m_TaskHandle, DAQmx_Val_Seconds);

 

next, we setup a callback:

DAQmxRegisterEveryNSamplesEvent(m_TaskHandle, DAQmx_Val_Acquired_Into_Buffer, 1, 0, EveryNCallback, this);

 

inside the callback, our code reads the data:

DAQmxReadAnalogF64(m_TaskHandle, 
nSamples, 
10.0, 
dataLayout, 
pBuffer, 
nSamples, 
&read, 
NULL);

 

Discussion:

This setup uses a waveform on "/Dev1/PFI10" where a square wave cycles every second.   In this design, the leading edge of the assigned trigger pulse kicks-off the data collection (via DAQmxSetDigEdgeStartTrigSrc).   The above abstract code snippet (key parameters are shown to illustrate the setup) works well.  The system runs continuously until we stop data collection using API calls to stop the DAQ under our software control.  This pattern configured the API to internally transfer the data into our client buffer using the DAQmx thread (the eventOptions flag was set to 0, so the callback function is called in a DAQmx thread) as opposed to the alternative method of using a separate thread via DAQmx_Val_SynchronousEventCallbacks.   Once we've read the data using DAQmxReadAnalogF64, we return, everything works fine.  This setup is stable and runs without error continuously for many days.   The goal is to change the readout frequency by changing the number of samples read at a constant ADC rate.  The internal clock is 10MHz.

 

Question:

What are the valid combinations of {sampling rate, number of samples} given this setup?


For example, trying the following setup does not work, the registered callback is never called.

 

float64 SamplingRate = 180000.0; // 180K Hz
uInt32 nSamples = 60000;         // 60K 

 

But, the following setup combinations do work.

 

float64 SamplingRate = 200000.0; // 200K Hz
uInt32 nSamples = 200000;        // 200K 

 

float64 SamplingRate = 200000

uInt32 nSamples = 100000

 

float64 SamplingRate = 150000

uInt32 nSamples = 50000

 

float64 SamplingRate = 200000

uInt32 nSamples = 50000

 

float64 SamplingRate = 125000

uInt32 nSamples = 25000

0 Kudos
Message 1 of 5
(4,930 Views)

Hello big.tuna,

 

I am pretty sure that you are familiared with this concepts, but I will include them in my post in case you are missing something. 

 

DAQmx Timing and Sample Rates

Understanding and Avoiding NI-DAQmx Overwrite and Overflow Errors

 

With the function: 

 

DAQmxSetSampTimingType(m_TaskHandle, DAQmx_Val_SampClk);

 

You will be setting the speed on how the signal is digitized. And specifying the samples to read you will indicate how much samples you want to take out of RAM buffer. Let's set up an example using the same numbers that you indicated on the post: 

 

float64 SamplingRate = 180000.0; // 180K Hz
uInt32 nSamples = 60000;         // 60K 

 

This means that the hardware will be acquiring 180 000 samples per second and you will extract 60 000 samples each time you called the DAQmxReadAnalogF64 function

 

DAQmxReadAnalogF64 - Help Document

 

So, if you call the function only call the function one time per second you will be extracting 60 000 samples of the buffer and leaving 120 000 there. The next iteration you will process another 60 000 samples, but another 120 000 will be accumulated. Now lets imagine that you try to call the DAQmx Read function every 0.25 seconds requesting 50000 samples to read. 

 

The first three read operations will perform without issues, however the fourth one will have to wait some time until the rest 20 000 samples are acquired. The combination of Sample Rate and Samples to Read is key to prevent an overwrite error.

 

Using the DAQmxRegisterEveryNSamplesEvent should prevent an overwrite error because it would allow to create an event each time you reach the number of samples you desire as the help document indicates: 

 

DAQmxRegisterEveryNSamplesEvent - Help Document

 

Questions:

1- Using the other combinations have you been able to confirm if callback is being done as soon as the number of requested samples is specified? 

2- For what I understood the callback function is then calling the read function. Are you extracting the same number samples that you are specifying for generating the event?

3- Is the signal for your analog input changing over the time? Why do you need to use those particular Sample Rate/Number of Samples?

4- Are you monitoring that the right amount of samples are being extracted from the buffer? Based on the following help document: 

 

NI PCIe-6363 Supported Properties

 

You can use the function named: DAQmxGetReadAvailSampPerChan 

 

If your code is being executed correctly this number should not increase with the time. 

 

Comments:

 

I have to be honest by telling that I am not sure why your callback event is not being registered. I have access to a PCIe-6363 and I can run test if it is necessary. I hope this information helps you out to track the performance of your application. 

 

Answer: 

 

What are the valid combinations of {sampling rate, number of samples} given this setup? 

 

I believe that what I explained on the top should answer this question. However, I am not sure how to answer this other one: 

 

What is a valid combination of sampling rate and number of samples for the DAQmxRegisterEveryNSamplesEvent to work? 

 

I will investigate some about this issue. 

 

Regards,

 

Randy @Rscd27@
0 Kudos
Message 2 of 5
(4,826 Views)

Thank you for the detailed reply, I need to clarify something based on your discussion (I have also answered the questions you added):

 

As you stated:

"So, if you call the function only call the function one time per second you will be extracting 60 000 samples of the buffer and leaving 120 000 there. The next iteration you will process another 60 000 samples, but another 120 000 will be accumulated. Now lets imagine that you try to call the DAQmx Read function every 0.25 seconds requesting 50000 samples to read."

 

It is important to note that we have registered the callback mechanism based on the number of samples to read, this is independent of the A/D sampling rate.   Such that, when we register for 60K values at ADC=180K, we should get a callback every 1/3 second.   As the original post gave examples of working callbacks every 1/2, 1/3, 1/4 and 1/5 second by way of the combinations used.   The issue is not configuring for 3 callbacks per second, but the systematic failure with some combinations.  n other words, the combinations that work always work, the ones that do not always fail.

 

As a reminder, let's recall the patterns that work:

 

float64 SamplingRate = 200000.0; // 200K Hz    // <------------- 1 callback per second
uInt32 nSamples = 200000;        // 200K 

 

float64 SamplingRate = 200000                  // <------------- 2 callbacks per second

uInt32 nSamples = 100000

 

float64 SamplingRate = 150000                 // <-------------- 3 callbacks per second

uInt32 nSamples = 50000

 

float64 SamplingRate = 200000                 // <-------------- 4 callbacks per second

uInt32 nSamples = 50000

 

float64 SamplingRate = 125000                  // <-------------- 5 callbacks per second  

uInt32 nSamples = 25000

 

 

Now, the following pattern DOES NOT work:

 

float64 SamplingRate = 180000.0; // 180K Hz                 // <--------------- should get 3 callbacks per second
uInt32 nSamples = 60000;         // 60K 

 

If you compare the failing pattern with 3 callbacks per second to the successful pattern with 3 callbacks per second, there may be some clues.   

 

Thank you again for the attention to this

 

Questions:

1- Using the other combinations have you been able to confirm if callback is being done as soon as the number of requested samples is specified? 

when callbacks work, they always return the expected number of samples read (this is filled-in by the DAQmx API, we pass the address of an int32)

 

2- For what I understood the callback function is then calling the read function. Are you extracting the same number samples that you are specifying for generating the event?

yes, every callback that we receive return the expected number of samples.

 

3- Is the signal for your analog input changing over the time? Why do you need to use those particular Sample Rate/Number of Samples?

yes, the application is a scientific analysis system, we need hi-speed, real-time data acquisition, this is a basic requirement of the system, it is vitally important to get this to work.

 

4- Are you monitoring that the right amount of samples are being extracted from the buffer? Based on the following help document: 

yes,  I have verified with careful analysis that when we get the data it is correct. 

 

I am curious if there was something obvious I can try or is there a known limitation?

0 Kudos
Message 3 of 5
(4,819 Views)

Hello big.tuna,

 

I was out for some time and I was unable to reply earlier. I will like o know if you are still facing this issue. 

 

Regards,

Randy @Rscd27@
0 Kudos
Message 4 of 5
(4,706 Views)

Thank you, this issue is now resolved, I posted the tested code in a new forum link titled:

 

"Generic sample C++ code for Flexible Configuration for generic combinations of the ADC Rate and Sampling rate using a NI PCIe 6363 Device via the DAQmx API"

 

The key was adding a call to DAQmxSetBufInputBufSize()

 

The above link has full C++ code that may be used in a console to demonstrate (otherwise problematic) general combinations of ADC and samples, I tested this with ADC/sample (ratio) 1 through to 500, this equates to a callback Hz (effective application data collection rate) = ADC/sample, or 1 per second up to 500 application readings per second.

Previously some combinations did not work, the underlying reason was that the API was internally guessing at a buffer needed to accommodate the parameters, but sometimes was too small.   In the C++ code sample, I passed in a large buffer to DAQmxSetBufInputBufSize(), which addresses the issue.   No optimization was done, this code was shared to show how to get the system to work for every configuration.

 

0 Kudos
Message 5 of 5
(4,702 Views)