Matlab FM Demodulation and Get Rid of Phase Folding Effect - matlab

I have a matlab code to Frequency modulation and demodulation a signal. My code is work well for modulation part. My message signal is m and modulated signal is u, code plot the message signal and its integral in one graph for plotting 1.
Then signal modulated with carrier and program plots the modulated signal in time domain for plotting 2.
After that, by the help of some code blocks program find the frequency spectrum of modulated signal and message signal to plot graph of them for plotting 3.
In demodulation part program make some fundamental calculation for FM detection, then to obtain message signal it uses filter.
Last part program plots the graph of recovered signal with message signal to compare them.
I summarized all code because ı do not know whre is the problem.
My problem about plotting 3 when I make zoom graph 3 I see some phase foldings or like it.Graph is not symmetric according to y-axis.
I did not solve this problem, I research about them and I decided to use unwrap(). Although I tried a lot, I could not be successful. How can I get rid of this phase folding with unwrap() function. Thank you.
My matlab code is ;
ts = 0.0001;% Sampling interval
t0 = 0.15; % Duration
t = 0:ts:t0;% define time vector
%% OTHER PARAMETERS
fc = 200; % Carrier signal frequency
kf =50; % Frequency deviation constant
fs = 1/ts; % Sampling frequency
%% MESSAGE SIGNAL SIMPLY
m = 1*(t<t0/3)-2*(t<2*t0/3).*(t>=t0/3);
%% Integration of m
int_m(1) = 0;
for k =1:length(m)-1
int_m(k+1) = int_m(k) + m(k)*ts;
end
%% PLOTTING 1
figure; subplot(211); % Message signal
plot(t,m);grid on;xlabel('time');ylabel('Amplitude');
title('m(t)');ylim([-3 2]);
subplot(212);plot(t,int_m);% Integral of message signal
grid on; xlabel('time');ylabel('Amplitude');title('integral of m(t)');
ylim([-0.07 0.07]);
%% FM MODULATED SIGNAL
u = cos(2*pi*fc*t + 2*pi*kf*int_m);
%% PLOTTING 2
figure; plot(t,u); % Modulated signal in time domain
grid on;xlabel('time');
ylabel('Amplitude');title('FM :u(t)');
ylim([-1.2 1.2]);
%% FINDING FREQUENCY SPECTRUM AND PLOTTING 3
% Frequency spectrum of m(t)
f=linspace(-1/(2*ts),1/(2*ts),length(t));
M=fftshift(fft(m))./length(t); % Taking fourier transform for m(t)
U=fftshift(fft(u))./length(t); % Taking fourier transform for u(t)
figure;subplot(211); % Frequence spectrum of m(t)
plot(f,abs(M)); grid;
xlabel('Frequency in Hz');xlim([-500 500]);
ylabel('Amplitude');title('Double sided Magnitude spectrum of m(t)');
subplot(212);plot(f,abs(U)); % Frequency spectrum of u(t)
grid;xlabel('Frequency in Hz');xlim([-500 500]);
ylabel('Amplitude');title('Double sided Magnitude spectrum of u(t)');
%% DEMODULATION (Using Differentiator)
dem = diff(u);
dem = [0,dem];
rect_dem = abs(dem);
%% Filtering out High Frequencies
N = 80; % Order of Filter
Wn = 1.e-2; % Pass Band Edge Frequency.
a = fir1(N,Wn);% Return Numerator of Low Pass FIR filter
b = 1; % Denominator of Low Pass FIR Filter
rec = filter(a,b,rect_dem);
%% Finding frequency Response of Signals
fl = length(t);
fl = 2^ceil(log2(fl));
f = (-fl/2:fl/2-1)/(fl*1.e-4);
mF = fftshift(fft(m,fl)); % Frequency Response of Message Signal
fmF = fftshift(fft(u,fl)); % Frequency Response of FM Signal
rect_demF = fftshift(fft(rect_dem,fl));% Frequency Response of Rectified FM Signal
recF = fftshift(fft(rec,fl)); % Frequency Response of Recovered Message Signal
%% PLOTTING 4
figure;subplot(211);plot(t,m);grid on;
xlabel('time');ylabel('Amplitude');
title('m(t)');ylim([-3 2]);
subplot(212);plot(t,rec);
title('Recovered Signal');xlabel('{\it t} (sec)');
ylabel('m(t)');grid;
My problem is in this third graph to show well I put big picture

