Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Continuous Data Acquisition with DAQmx with NI USB- 6210 problem with long execution time. No problems with PCI-6014.

Solved!
Go to solution

Background

 

I have a scanning software (using C++ and nidaqmx) which reads data from 4 analog channels to 4 digital channels. The purpose of the software is to sample data continuously on 4 analog channels  measuring data from 48 voltage sensors  (4X12). The system works by taking 10 readings and averaging them to give a data point every 1000ms. 

 

Using PCI-6014, the data readings were perfect and the time between samples is ~1sec.

 

After using NI PCI 6014 for sometime and following recommendations from NI, we swtiched to USB 6210 (M Series) in the aim of getting a more robust DAQ system.

 

Problem

 

Touted by the people at NI as similar to the PCI-6014, the USB-6210 gave us slower 'time between samples' ~2sec, using the same program and system. This is very curious. Having doing the due diligence of reading forum entries who might show others that have the same problem, I came across:

 

DAQmx's DAQmxReadAnalogScalarF64 takes way too long to execute with USB-6221

 

DAQmx's DAQmxReadAnalogScalarF64 takes long time to execute

 

 

I have a few questions:

 

1) Is it a technicality issue, that the USB-6210 is limited in its function compared to PCI? This is not expected because the max freq that we think we use is only 1kHz. The specification on the USB 6210 is 16bit, 250kS/s. Could NI comment on this?

 

2) Should one put in a DAQmxCfgSampClkTiming function?

 

3) Has anyone else encountered the same situation of long response time in USB cards? Are there any solutions?

 

 

I would love to hear from this community. Thank you so much!

 

 

Regards,

Zhihan

 

 

My code snippet is attached and also found here:

 

(…)
if (pParent)
{
CSingleLock lock(&(pParent->m_cs));
TaskHandle taskHandle[NUMBER_OF_BLOCKS], writeTask;
int32 error=0, read;
int block, ch;
char sDev[] = "Dev*/ai0", controlDev[] = "Dev*/port1/line0:3";
uInt8 cs[8]={0,0,0,0,0,0,0,0};
sDev[3] = '0' + pParent->m_NiDaqDevice;
controlDev[3] = '0' + pParent->m_NiDaqDevice;
for (block = 0; block < NUMBER_OF_BLOCKS; block++)

 

{
sDev[7] = '0' + block;
taskHandle[block] = 0;
DAQmxErrChk (DAQmxCreateTask("", &taskHandle[block]));
DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle[block], sDev, "", terminalConfig, -5.0, 5.0, DAQmx_Val_Volts, NULL));
}


DAQmxErrChk (DAQmxCreateTask("",&writeTask));
DAQmxErrChk (DAQmxCreateDOChan(writeTask, controlDev, "", DAQmx_Val_ChanForAllLines));
for (;;)


{
CTime currentTime = CTime::GetCurrentTime();
_timeb tb;
_ftime(&tb);
int nHwSwitchTime = HW_SWITCH_TIME; // default value
iniReader.getKeyValue(HW_SWITCH_TIME_S, A_DATA_S, nHwSwitchTime);
INT_PTR nWell = 0;
CMeasurement *measurement = new CMeasurement(NUMBER_OF_BLOCKS * NUMBER_OF_CHANNELS + 1); // Add 1 for termistor
if (measurement)

 

{
measurement->SetTimeStamp(currentTime);
measurement->SetTerminalConfig(sMeasurementMethod);
for (ch = 0; ch < NUMBER_OF_CHANNELS; ch++)

 

{
// Select channel


cs[0] = ((ch & 1) != 0); cs[1] = ((ch & 2) != 0); cs[2] = ((ch & 4) != 0); cs[3] = ((ch & 😎 != 0);
DAQmxErrChk (DAQmxWriteDigitalLines(writeTask, 1, 1, 0.1, DAQmx_Val_GroupByChannel, cs, NULL, NULL));
// Sleep a while to make sure the HW is ready for measuring
Sleep(nHwSwitchTime);
for (block = 0; block < NUMBER_OF_BLOCKS; block++)

 

{
nWell = ch + block * NUMBER_OF_CHANNELS;


// Read sample


DAQmxErrChk (DAQmxReadAnalogF64(taskHandle[block], nSampleBuffer, 10.0, DAQmx_Val_GroupByChannel, sample, nSampleBuffer, &read, NULL));
qsort(sample, read, sizeof(float64), compare_float64);
double dSum = 0.0, dMean = 0.0;
int nUpperBound = min(read - 1, nEndIndex);
for (int i = nStartIndex; i <= nUpperBound; i++)
dSum += sample[i];
if (nUpperBound >= nStartIndex)
dMean = dSum / (nUpperBound - nStartIndex + 1);
measurement->SetChannelData(nWell, -dMean * dVoltageFactor);
}


}
pParent->AddBMeasurement(measurement);
if (pParent->m_TerminateThread.Lock(timeBetweenSamples(&tb)) != 0) // Wait unless...
break; // ...the event is signaled then terminate
}
}
(…)

 

0 Kudos
Message 1 of 4
(4,525 Views)

Hello? Could someone respond please?

 

Thanks!

0 Kudos
Message 2 of 4
(4,493 Views)

Hi Zhihan,

 

Thanks for posting on the NI forums.  First off, I would definitely recommend to configure your sample clock in your program by using the function DAQmxCfgSampClockTiming.  This will give you the deterministic timing (up to 250KS/s) when taking your measurements.  Currently you do not have this specified anywhere in your program.  

 

Also as Andrew S posted in in the forum "DAQmx's DAQmxReadAnalogScalarF64 takes way too long to execute with USB-6221" that you linked above, the usb bus will add some latency to the measurement compared to the PCI bus.  So, it will take longer to transfer your samples from the USB device to LabVIEW.  This is probably why you are seeing this time delay in your program. 

 

The USB-6210 is similar to the PCI-6014 but an important difference is the bus type.  The NI recommended upgrade from the PCI-6014 is the PCI-6221.

Regards,
Jordan F
National Instruments
Message 3 of 4
(4,460 Views)
Solution
Accepted by topic author clader

Hi Jordan

 

Thanks for your reply. The solution was not the sample clock function. We just made the code more efficient through another way of data collection in the DAQ. This solved the time lag. Thanks anyway! 

 

Regards,

Zhihan

0 Kudos
Message 4 of 4
(4,407 Views)