# Obtaining the FFT of a data set collected through an accelerometer

I'm using MATLAB to analyse a very large sample of acceleration data collected using the MPU9150 IC. My aim is to plot the FFT for this large sample of data. The daya is of three axes; $x,y,z$ and I have successfully imported the data into matlab as vectors.

As I am new to MATLAB I have taken over month to plot the FFT graph but I believe its highly dependent on the smoothing factor. I wish to first illustrate my approach and then showcase my full code for your kind reference. Sampling frequency of of the accelerometer is 10 Hz.

Approach in exact order.

• Import the raw acceleration vector with $x,y,z$ axes Determine butterworth Filter parameters

• Apply butter-worth filter using filtfilt()

• use smooth() function with a smooth factor. ( NOTE: smoothing factor effects FFT shape significantly)

• obtain FFT using abs(fft(acceleration_DC_shifted_Filtered_Vector))

• smooth the FFT line using smooth function (this smoothing has no effect on FFT there fore can be skipped if required.)

• plot FFT

My code is below,

%importing data from workspace.
accelerationd2 = Xaccelday2;
% Setting basic Parameters. Number of samples should be same in all day files.         number_of_samples = length (accelerationd2); sampling_frequency = 10;

%Setting filtering paramters.
cut_off_frequency = 5;
wn = cut_off_frequency/sampling_frequency;

order_of_butterworth_filter = 1;
[b1,a1]= butter(order_of_butterworth_filter,wn,'low');

%Filtering data from all ten days.
accelerationd2_filtered = filtfilt(b1,a1,accelerationd2);

%DC shift removal

accelerationd2_smoothned= smooth(accelerationd2_filtered,36.5);%acceleration 1filtered was passed into all smoothfunctions
accelerationd2_DC_shifted = accelerationd2_filtered-accelerationd2_smoothned;

%Computing FFT
accelerationd2_FFT = smooth(abs(fft(accelerationd2_DC_shifted)),8000); %1000 is ballpark
bin_vals = (0 : number_of_samples-1);
fax_Hz = bin_vals*sampling_frequency/number_of_samples;
N_2 = ceil(number_of_samples/2);

%Detecting peaks
figure;
plot((fax_Hz(1:N_2)),(accelerationd2_FFT(1:N_2)),'r');
hold on
legend('Day-02');

%[maxtabDay1, mintabDay1] = peakdet(accelerationd1_FFT(1:N_2), 15, fax_Hz(1:N_2));
[maxtabDay2, mintabDay2] = peakdet(accelerationd2_FFT(1:N_2), 15, fax_Hz(1:N_2));

%This is where peaks are dressed with markers. Markers must have the same color of the line. Markers can be different symbols. Types of markers that can be used : ^ , *
plot(maxtabDay2(:,1), maxtabDay2(:,2), 'r*');
xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
title('Single-sided Magnitude Spectrum (Hz)');
%hold on
hold off
%axis tight


My problem is that the FFT changes highly as the smoothing factor in

 accelerationd2_smoothned= smooth(accelerationd2_filtered,36.5)


is changed. Any help would be so much appreciated.

Is it my thinking that there is only one correct FFT and the FFT should not change depending on the process I obtain it from?

Another important reason to note is that all samples have a DC shift. Which is why the smooth function has been used. If it is not used, the time domain is not brought about $y=0$-axis before inserting to the FFT function.

I would appreciate if a better procedure can be explained that can be used to obtain the FFT through MATLAB.

P.S. It would be nice to have a method I can obtain the FFT for my data set. I collected this data about the motion of an particular animal. And I need to generate the FFT for its movement. I have many records but not a proper method. My data goes like, $X_{\rm acceleration}, Y_{\rm acceleration}, Z_{\rm acceleration}$. But there can be DC shifts seen on the time domain because the animal because the collar which has the logger was not perfectly in the middle. Therefore I must remove these DC components caused by gravity.

• The DFT of a discrete signal is unique and reversible. That is, given the DFT you can reconstruct the original signal. If you change the signal, you change the DFT. Smoothing is a filtering operation. If it is linear filtering, then it can be implemented by a multiplication in the Fourier domain. This is why the DFT result looks different. – geometrikal May 2 '16 at 5:12
• could you please propose a method I can obtain the FFt for my data set? I collected this data about the motion of an perticular animal. And I need to generate the FFT for its movement. I have many records but not a proper method. My data goes like Xacceleration, YAcceleration, Zacceleration. But there can be DC shifts seen on the time domain because the animal because the collar which has the logger was not perfectly in the middle. Therefore i must remove these DC components caused by gravity. – Denis May 2 '16 at 5:33
• What kind of animal? I have a friend who did something similar with some sea snail things. – geometrikal May 2 '16 at 6:40
• This is an Elephant. I have millions of acceleration records (about 10 days) of acceleration data. I am requested to plot the FFT for atleast a day. – Denis May 2 '16 at 6:46
• Can you share a day's sample? :P – geometrikal May 2 '16 at 7:58

From you code it appears you do a low pass butterworth filter:

[b1,a1]= butter(order_of_butterworth_filter,wn,'low');
accelerationd2_filtered = filtfilt(b1,a1,accelerationd2);


Then another low pass moving average filter which you minus from the previous.

accelerationd2_smoothned = smooth(accelerationd2_filtered,36.5);
accelerationd2_DC_shifted = accelerationd2_filtered - accelerationd2_smoothned;


Yes, this second part will remove DC, but I think this is the first thing you should do. That is, use a HIGH pass butterworth filter (with a few more orders perhaps)

cut_off_frequency = 5;
wn = cut_off_frequency/sampling_frequency;
order_of_butterworth_filter = 4;
[b1,a1]= butter(order_of_butterworth_filter,wn,'high');
accelerationd2_filtered = filtfilt(b1,a1,accelerationd2);


Then apply the FFT. If there is two much high frequency noise, you can apply a low pass butterworth filter to the above output.

As for you analysis, the FFT uses the entire signal to compute. So any frequency magnitudes represent the average over the whole time series. That is, there is no time information in there. Since you have a large sample of animal data, I imagine you would want to see how things change over time, so I suggest instead using the STFT or some other wavelet transform.

In MATLAB you might get good results out of the box using spectrogram, no pre-filtering required.

window = 1000;
overlap = round(0.9*window);
s = spectrogram(accelerationd2,window,noverlap)
`