k = -(length(X)-1)/2:1:length(X)/2;
Your k is not symmetric.
If you work with symmetric k is it working fine?

Related

Applying bandpass in the Fourier for my signal in matlab

I'm trying to apply a bandpass around freq 0 without luck. I'd be happy to receive some help please
x=scan11(1,:)*1e-3/3e8; y=scan11(2,:);
plot(x,y) % my function
[XX,ff]=trans_fourier(y,mean(diff(x)));
plot(ff,abs(XX)) % gives the Fourier transform
I want to choose the freq around 0. let's suppose -1e13 till 1e13 and than to make ifft and to plot the signal after this filer.
How should I start doing this? the command
YY=bandpass(y,[-1e13 1e13],1/mean(diff(x)))
didn't help here unfortunately.
Since, i can't upload here files, here is also my question on matlab forum with all the files
matlab link
I am not sure what the contents of the trans_fourier function exactly are, but in 'plain matlab functions', you could attempt something along the lines of the following.
Nt = 1024; % Number of samples
Fs = 10; % Sampling frequency (samples / second)
t = (0:Nt-1)/Fs; % Time array
x = sin(t/10); % Low-frequency signal
x = x + 0.25*randn(1,Nt); % add some noise
X = fftshift(fft(x)); % FFT of signal with 0 Hz centered
fr = (-Nt/2 : Nt/2-1)/(Nt/Fs); % Frequency axis
% Filter: squared cosine (edit as desired)
fsl = 10; % Length of filter slope, in samples
filt = zeros(size(X));
filt(Nt/2+1+(-fsl:fsl)) = cos( linspace(-pi/2,pi/2,2*fsl+1) ).^2;
x_filt = real(ifft(ifftshift( filt.*X ))); % Filtered x
figure();
subplot(2,2,1); plot(t,x); ax=axis; title('original signal');
subplot(2,2,4); plot(t,x_filt); axis(ax); title('Low-pass filtered signal');
subplot(2,2,2); plot(fr,abs(X)); ax=axis; title('original amplitude spectrum');
subplot(2,2,3); plot(fr,abs(X).*filt); axis(ax); title('Filtered amplitude spectrum');
I am not sure what exactly you meant when you said
let's suppose -1e13 till 1e13
, but keep in mind that extracting a single fourier component (essentially setting all values of the spectrum to zero, except the one you are interested in) acts as a brick-wall filter, and you will get considerable artefacts if you take the inverse transform. Refer to this topic or this page if you're interested.

FFT analysis for Rotor Unbalance

I am working on balancing an air-spindle. For the unbalance analysis I use an accelerometer (NI device). I have the voltage signal from the accelerometer corresponding to the vibration of spindle at a particular frequency (rpm) saved in an excel file. To analyze the unbalance from this vibration signal I use the "fft" function in Matlab. My data is sampled at a sampling frequency of 100,000 Hz. I am using the same example code given in the fft documentation. In the documentation the fft has peak at the frequency corresponding to the frequency of sine wave signal (50Hz and 120Hz). When I use the same code for getting fft of my sampled data for a rotational frequency of 40Hz (2400rpm), I do not get the peak at 40Hz. Am I doing something wrong?? where should I mention the rotational frequency of my spindle in the fft code. I would like to know the phase and magnitude of vibration signal for my rotational frequency (40Hz). the fft plot looks like this. My code is as follows. Any help is much appreciated.
%For vibration analysis of signal without any trial mass.
filename = '2400RPM.xlsx';
sheet = 1;
xlRange = 'C40:C516039'; % Column C has sampled vibration data
x = xlsread(filename,sheet,xlRange);
T=1/100000;
Fs=1/T;
L = length(x);
t= (0:L-1)*T;
Y = fft(x);
mag1 = abs(Y/L);
mag = mag1(1:L/2+1);
mag(2:end-1) = 2*mag(2:end-1);
ph1 = rad2deg(Y/L);
ph = ph1(1:L/2+1);
ph(2:end-1) = 2*ph(2:end-1);
f=Fs*(0:(L/2))/L;
%PLOTTING RESULTS
%--------------------------------------
subplot(2,2,[1,2])
plot(t,x);
title('Vibration Signal: 2400RPM');
xlabel('Time (seconds)');
ylabel('Amplitude (voltage)');
subplot(2,2,3)
plot(f,mag);
title('Magnituge Plot');
xlabel('Frequency (Hz)');
ylabel('Amplitude');
subplot(2,2,4)
plot(f,ph);
title('Phase Plot');
xlabel('Frequency (Hz)');
ylabel('Phase (degree)');

