From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

continuous simultaneous sampling

I am using NI DAQmx base on RedHat Linux 9.0.

I am acquiring 4 signals on a PCI6143 card.

Right now, I believe I am capturing the signals simultaneously, storing the results into a buffer, then chopping that buffer into 4 data structures (to separate each channel).

What I would like to do is to have this capuring go for a prolonged period of time, and then dump the results to 4 text files. I am not sure what the best approach for this would be. Obviously, I have a limit to the size of the buffer, so I cannot simply capture enough data to the buffer, then write it out.

It would be nice if there was some sort of double buffering approach, similar to graphics programming. I could capture to buffer 1, and when it is full, start capture to buffer 2, and while that is working, write buffer 1 to a file, then when buffer 2 is full, start capture to buffer 1 and write buffer 2 to the file, and so on.

Has anyone done anything like this? I am using the C libraries, so labview code wont help me.


Also, is this doing a simultaneous capture?

char chan[] = "Dev1/ai0:3";
float64 min = -5.0;
float64 max = 5.0;
float64 sampleRate = 250000.0;
#define bufferSize (uInt32)4000
#define samplesPerChannel (uInt32)1000
float64 data[bufferSize];
...
DAQmxErrChk (
DAQmxBaseCreateAIVoltageChan (
taskHandle,
chan,
"",
DAQmx_Val_Diff,
min,
max,
DAQmx_Val_Volts,
NULL)
);
DAQmxErrChk (
DAQmxBaseCfgSampClkTiming (
taskHandle,
source,
sampleRate,
DAQmx_Val_Rising,
DAQmx_Val_ContSamps,
samplesPerChannel)
);
DAQmxErrChk (
DAQmxBaseReadAnalogF64 (
taskHandle,
pointsToRead,
timeout,
DAQmx_Val_GroupByScanNumber,
data,
bufferSize,
&pointsRead,
NULL)
);
0 Kudos
Message 1 of 6
(2,991 Views)
Hello d0s4gw,

The NI-DAQmx Base driver automatically handles buffering data between the 6143 and the PC. I'm not sure if, under the hood, the driver is implementing a double buffer or a circular buffer but that shouldn't affect our application. You should be able to read from this buffer, immediately write the values to a file and then read from the buffer again in plenty of time. Are you running into performance issues that are preventing you from doing this? If you wanted to you could explicitly program your own 2 buffers within your development environment and choose when to write to each buffer, but I'm not entirely sure this will give you any performance benefits.

I hope this helps,
E.Lee
Eric
DE For Life!
0 Kudos
Message 2 of 6
(2,960 Views)
So you are saying that the following code should be a continuous scan (assuming the disc can keep up)?


for (i = 0; i < someNumber; i++)
{
DAQmxErrChk (
DAQmxBaseReadAnalogF64 (
taskHandle,
pointsToRead,
timeout,
DAQmx_Val_GroupByScanNumber,
data,
bufferSize,
&pointsRead,
NULL)
);

for (j = 0; j < sizeOfBuffer/4; j++)
{
fprintf(file0, "%f\n", data[j*4 + 0]);
fprintf(file1, "%f\n", data[j*4 + 1]);
fprintf(file2, "%f\n", data[j*4 + 2]);
fprintf(file3, "%f\n", data[j*4 + 3]);
}
}
0 Kudos
Message 3 of 6
(2,957 Views)
Hello d0s4gw,

The second snippet of code you posted is not really what makes the task acquire samples continuously. The function you call before it, DAQmxBaseCfgSampClkTiming, actually configures the taks to be continuous. If the disk can't keep up and you overwrite your samples in the buffer, the driver should throw you an error, so you should be confident that all your data is valid if you are not receiving an error.

Take care,
E.Lee
Eric
DE For Life!
0 Kudos
Message 4 of 6
(2,934 Views)
I'm not sure I entirely understand. Perhaps some pseudocode may be of assistance.

I currently am doing something like this, and it is giving me the impression that it is working.


DAQmxBaseCreateAIVoltageChan (...)
DAQmxBaseCfgSampClkTiming (...)
startTask()
while (cond)
{
DAQmxBaseReadAnalogF64 (&data, ...)
foreach point in data
{
output (point)
}
}
stopTask()


If this isn't correct (and you indicated it is not) could you show me some pseudo code that is the right way to do this?
0 Kudos
Message 5 of 6
(2,927 Views)
Hello d0s4gw,

Sorry for the confusion. I did not mean to say that your code is incorrect, but just that the part of the code that determines if it is a continuous task is DAQmxBaseCfgSampClkTiming, not DAQmxBaseReadAnalogF64. Your code looks fine!

Take care,
E.Lee
Eric
DE For Life!
0 Kudos
Message 6 of 6
(2,911 Views)