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.