DFT code on Matlab does not work as intended

I am trying to implement a basic DFT algorithm on Matlab.
I simply use in phase and quadrature components of a sine wave with phase modulation(increasing frequency a.k.a chirp). I do compare my results with fft command of Matlab. My code gives the same results whenever there is no phase modulation(pure sine). Whenever I add chirp modulation, results differ. For example, when I use a chirp with some bandwidth around a carrier, the expected results should be a frequency distribution of chirp bandwidth starting from carrier frequency. However, I get a copy of that result backwards starting from carrier frequency as well. You can use my code below without modifying anything. Figure 5 is my result and figure 6 is the expected result. Carrier is 256 Hz with a 10Hz bandwidth of chirp. You can see the code below. The important part is for loop where I take dft of my signal. Also uou can see my dft result below.
close all;
clear all;
%% signal generation
t = (0:0.0001:1); % 1 second window
f = 256; %freq of input signal in hertz
bw = 10; % bandwidth sweep of signal
phaseInput = 2*pi*t*bw.*t;
signalInput = sin(2*pi*f*t + phaseInput); %input signal
inphase = sin(2*pi*f*t).*cos(phaseInput); %inphase component
quadrature = cos(2*pi*f*t).*sin(phaseInput); %quadrature component
figure
plot(t,signalInput,'b',t,inphase,'g',t,quadrature,'r');
title('Input Signal');
xlabel('Time in seconds');
ylabel('Amplitude');
%% sampling signal previously generated
Fs = 1024; %sampling freq
Ts = (0:1/Fs:1);%sample times for 1 second window
sPhase = 2*pi*Ts*bw.*Ts;
sI = sin(2*pi*f*Ts).*cos(sPhase);
sQ = cos(2*pi*f*Ts).*sin(sPhase);
hold on;
plot(Ts,sI+sQ,'b*',Ts,sI,'g*',Ts,sQ,'r*');
fftSize = Fs; %Using all samples in dft
sampleIdx = (0:1:fftSize-1)';
sampledI = sI(1:fftSize)';
sampledQ = sQ(1:fftSize)';
figure;
plot(sampleIdx,sampledI,sampleIdx,sampledQ);
title('Sampled IQ Components');
%% DFT Calculation
dftI = zeros(fftSize,1);
dftQ = zeros(fftSize,1);
for w = 0:fftSize-1
%exp(-2*pi*w*t) = cos(2*pi*w*t) - i*sin(2*pi*w*t)
cI = cos(2*pi*w*sampleIdx/fftSize); %correlation cos
cQ = -sin(2*pi*w*sampleIdx/fftSize); %correlation sin
dftI(w+1) = sum(sampledI.*cI - sampledQ.*cQ); %
dftQ(w+1) = sum(sampledI.*cQ + sampledQ.*cI);
end;
figure;
plot(Fs*sampleIdx/fftSize,dftI);
title('DFT Inphase');
xlabel('Hertz');
figure
plot(Fs*sampleIdx/fftSize,dftQ);
title('DFT Quadrature');
xlabel('Hertz');
figure;
plot(Fs*sampleIdx/fftSize,sqrt(dftQ.^2+dftI.^2));
%% For comparison
sampledInput = sin(2*pi*f*Ts + sPhase);
Y = fft(sampledInput(1:1024),1024);
Pyy = Y.*conj(Y)/1024;
f = (0:1023);
figure;
plot(f,Pyy)
title('Power spectral density')
xlabel('Frequency (Hz)')
the reason lies in the fact that two different signals will definitely give your two different frequency spectrums. check out the code below, you will find that the input of the dft algorithm you actually gave is sampledI+jsampledQ. as a result, what you are doing here is NOT merely decomposing your original signal into In-phase and quadrature components, instead, you are doing Hilbert transform here -- to change a real signal into a complex one.
cI = cos(2*pi*w*sampleIdx/fftSize); %correlation cos
cQ = -sin(2*pi*w*sampleIdx/fftSize); %correlation sin
dftI(w+1) = sum(sampledI.*cI - sampledQ.*cQ); %
dftQ(w+1) = sum(sampledI.*cQ + sampledQ.*cI);
so the sampledInput for comparison should be sampledInput = sI+1i*sQ;.

Fourier transform and LTI filter and frequency response in Matlab

