08-25-2013 12:41 PM
Hello!
I am working in a control system that will read the sensors, calculate the next output and send it to the output. Then read the sensors again and so on.
I have two DAQ boards, one USB-6009 and one MyDAQ. In the firsts tests I found the follow results (approximate):
================================
ANSI C NI-DAQmx
================================
Output Input Fa
--------------------------------
USB-6009 USB-6009 750Hz
USB-6009 MyDAQ 200Hz
MyDAQ USB-6009 300Hz
MyDAQ MyDAQ 150Hz
where Fa is the sample rate archived. The signal was a sinusoid.
This test was in the same computer, using all USB ports combinations.
The boards specifications regarding AI/AO rates are:
USB-6009
Input: 48KHz
Output: 150Hz
MyDAQ
Input: 200KHz
Output: 200KHz
Why the USB-6009 was better in this test, despite your poor specifications related with the MyDAQ board?
08-25-2013 04:05 PM
08-25-2013 04:33 PM
Thank you for your answer!
The DAQmx functions are DAQmxWriteAnalogScalarF64 and DAQmxReadAnalogScalarF64.
As the code is running in Windows 7 SP1, the rate is controlled using the QueryPerformanceCounter. This function seems more precise than the C clock() function.
The global variables DUR (signal length in secoonds) and FA (sample rate in Hz) are necessary for the correct memory allocation in the variables declaration.
I tested both boards (USB-6009 and MyDAQ) using this code, changing only the device name and the output range (0 to 5 for the USB-6009 and -10 to 10 for the MyDAQ). I added a 2V DC, so both boards can output the same signal.
Please see the code in the following lines:
#include "stdafx.h"
#include <stdio.h>
#include <NIDAQmx.h>
#include <time.h>
#include <math.h>
#include <tchar.h>
#include <windows.h>
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
#define PI 3.141592653589793 // pi
#define DUR 10 // signal length (s)
#define FA 750.0 // Sample rate (Hz)
int main(void)
{
int error=0;
TaskHandle taskHandleOut=0;
TaskHandle taskHandleIn=0;
char errBuff[2048]={'\0'};
float64 data[1] = {1.0};
clock_t ltime;
clock_t ptime;
clock_t ttime;
int i;
float f;
float Vp;
float Vdc;
float64 vout[(int)(DUR*FA+1)];
float64 vin[(int)(DUR*FA+1)];
__int64 ctr1 = 0, ctr2 = 0, freq = 0;
/*********************************************/
// DAQmx Configure Code
/*********************************************/
DAQmxErrChk (DAQmxCreateTask("",&taskHandleOut));
DAQmxErrChk (DAQmxCreateTask("",&taskHandleIn));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandleOut,"Dev1/ao0","",0,5.0,DAQmx_Val_Volts,""));
DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandleIn,"Dev1/ai0","",DAQmx_Val_Diff,-10.0,10.0,DAQmx_Val_Volts,NULL));
/*********************************************/
// DAQmx Start Code
/*********************************************/
DAQmxErrChk (DAQmxStartTask(taskHandleOut));
DAQmxErrChk (DAQmxStartTask(taskHandleIn));
/*********************************************/
// Output Signal
/*********************************************/
f = 50; // Signal frequency (Hz)
Vp = (float)1.42; // Signal Amplitude (V)
Vdc = 2; // DC level (V)
for(i=0;i<=DUR*FA;i++)
{
vout[i] = Vdc+sin(2*PI*f*(1/FA)*i);
}
QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
ttime = clock();
for (i=0;i<DUR*FA;i++)
{
QueryPerformanceCounter((LARGE_INTEGER *)&ctr1);
/*********************************************/
// DAQmx Write Code
/*********************************************/
DAQmxErrChk (DAQmxWriteAnalogScalarF64(taskHandleOut,false,5,vout[i],NULL));
/*********************************************/
// DAQmx Read Code
/*********************************************/
DAQmxErrChk (DAQmxReadAnalogScalarF64(taskHandleIn,5,data,NULL));
vin[i] = data[0];
QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);
// Sample Rate control
while((ctr2-ctr1)<((1/FA)*freq))
{
QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);
}
}
ttime = clock() - ttime;
printf("Total time of %lf seconds\n",(double)ttime/CLOCKS_PER_SEC);
getchar();
for(i=0;i<DUR*FA;i++)
{
printf("%llf\n",vin[i]);
}
Error:
if( DAQmxFailed(error) )
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( taskHandleOut!=0 ) {
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandleOut);
DAQmxClearTask(taskHandleOut);
}
if( taskHandleIn!=0 ) {
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandleIn);
DAQmxClearTask(taskHandleIn);
}
if( DAQmxFailed(error) )
printf("DAQmx Error: %s\n",errBuff);
printf("End of program, press Enter key to quit\n");
getchar();
return 0;
}
Thank you again!
Best Regards,
Rodrigo.
08-25-2013 05:17 PM
08-25-2013 05:59 PM
Of course, I know that. I do not expect put one sample and after read it and gain..., and reach the specifications hardware timed sample rate.
What I want to know is why the MyDAQ is so inferior than the USB-6009, despite its better specifications.
08-25-2013 06:35 PM
08-25-2013 07:03 PM
All things equal, the USB-6009 is better for this application in my setup.
The problem is that it is not marginally better, it is a lot better, 5 times faster in the dedicated config.