Determine signal frequency - matlab

I am trying to determine the frequency of a signal given as a vector in Matlab.
Any idea how to do it ?

use fft() function in Matlab.
This contains both the phase and amplitude, to get the amplitude only you can use abs(fft(..))

Related

How to correctly bandpass filter in frequency with MATLAB?

i'm pretty new to matlab and signal processing, but I am working on a project and I am stuck. My goal is to do a band-pass fast Fourier transform (FFT) filter with cut-off frequencies of 0.5 Hz and 3 Hz from a real signal. My input signal is a signal sampled ad 405Hz and of around 35000 samples. My implementation looks like this:
%ZFiltered = My signal
filtered = bandpass(fft(zFiltered), [0.5 3], sampling_frequency);
res = ifft(filtered);
subplot(2,1,1)
plot(zFiltered)
subplot(2,1,2)
plot(abs(res))
My questions are: Why do I get a signal which contains also imaginary part? Why does it look like this ?
Your goal is unclear to me; here are three different approaches that your question hints at
filter your raw signal with a band-pass filter as your code attempts to do
use the fft and ifft functions to filter your raw signal
calculate the coefficients of a digital filter that would act as a band-pass filter when used with the filter function
Approach 1: filtering with bandpass function
Referring to the bandpass documentation, you would use your original signal and specify the filter band and sampling frequency as in:
filtered_signal = bandpass(zFiltered,[freq_low freq_high],sample_freq);
plot(zFiltered); hold on;
plot(filtered_signal);
where the inputs are the
zFiltered : original (unfiltered signal)
freq_low=0.5 : lowest frequency in Hz of the band pass range`
freq_high=3 : highest frequency in Hz of the band pass range
sample_freq=405 : the sampling frequency in Hz
Your approach using digital fast Fourier transform function fft produces complex results because you are looking at the actual components computed by the transform (which by definition are complex having both real and imaginary parts). You can compute the power of the signal with:
P = abs(res/n).^2;
which gives you the power of the signal for each frequency represented in the Fourier transform (see the fft function docs here for more information).
Approach 2: Filtering with fft ifft functions
Use the Fourier transform and inverse Fourier transform functions to filter the signal. The steps here are to use fft to get the signal into the frequency domain. Set the elements you want filtered to zero and then apply the inverse Fourier transform (ifft) to get the filtered signal. Each component represents a given discrete frequencies in the range between 0Hz and F_s/2 that contributes to the signal. Set components of the FFT you want to suppress to zoro and apply ifft to get back a filter signal. Please see the fft docs and ifft docs for information on these functions and some of the intricacies of working with signals in the frequency domain.
Approach 3: Filtering with the coefficeints of the standard difference equation
Computing the coefficients of a digital band pass filter. This approach calculates the coefficients (vectors A and B) of the standard difference equation (see filter docs for details). An example of a function that does this is butter which gives the coefficients that represent a Butterworth filter of a given frequency. You could also look at the designfilt function for more options.

How can filter data to remove noise in matlab?

I have 2 arrays of 800000 input and output data samples of a system. The system in a kind of oven that works among 0 and 10 volts. The sample time is 0.001s.
I have to identify the model of this system, but first of all, given that the data are clearly dirty, I would like to filter the noise.
How can I do it with the System Identification Toolbox of Matlab?
Moreover, how can I estimate the cutoff frequency to remove the noise?
Thank you in advance.
PS: given that this is a bit out of topic, please, post your answer here thank you.
The cutoff frequency is directly given by you sampling time or sampling frequency.
you sampling frequency is 1/(sampling time) and must at least 2 the factor of the highest frequency of interest:
http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem
f_s = 1/T_s >= 2*f_cutOff
You can then simply to same frequency domain processing in the case you sampling frequency is realy high enough. The easiest way would to have a look at the frequency domain (with function fft() ). And check first where you have high noise components. Then filter out these components (zeroing) and then transform it back into time domain ( with function ifft() ).
Noise is modeled as a white Gaussian distribution in the simplest case. If you estimate the noise energy, you can make a dummy noise by calling
noise = A*randn(1,N);
Here, A is the amplitude and N is the sample count. then just take the fft of this signal and subtract it from the fft of input signal and take the inverse fft (ifft)

Confusion in figuring out the relation between actual frequency values and FFT plot indexes in MATLAB

I know that there are a lot of similar questions to this, I am still unable to figure out the answer.
Let's say we have time signal in MATLAB:
t=0:1/44100:1
and a cosine signal with frequency 500Hz:
x=cos(2*pi*500*t);
Now, I am trying to plot the magnitude spectrum obtained using the fft command on signal x
FFT=abs(fft(x))
plot(FFT)
According to the theory, we should get two peaks in the plot, one at -500 Hz and the other at 500Hz.
What I don't understand is that I do get two peaks but I can't figure out at what frequencies these peaks are. I know there is a way to figure out the frequency using the FFT index, length of the input signal and the sampling frequency but I still can't calculate the frequency.
I know that there are methods to align the FFT plots so that the peaks lie at the index number of the frequency they represent by using the fftshift function, but what I want is to figure out the frequency using the the plot resulting from simply calling this function:
FFT=fft(x)
In this case, I already know that signal contains a cosine of 500Hz, but what if the signal that we want to get the FFT of is not known before time. How can we get the frequency values of the peaks in that sample using the output from the fft function?
You need to generate the frequency array yourself and plot your FFT result against it.
Like this:
function [Ycomp, fHz] = getFFT(data, Fs)
len = length(data);
NFFT = 2^nextpow2(len);
Ydouble = fft(data, NFFT)/len; % Double-sided FFT
Ycomp = Ydouble(1:NFFT/2+1); % Single-sided FFT, complex
fHz = Fs/2*linspace(0,1,NFFT/2+1); % Frequency array in Hertz.
semilogx(fHz, abs(Ycomp))
end
You will see peaks at 500 Hz and Fs - 500 Hz (i.e. 44100 - 500 = 43600 Hz in your particular case).
This is because the real-to-complex FFT output is complex conjugate symmetric - the top half of the spectrum is a "mirror image" of the bottom half when you are just looking at the magnitude and is therefore redundant.
Note that of plotting power spectra you can usually save yourself a lot of work by using MATLAB's periodogram function rather than dealing directly with all the details of FFT, window functions, plotting, etc.

How to calculate user defined SNR, given only sampling frequency and a vector containing signal samples?

So I have the samples (hex values) of a sinus signal and I know the sampling frequency. Using this I can plot an fft or periodogram but then I would like to find out the SNR ratio. What would be the most accurate way to calculate the noise and signal power? I would prefer doing it in frequency domain. Is there a way to do this also in time domain?
Thanks a lot in advance!!!
So if there is noise on your signal and you know that your underlying signal is a sine wave, you can easily get your signal parameters i.e. amplitude,frequency and phase by least squares. If y(t) is your signal just minimize the L2 norm of (y(t)-A.sin(wt+b)) over A,w and b. Then you can easily get signal power from the underlying signal and the noise power from the error signal (y(t)-A.sin(wt+b)).

How to get coefficients for sine/cosine function from complex FFT in Matlab?

I'm working on a control system that measures the movement of a vibrating robot arm. Because there is some deadtime, I need to look into the future of the somewhat noisy signal.
My idea was to use the frequencies in the sampled signal and produce a fourier function that could be used for extrapolation.
My question: I already have the FFT of the signal vector (containing 60-100 values e.g.) and can see the main frequencies in the amplitude spectrum. Now I want to have a function f(t) which fits to the signal, removes some noise, and can be used to predict the near future of the signal. How do I calculate the coefficients for the sine/cosine functions out of the complex FFT data?
Thank you so much!
AFAIR FFT essentially produces output as a sum of sine functions with different frequencies. The importance of each frequency is the height of each peak. So what you really want to do here is filter out some frequencies (ie. high frequencies for the arm to move gently) and then come back to the time domain.
In matlab this should be like going through the vector of what you got from fft, setting some values to 0 (or doing something more complex to it) and then use ifft to come back to time domain and make the prediction based on what you get.
There's also one thing you should consider while doing this - Nyquist frequency - this means that the highest frequency that you get on your fft is half of the sampling frequency.
If you use an FFT for data that isn't periodic within the FFT aperture length, then you may need to use a window to reduce spurious frequencies due to "spectral leakage". Frequency estimation techniques to better estimate "between bin" frequency content may also be appropriate. The phase of each cosine sinusoid, relative to the edge of the window, is usually atan2(imag[i], real[i]). The frequency depends on the sample rate and bin number versus the length of the FFT.
You might also want to look into using a Kalman filter instead of an FFT.
Added: If your signal isn't exactly integer periodic in the FFT length, then you may want to do an fftshift before the FFT to move the resulting phase measurement reference point to the center of your data vector, instead of a possibly discontinuous circular edge.