0
votes

I have an array (size 128) of data that I am using FFT on. I am trying to find the frequency of the data through the FFT spectrum. The problem is that the formula freq = i * Fs / N doesn't seem to be working. My data is quite noisy and I don't know if it is because of my noisy data or because I am doing something else wrong. Below is my raw data:

Raw Data

And this is the spectrum that results from the transform:

Spectrum

I am getting two maximum peaks of equal magnitude at index 4 and 128 in the output array. The frequency of the data should be around 1.1333 Hz, but I am getting 5-6 or completely wrong values when I use the formula:

freq = i * Fs / N;

where i is the array index of the largest magnitude peak, Fs is the sampling rate in Hz, and N is the data size.

Using my data, you get freq = (4 * 11.9) / 128 = 0.37 Hz, which is very off from what is expected.

If my calculation is correct, are there any ways to improve my data? Or, are my calculations for frequency incorrect?

2
For one your spectrum seems to contain 256 points, so I'm guessing you are plotting interleaved real & imaginary parts rather than the magnitudes. If i is the index shown in your Spectrum plot, then the result will be off by a factor of 2 (not helping your case though). Then you have a strong average value/very low frequency component (the section of raw data varies between 98-100, instead of near 0) which would naturally appear in the lower spectrum bins. Remove that bias and you might better see spectrum peaks associated with you data oscillations.SleuthEye
By the strong average value do you mean the peaks on the edges of the spectrum? I removed around 1/5th of the spectrum on each side and got this: image link . So I'm guessing my data is just too noisy to create an accurate frequency spectrum?Piglet
I'm also confused about the index of the maximum magnitude. Assuming there are 256 data points, and imaginary parts are interleaved, if the highest magnitude was at index 90, would I say i = 45 since the 45th real value would be at index 90?Piglet

2 Answers

1
votes

Lets first make sure you are looking at the actual magnitudes. FFTs would return complex values associated with each frequency bins. These complex values are typically represented by two values: one for the real part and another for the imaginary part. The magnitude of a frequency component can then be obtained by computing sqrt(real*real+imaginary*imaginary).

This should give you half as many values and the corresponding spectrum (with the magnitudes expressed in decibels):

enter image description here

As you can see there is a strong peak near 0Hz. Which is consistent with your raw data having a large average value, as well as an increasing trend from time 0 to ~4.2s (both of which being larger than the oscillations' amplitude). If we were to remove these low frequency contributions (with for example a high-pass filter with cutoff frequency around 0.25Hz) we would get the following fluctuation data:

enter image description here

with the corresponding spectrum:

enter image description here

As you can see the oscillation frequency can much more readily be observed in bin 11, which gives you freq = (11 * 11.9) / 128 = 1Hz.

Note however that whether removing these frequency components bellow 0.25HZ is an improvement of your data depends on whether those frequency components are of interest for your application (possibly not since you seem to be interested in relatively faster fluctuations).

-1
votes

You need to remove the DC bias (average of all samples) before the FFT to measure frequencies near 0 Hz (or near the FFT's 0th result bin). Applying a window function (von Hann or Hamming window) after removing the DC bias and before the FFT may also help.