06-11-2009 07:21 AM
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
}
}
(…)
Solved! Go to Solution.
06-12-2009 03:41 AM
Hello? Could someone respond please?
Thanks!
06-15-2009 09:48 AM
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.
06-26-2009 07:22 AM
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