Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

high speed acquisition in c++

Hello, I have developed a code in C++ to acquire data on an NI USB 6212 card, in my application I have to acquire 4 parameters at 100kHz for 1 hour maximum;

on lab view there are solutions for high speed acquisition,Is there a possibility to do the same thing in C++?

I do a dynamic allocation on an array data ( DAQmxReadAnalogF64(taskHandle, numSamplesToRead, acquisitionTime * 6, DAQmx_Val_GroupByChannel, data, numSamplesToRead * 4, &numSamplesRead, NULL);)

so when I enter the frequency and the acquisition duration that I want I get an error that I cannot make this allocation.

Do you have any solutions to offer me?
thanks in advance.

Message 1 of 7
(141 Views)

Yes, in C++ you can achieve high-speed data acquisition using NI-DAQmx libraries similar to LabVIEW. To avoid allocation issues, ensure the buffer size is large enough for the data you're acquiring. You can calculate the required buffer size based on the acquisition frequency and duration, then allocate memory accordingly to prevent errors.

0 Kudos
Message 2 of 7
(123 Views)

HI,

 

I made a dynamic allocation for the size of the table , and I used DAQmxConfigureLogging to save directly to tdms files

when I enter the frequency at 100kHz and 60 min the allocation fails.

code:

int32 numSamplesToRead = samplingRate * acquisitionTime;
float64* data = new(std::nothrow) float64[numSamplesToRead * 4];
if (data == nullptr) {
std::cerr << "error" << std::endl;
return -1;
}

 

0 Kudos
Message 3 of 7
(114 Views)

Of course it must fail!

100KHz, 4 channels, 1 hour results in:

 

100000 * 4 * 3600 * 8 bytes = 11.52 GB of buffer allocation! Good luck with that!

 

You do not allocate the whole buffer for long during acquisition in one chunk. Instead you read repeatedly data from the DAQ task in a smaller buffer and then process it, like analysis, visualization and/or logging. That's what your LabVIEW examples did too. But in LabVIEW it's simply a bit more convenient and the memory management happens more seamless. In C(++) you have more power to do things, including bad things!

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 7
(78 Views)

Hello, thank you for your feedback;

I coded a while loop when I stop after 60 min, but I'm not sure if I'm losing data?

 

while (true) {

int32 numSamplesRead = 0; // Nombre réel d'échantillons lus
auto startTime = std::chrono::steady_clock::now();
error = DAQmxReadAnalogF64(taskHandle, numSamplesToRead, 5000.0, DAQmx_Val_GroupByScanNumber, data, numSamplesToRead, &numSamplesRead, NULL);
auto currentTime = std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::minutes>(currentTime - startTime).count();


if (elapsedTime >= 60) {
break;
}
}

 

Amel

0 Kudos
Message 5 of 7
(68 Views)

So do you only have one channel suddenly? Otherwise the parameters to DAQmxReadAnalogF64() are not really correct. The 2nd parameter is how many samples to read per channel, the 6th parameter is however how large your data array is. That should be numSamplesToRead * numChannelsPerScan.

 

And if you had any overrun or other error or not would be indicated by the return value of DAQmxReadAnalogF64(). So you should exit your loop not just when you acquired 60 minutes of data but any time your error variable gets unequal to success!

 

instead of:

 

while (true)
{
    bla bla;
    if (exit_condition)
        break;
}

 

you could do much more elegantly:

 

do
{
    bla bla;
} while (!error && elapsed_time < 60);

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 7
(62 Views)

Okay thank you, no I still have 4 parameters, at 100kHz, but today I don't have access to my system so I used a second card, the NI USB6002, just to test; but I will adapt later.

🙂

0 Kudos
Message 7 of 7
(53 Views)