I'm new to Matlab for LTI signal processing and wondering if anyone can help with something that I'm sure is meant to be basic. I've spent hours and hours researching and obtaining background information and still cannot obtain a clear path to tackle these problems. So far, from scratch, I have generated a signal required and managed to use the fft function to produce the signal's DFT:
function x = fourier_rikki(A,t,O)
Fs = 1000;
t = 0:(1/Fs):1;
A = [0.5,0,0.5];
N = (length(A) - 1)/2;
x = zeros(size(t));
f1 = 85;
O1 = 2*pi*f1;
for k = 1:length(A)
x1 = x + A(k)*exp(1i*O1*t*(k-N-1));
end
f2 = 150;
O2 = 2*pi*f2;
for k = 1:length(A);
x2 = x + A(k)*exp(1i*O2*t*(k-N-1));
end
f3 = 330;
O3 = 2*pi*f3;
for k = 1:length(A);
x3 = x + A(k)*exp(1i*O3*t*(k-N-1));
end
signal = x1 + x2 + x3;
figure(1);
subplot(3,1,1);
plot(t, signal);
title('Signal x(t) in the Time Domain');
xlabel('Time (Seconds)');
ylabel('x(t)');
X = fft(signal); %DFT of the signal
subplot(3,1,2);
plot(t, X);
title('Power Spectrum of Discrete Fourier Transform of x(t)');
xlabel('Time (Seconds)');
ylabel('Power');
f = linspace(0, 1000, length(X)); %?
subplot(3,1,3);
plot(f, abs(X)); %Only want the positive values
title('Spectral Frequency');
xlabel('Frequency (Hz)'); ylabel('Power');
end
At this stage, I'm assuming this is correct for:
"Generate a signal with frequencies 85,150,330Hz using a sampling frequency of 1000Hz - plot 1seconds worth of the signal and its Discrete Fourier Transform."
The next step is to "Find the frequency response of an LTI system that filters out the higher and lower frequencies using the Fourier Transform". I'm stuck trying to create an LTI system that does that! I have to be left with the 150Hz signal, and I'm guessing I perform the filtering on the FFT, perhaps using conv.
My course is not a programming course - we are not assessed on our programming skills and I have minimal Matlab experience - basically we have been left to our own devices to struggle through, so any help would be greatly appreciated! I am sifting through tonnes of different examples and searching Matlab functions using 'help' etc, but since each one is different and does not have a break down of the variables used, explaining why certain parameters/values are chosen etc. it is just adding to the confusion.
Among many (many) others I have looked at:
http://www.ee.columbia.edu/~ronw/adst-spring2010/lectures/matlab/lecture1.html
http://gribblelab.org/scicomp/09_Signals_and_sampling.html section 10.4 especially.
As well as Matlab Geeks examples and Mathworks Matlab function explanations.
I guess the worst that can happen is that nobody answers and I continue burning my eyeballs out until I manage to come up with something :) Thanks in advance.
I found this bandpass filter code as a Mathworks example, which is exactly what needs to be applied to my fft signal, but I don't understand the attenuation values Ast or the amount of ripple Ap.
n = 0:159;
x = cos(pi/8*n)+cos(pi/2*n)+sin(3*pi/4*n);
d = fdesign.bandpass('Fst1,Fp1,Fp2,Fst2,Ast1,Ap,Ast2',1/4,3/8,5/8,6/8,60,1,60);
Hd = design(d,'equiripple');
y = filter(Hd,x);
freq = 0:(2*pi)/length(x):pi;
xdft = fft(x);
ydft = fft(y);
plot(freq,abs(xdft(1:length(x)/2+1)));
hold on;
plot(freq,abs(ydft(1:length(x)/2+1)),'r','linewidth',2);
legend('Original Signal','Bandpass Signal');
Here is something you can use as a reference. I think I got the gist of what you were trying to do. Let me know if you have any questions.
clear all
close all
Fs = 1000;
t = 0:(1/Fs):1;
N = length(t);
% 85, 150, and 330 Hz converted to radian frequency
w1 = 2*pi*85;
w2 = 2*pi*150;
w3 = 2*pi*330;
% amplitudes
a1 = 1;
a2 = 1.5;
a3 = .75;
% construct time-domain signals
x1 = a1*cos(w1*t);
x2 = a2*cos(w2*t);
x3 = a3*cos(w3*t);
% superposition of 85, 150, and 330 Hz component signals
x = x1 + x2 + x3;
figure
plot(t(1:100), x(1:100));
title('unfiltered time-domain signal, amplitude vs. time');
ylabel('amplitude');
xlabel('time (seconds)');
% compute discrete Fourier transform of time-domain signal
X = fft(x);
Xmag = 20*log10(abs(X)); % magnitude spectrum
Xphase = 180*unwrap(angle(X))./pi; % phase spectrum (degrees)
w = 2*pi*(0:N-1)./N; % normalized radian frequency
f = w./(2*pi)*Fs; % radian frequency to Hz
k = 1:N; % bin indices
% plot magnitude spectrum
figure
plot(f, Xmag)
title('frequency-domain signal, magnitude vs. frequency');
xlabel('frequency (Hz)');
ylabel('magnitude (dB)');
% frequency vector of the filter. attenuates undesired frequency components
% and keeps desired components.
H = 1e-3*ones(1, length(k));
H(97:223) = 1;
H((end-223):(end-97)) = 1;
% plot magnitude spectrum of signal and filter
figure
plot(k, Xmag)
hold on
plot(k, 20*log10(H), 'r')
title('frequency-domain signal (blue) and filter (red), magnitude vs. bin index');
xlabel('bin index');
ylabel('magnitude (dB)');
% filtering in frequency domain is just multiplication
Y = X.*H;
% plot magnitude spectrum of filtered signal
figure
plot(f, 20*log10(abs(Y)))
title('filtered frequency-domain signal, magnitude vs. frequency');
xlabel('frequency (Hz)');
ylabel('magnitude (dB)');
% use inverse discrete Fourier transform to obtain the filtered time-domain
% signal. This signal is complex due to imperfect symmetry in the
% frequency-domain, however the imaginary components are nearly zero.
y = ifft(Y);
% plot overlay of filtered signal and desired signal
figure
plot(t(1:100), x(1:100), 'r')
hold on
plot(t(1:100), x2(1:100), 'linewidth', 2)
plot(t(1:100), real(y(1:100)), 'g')
title('input signal (red), desired signal (blue), signal extracted via filtering (green)');
ylabel('amplitude');
xlabel('time (seconds)');
Here is the end result...

