08-15-2008 10:49 AM
I'm using the USB 6009 to acquire audio in the form of a sine wave via analog inputs. My goal is to acquire the audio and determine the Fundamental frequency and THD+N of the signal much like the SignalExpress tool does when using the Analysis->Frequency-Domain measurements->Distortion block. I'm using the C API calls in a C++ program. My first question, are there C API calls to get the Distortion measurements?
My other issue is that when I perform a DAQmxReadRaw, for data format I expect a 16 bit integer representation of a sine wave but the values are all over the place, representing more of jagged sawtooth than a sine wave. Maybe I'm handling the data wrong? I'm passing a char array into the ReadRaw call and getting what looks to be valid data although I'm not sure of the raw data format for the device. Maybe I'm setting up the timing / sampling params wrong. SignalExpress has no problems, so it must be something I'm doing. Here's my very simple setup of the task: DAQmxErrChk (DAQmxCreateTask("",&taskHandle)); DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",DAQmx_Val_RSE,-2,2,DAQmx_Val_Volts,NULL)); DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"OnboardClock",10000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,1000));DAQmxDisableStartTrig( taskHandle ); DAQmxErrChk (DAQmxStartTask(taskHandle)); DAQmxErrChk (DAQmxReadRaw( taskHandle, -1, 10.0, Samples, 1000*2, &SamplesRead, &NumBytesPerSample, NULL));
Thanks for any suggestions,
Patrick |
08-15-2008 01:38 PM
I am a DAQ guy so I don't have an answer for your first questio.
But for your issue with DAQmxReadRaw, from NI-DAQmx C Reference Help, "DAQmxReadRawReads raw samples directly from the input lines. There is no scaling, parsing, or separation of the samples. Refer to the specifications for your device to determine the format of the incoming samples." So it is possible that when you read raw data from 6009, the data is not even separated by samples. If you want to read data in unscaled 16-bit integer representation, why don't you try DAQmxReadBinaryI16 or DAQmxReadBinaryU16? DAQmxReadBinaryI16 reads multiple unscaled, signed 16-bit integer samples; DAQmxReadBinaryU16 reads multiple unscaled, unsigned 16-bit integer samples. I am not sure if 6009 returns signed or unsigned data looking at its specification document on ni.com. It only says that 6009 returns 14-bits data in differential mode and 13-bits data in single-ended mode for analog input.
08-15-2008 02:54 PM
I appreciate the feedback! I did try both DAQmxReadBinaryU16 and DAQmxReadBinaryI16. I get the same result as when I call DAQmxReadRaw and pass in an INT16 array. The values come back between ~ -14000 and -19000 when they should be ranging from ~ -32,000 to 32,000 for the full scale sine wave I'm capturing. As you pointed out, it's hard to find out what the data format is for the DAQmxReadRaw API call. I can't find it either. All I know is that it's 2 bytes per sample and the ADCRawSampleSize property call returns 16 bit.
I keep thinking I must be setting up the task wrong wrong or I need to set some properties. Like I said, SignalExpress shows a clean sinewave on the input.
08-15-2008 03:29 PM
I just noticed that in your code
DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",DAQmx_Val_RSE,-2,2,DAQmx_Val_Volts,NULL));
You are setting up the channel to acquire data in RSE mode and RSE mode only has a 13-bit resolution versus 14-bit resolution for differential. I just tried to do the same with a simulated device; the default for ai channels in SignalExpress seems to be differential. How is your signal connected to the device? AI 0+ and AI 0- as in differential mode or AI0 and GND for RSE mode.
You are setting the range to be (-2 V, 2 V). I am assuming that you are giving it a sine wave with an amplitude of 2?
08-15-2008 04:12 PM
The physical connection is AI0 and GND for RSE mode. The sine wave I'm acquiring is ~-1.25 to 1.25 volts. The sine wave is produced on another computer, played out the headphone port and captured with the USB DAQ. It's a stereo signal so the left channel sine wave is acquired by Dev1/ai0 and the right channel by Dev1/ai1 with the cable shield being the GND. I'm only looking concerned with the one input at the moment. I'm duplicating the setup parameters I'm using with SignalExpress since it seems to capture the signal just fine.
08-15-2008 05:01 PM
08-15-2008 06:17 PM
This is certainly very strange because the only difference between DAQmxReadAnalogF64 versus DAQmxReadBinaryU16 and DAQmxReadBinaryI16 is whether the driver applies the calibration constants or not. Can you show me how are you calling DAQmxReadBinaryU16 and DAQmxReadBinaryI16? What parameter do you feed into the functions, esp. the type of the parameters? Can you also post a graph of the data you get when you do DAQmxReadBinaryU16 and DAQmxReadBinaryI16?
Another thing, I look at 6009 spec, it seems like for RSE measurement there is only only range (-10,10), so a sine wave of amplitude 1.25 will not be utilize the the full range of the 13 bit resolution in RSE mode.
Single-ended ................................... ±10 V
Differential...................................... ±20 V, ±10 V, ±5 V, ±4 V, ±2.5 V, ±2 V, ±1.25 V, ±1 V
08-15-2008 07:36 PM
Here's the call:
INT16 Samples[1000];
DAQmxErrChk (DAQmxReadBinaryI16( taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, Samples, 1000, &SamplesRead, NULL));
I just graphed the data and it does look like a sinewave! I'm not sure what I changed from earlier today when it looked sawtooth but, it's greatly attenuated compared to full scale. If you still want to see it, I can post a little later on.
So, maybe it has to do with the the spec, Single-ended ... ±10 V? I wonder if I multiplied all the values by a constant to bring it to full scale if that would help, however, the data is still between -14000 and -19000 so it's offset. Ideally it would be centered ~-2500 to 2500 on a -32767 to 32767 scale if it was just a matter of being attenuated.
We always measure audio as single ended with a ground reference or floating on our high dollar audio analyzer. I'm looking at this USB DAQ as poor man's alternative when the precision equipment is not available.
08-18-2008 02:01 PM
I dug around the hardware specification for 6009 for a bit and figure out why the device return raw data like what you are seeing.
Due to the funky nature of ADC on board, in single-ended mode the ADC's range actually gets cut into half, so instead of 0x0000 being the min code and 0xFFFF being the max code, 0x8000 is actually the min code and 0xFFFF is actually the max code in RSE mode. So -10V in RSE mode would be return in code that is close to 0x8000 and 10V in RSE would be return in code that is close to 0xFFFF.
If you do the math (1.25V - (-10V)) / ( 20V / 0x7FFF ) + 0x8000 = 51200 which is C800. If you reinterpret C800 as INT16 then it is -14336. If you do ( -1.25V - (-10V)) / ( 20V / 0x7FFF ) + 0x8000 = 47104 which is B800. If you reinterpret B800 as INT16 then it is -18432. The values I am using are all ideal values without calibration; the values you are getting between -14000 and -19000 actually correspond with the nature of the ADC.
I hope this explains 6009's behavior better. I also attached two links to knowledgebases on ni.com that might shred some light on the nature of the circuitry in 6009.
Explanation of the Analog Input Circuitry on the 6008/6009
http://digital.ni.com/public.nsf/allkb/C7E181E51E4299FC862570A700604141?OpenDocument
Why Does My USB 6008/6009 Have Different Resolutions for Differential and Single-Ended Measurements?
http://digital.ni.com/public.nsf/allkb/36D8A8E6F047F313862573D10080547C?OpenDocument
08-18-2008 03:35 PM