Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

FFT Results: Incorrect results for different signal shapes

I am using Measurement Studio 8.1 to read an analog input that I would like to get the frequency from. It would be simpler to use a counter but one is not available so I am resorting to using an analog scan of the channel then a FFT to get the frequency. In the real application the signal will be coming from a hall effect sensor reading an RPM. For testing I am sampling at 10kHz, my test signal is at 400Hz, and I am gathered 2500 points/channel.

During development I am using a signal generator to test the program. I thought I had it working fine because when I use a sine, square, or triangle wave with a 50% duty cycle all works well and my program does exactly what I want. The problem is, I started to test with a square wave of varying duty cycle and now it is not working. First it was reading zero because my simple algorithm was grabbing the DC component for it's calculation. Fixed that. But now I have a situation where my FFT result looks to be double or sometimes triple what the test signal frequency is. I do not claim to be a FFT or PowerSpectrum expert but I did find a few good articles at NI developer zone that make me think I am doing the basics right. The help files don't give examples, just equations. I did run the sample program called Filtering and if you vary the suty cycle of the square wave in that sample I think I can see why I am getting the problem I am getting, I just don't know how to fix it.  If a multimeter is smart enough to give me the right frequency of the signal I'm sure Measurement Studio can do the same...I just don't know how.  The function I am using to get the frequency from an analog signal is listed below.  Any suggestions would be greatly appreciated.

public static double CalcFrequencyViaFFT(double[,] AIScandata, int arrayIndexForCalc, int scanRate)
{
double[] dataRow;
double[] dataRowCopy;

double mx, mn, offset, scale;
int idxMax, idxMin;

//Extract Row to be used for calculation
dataRow = ArrayOperation.CopyRow(AIScandata, arrayIndexForCalc);
dataRowCopy = (double[]) dataRow.Clone();


//Scale copy to -1 to 1 signal
dataRowCopy = ArrayOperation.Scale1D(dataRowCopy, out offset, out scale);

int datasize = dataRow.Length;

ComplexDouble[] FFTValue;
double[] magnitudes;
double[] phases;
//Perform FFT
//FFTValue = Transforms.RealFft(dataRow);

//Try using power spectrum to see if it can give the same result more directly
// ** In the end gives same result as .RealFft. TODO: benchmark to see which is faster
Transforms.PowerSpectrum(dataRowCopy);
dataRowCopy[0] = 0.0; //Get rid of DC component so I can find variable component
ArrayOperation.MaxMin1D(dataRowCopy, out mx, out idxMax, out mn, out idxMin);

//Use FFT data
//ComplexDouble.DecomposeArrayPolar(FFTValue, out magnitudes, out phases);
//ArrayOperation.MaxMin1D(magnitudes, out mx, out idxMax, out mn, out idxMin);

// Console.Out.WriteLine("\t\tDEBUG INFO: scanrate,datasize,idxMax={0}, {1}, {2}",
// scanRate,datasize,idxMax);

return (double) scanRate/datasize*idxMax;
} //end CalcFrequencyViaFFT
0 Kudos
Message 1 of 11
(4,668 Views)
Cnuk,

You might try implementing the frequency measurement discussed in this thread to see if that has any effect.

Message Edited by Jon M on 04-11-2007 10:42 AM

Test Engineer - CTA
0 Kudos
Message 2 of 11
(4,663 Views)
The PeakDetector is definitely a better option for what I'm doing.  I still have problems getting it to work consistently for a square wave however.  The signal generator looks very clean yet the PeakDetector still picks up false peaks.  Using a combination of Amplitude and 2nd Derivative I still don't have a solution that works 100% for square waves.  At this point I'm just hoping the real signal in is not a square wave which is a pretty poor solution.
 
Any other suggestions to improve the square wave performance?
0 Kudos
Message 3 of 11
(4,648 Views)
From your code it looks like you were using both Transforms.RealFft and Transforms.PowerSpectrum. Have you also tried using Transforms.Fft or Transforms.Fft2D and do they yield similiar results?
Test Engineer - CTA
0 Kudos
Message 4 of 11
(4,643 Views)
You could also try the Measurements.AutoPowerSpectrum instead of Transforms.PowerSpectrum as well.
Test Engineer - CTA
0 Kudos
Message 5 of 11
(4,643 Views)
I have Measurement Studio 8.1 Pro and I don't see an AutoPowerSpectrum listed in the help file anywhere.  Do I need a different version or am I blind?

Thanks
0 Kudos
Message 6 of 11
(4,636 Views)
AutoPowerSpectrum is part of the Enterprise version of Measurement Studio.
Test Engineer - CTA
0 Kudos
Message 7 of 11
(4,618 Views)
So I'm out of luck.  Anything else in the Pro version that may be more successful than what I'm already trying?
 
Thank You
0 Kudos
Message 8 of 11
(4,610 Views)
Does the SpectrumAnalyzer example located at C:\Program Files\National Instruments\MeasurementStudioVS2005\DotNET\Examples\DAQmxWithUI\SpectrumAnalyzer display the frequency correctly? I tested this example with a 100hz, 1khz and 13khz square wave with an acquisition rate of 100khz and it appeared to work correctly.
Test Engineer - CTA
0 Kudos
Message 9 of 11
(4,596 Views)
I don't have a SpectrumAnalyzer example in my examples directory.
0 Kudos
Message 10 of 11
(4,548 Views)