how to transform frequency domain into time domain

I had created a 3 three different frequency signal and filter out the signal i don't want. But when i using ifft in matlab, it shows a wrong graph.How to transform my frequency domain spectrum back into my 3 second time domain graph? Below my code is as below:
clc
clear all
Fs = 8192;
T = 1/Fs;
%create tones with different frequency
t=0:T:1;
t2=1:T:2;
t3=2:T:3;
y1 = sin(2*pi*220*t);
y2 = sin(2*pi*300*t2);
y3 = sin(2*pi*440*t3);
at=y1+y2+y3;
figure;
plot(t,y1,t2,y2,t3,y3),title('Tones with noise');
[b,a]=butter(2,[2*290/Fs,2*350/Fs],'stop');
e=filter(b,a,at);
et=(ifft(abs(e)));
figure,
plot(et)
As it is now, et is in the frequency domain, because of the fft. You don't need to fft. just plot(e) and you'll get the time domain filtered waveform. Yo can check the filter performance in the freq. domain by fft though, just
plot(abs(fftshift(fft(fftshift(e)))));
xlim([4000 5000])
Edit:
Your code as it is written on the question has the following bug: at has exactly 1 second of info in it (or 8192 elements). If you plot(at) you'll see the sum of frequencies alright, but they all happen in the same time. This is how to fix it:
clear all
Fs = 8192; % or multiply by 3 if needed
T = 1/Fs;
%create tones with different frequency
t=0:T:3;
y1 = sin(2*pi*220*t).*(t<1);
y2 = sin(2*pi*300*t).*(t<2 & t>=1);
y3 = sin(2*pi*440*t).*(t>=2);
at=y1+y2+y3;
[b,a]=butter(2,[2*290/Fs,2*350/Fs],'stop');
e=filter(b,a,at);
figure,
plot(t,e)
dt=t(2)-t(1);
N=length(at);
df=1/(N*dt); % the frequency resolution (df=1/max_T)
if mod(N,2)==0
f_vector= df*((1:N)-1-N/2); % frequency vector for EVEN length vectors: f =[-f_max,-f_max+df,...,0,...,f_max-df]
else
f_vector= df*((1:N)-0.5-N/2); % frequency vector for ODD length vectors f =[-f_max,-f_max+fw,...,0,...,f_max]
end
freq_vec=f_vector;
fft_vec=fftshift(fft(e));
plot(freq_vec,abs(fft_vec))
xlim([0 1000])