Reputation: 2685
After reading a lot of research and works on subject I still have got problems applying FFT to my accelerometer data. Most of my code is taken from official MATLAB example: FFT for one dimension. After more reading I've found this question: FFT and accelerometer data: why am I getting this output? where there was suggestion to use windowing. So after some more reading I've added hamming window to my code.
My data looks like that on plot:
And this is the code that I am using for FFT:
fs = 1/0.02; %0.02 comes from picking sample each 20ms
m = size(data,1);
w = hanning(m);
yw = w.*data;
n = pow2(nextpow2(yw));
y = fft(yw,size(n,1));
f = (0:size(n,1)-1)*(fs/size(n,1));
power = y.*conj(y)/size(n,1);
figure
plot(f,power)
The problem is that my plot from this code looks like that:
Can someone tell me what is wrong with my code? To be honest I'd excepted it would look better (something like this:https://i.sstatic.net/gNdag.jpg) so that's why I am asking this question.
EDIT: My data can be found here: https://dl.dropboxusercontent.com/u/58774274/exp.txt
Upvotes: 1
Views: 4073
Reputation: 4336
Your Fs
is 50
so the highest frequency in your data can be Fs/2 = 25Hz
.
See if this code helps.
fid = fopen('1.txt','r');
C = textscan(fid, '%f');
fclose(fid);
data = C{1};
fs = 50;
m = length(data);
nfft = 2^nextpow2(m);
y = fft(data,nfft)/m;
f = fs/2 * linspace(0,1,nfft/2+1);
power = abs(y);
subplot(211)
plot(f,power(1:nfft/2+1))
t = (0 : m-1)/fs;
s0 = .8*fs : 3.2*fs; % .8 sec to 3.2 sec
p(s0) = .5*cos(2*pi*3.3*t(s0)+.25*pi);
p = p + mean(data);
subplot(212)
plot(t,data);hold on
plot(t,p,'r')
This is your data in frequency domain.
There is a peak at 3.3 Hz
.
As a proof I plotted a sinusoidal with frequency of 3.3 Hz
along with your data,
As you can see, it totally matches your data.
Upvotes: 2
Reputation: 70693
Your plots will look better if you first remove the DC offset (subtract the average of all samples from each point before computing the FFT), and then plot only half the FFT result data points (N/2) or less (since the upper half of an FFT result is just a conjugate mirror of the first half for real data input).
Upvotes: 2
Reputation: 3892
What your reference plot shows is just the magnitude on a logarithmic scale (in dB). Also it seems that the DC offset is removed. So you end up with something like this if you adapt it in your code.
data = data-mean(data); % DC removal
fs = 50;
m = length(data);
nfft = 2^nextpow2(m);
y = fft(data,nfft)/m;
f = fs/2 * linspace(0,1,nfft/2+1);
power = abs(y);
plot(f,10*log10(power(1:nfft/2+1))); % plot log magnitude
ylim([-30 0]) %limit axis
Looks at least similar to me.
If you additionally take the absolute square you are basically estimating the power spectral density of your signal. So meaning you have to change power = abs(y);
to power = abs(y.^2);
and then obviously have to adapt your ylim([-30 0])
to something lower like -50.
Upvotes: 1