04-24-2024 05:53 AM
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.
Solved! Go to Solution.
04-24-2024 10:36 AM
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.
04-25-2024 01:31 AM
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;
}
04-29-2024 05:33 AM - edited 04-29-2024 05:34 AM
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!
04-29-2024 07:24 AM
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
04-29-2024 08:06 AM - edited 04-29-2024 08:08 AM
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);
04-29-2024 09:00 AM
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.
🙂