Amplitude-Frequency response peaks at zero, how to fix?

I made an amplitude-frequency response curve but I have a peak at 0 Hz. I'm not sure why but I know for sure that this is definitely wrong. The peak should be around 125 Hz. How do I get rid of the zero peak? I have attached the code and the excel data file. Thanks!
f = xlsread(e);
%plotting the signal
t = f(:,1);
X1 = f(:,2);
data_d = detrend(X1,1);
subplot(2,1,1)
plot(t,X1);
hold on
plot(t,data_d, 'g')
hold off
%Some of the envelope code was not working properly because MATLAB read
%some lines of the excel file as infinite numbers. The envelope function
%does not take infinite numbers.
%Thus, the below code deletes the infinite numbers from the array. There
%are only 2 of them.
fin = isfinite(X1);
t = t(fin);
signal = X1(fin);
Fs = 5000;
%Since the signal is real-valued, we use only the positive frequencies from
%the DFT to estimate the amplitude. Scale the DFT by the length of the
%input signal and multiply all frequencies excep 0 and the Nyquist by 2.
xdft = fft(signal);
xdft = xdft(1:floor(length(signal)/2+1));
xdft = xdft/length(signal);
xdft(2:end-1) = 2*xdft(2:end-1);
freq = 0:Fs/length(signal):Fs/2;
subplot(2,1,2)
plot(freq,abs(xdft))
hold on
plot(freq,ones(floor(length(signal)/2+1),1), 'LineWidth', 2)
xlabel('Hz')
ylabel('Amplitude')
xlim([0 200])
ylim([0 0.02])
hold off

 Accepted Answer

The peak at 0 Hz is the direct-current (d-c) or constant offset. You can eliminate it by subtracting the mean of the signal before taking the Fourier transform.
xdft = fft(signal - mean(signal));

12 Comments

By the way, you might want to use fftshift() rather than throw away half your spectrum.
fftshift() instead of fft()?
@Chinwe Orie — As always, my pleasure!
Also, a one-sided Fourier transform is perfectly fine if you want to explore the frequency content of your signal. (You will need the full Fourier transform only if you later want to do an inverse Fourier transform, and if you use fftshift, you will then need to re-shift it back to the original.)
Your current code is correct, although I prefer the code in fft (link), simply because I am used to using it.
Ok I understand. I do have one more question though.
The code above is mostly from a MATLAB example called https://www.mathworks.com/help/signal/ug/amplitude-estimation-and-zero-padding.html
I was wondering why the "ones(floor(length(signal)/2+1),1" part (the second plot in my code) is the amplitude of my signal.
In the code in the documentation you referenced, Amplitude Estimation and Zero Padding (link), that is part of a plot call that draws a horizontal line at 1 for all the frequencies in your Fourier-transformed data. It does not appear on your plot because the y-axis limits do not include 1.
It is the amplitude of the signal peak in the documentation example. I cannot determine if it is the peak amplitude of your signal.
Oh ok. Well in that case, what's the best way to determine the amplitude of any signal (let's say, mine for example)?
For one peak, I would use the max function on abs(xdft). Another option is findpeaks (again on abs(xdft)) if you have more than one peak. Use the name-value pair arguments in findpeaks to limit what it looks for and therefore the results it returns.
And then if one wanted to plot the amplitude and frequency together?
The plot of the Fourier transformed signal already does that (plotting amplitude as a function of frequency).
Ah yes, that's true. But doesn't it do the plot using normalized frequency? Is there a way to convert normalized to the regular frequency scale?
The only ‘normalized frequency’ I’m aware of uses a scale from 0 to pi. The frequency otherwise goes from 0 to the Nyquist frequency (half the sampling frequency).

Sign in to comment.

More Answers (0)

Products

Release

R2018a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!