Sunday, October 13, 2019

Discrete Signals And Systems with MATLAB GUI

Discrete Signals And Systems with MATLAB GUI


Here, you will build a desktop application (UI, user interface) to simulate how signals and discrete systems are built and how fast fourier transform is applied on those discrete signals. A number of discrete signals are used as test signals are impulse, step, real exponential, sinusoidal, random, square, angled triangle, equilateral triangle, and trapezoidal signals.


Follow these steps below:


1. Type this command on MATLAB prompt:


guide

The GUIDE Quick Start dialog box will show up, as shown in figure below:




2. Select the Blank GUI (Default) template, and then click OK:



3. Drag four axes, thirteen panels, nine push buttons, twenty edit texts on UI form. All Tag properties that needed in Matlab code are set as shown in the figure below. 



4. Set the String property of popupmenusignal1 component as shown below:


4. Set the String property of popupmenusignal2 component as shown below:



6. Save UI form as discrete_signals.fig. 
7. Right-click on pbDraw1 and choose View Callbacks and then choose Callback. 


8. Define pbDraw1_Callback() function below to reads signals parameters and displays chosen signal in axes1 component:


% --- Executes on button press in pbDraw1.
function pbDraw1_Callback(hObject, eventdata, handles)
% hObject    handle to pbDraw1 (see GCBO)
% eventdata  reserved - to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global n0; 
global n1;
global x;

% Reads n01, n11, and n21
n0 = str2num(get(handles.n01,'String'));
n1 = str2num(get(handles.n11,'String'));
n2 = str2num(get(handles.n21,'String'));
eksp = str2num(get(handles.coef1,'String'));

% Reads parameters for sinusoidal
A = str2num(get(handles.A1,'String'));
Frek = str2num(get(handles.Freq1,'String'));
Fase = str2num(get(handles.Phase1,'String'));
Fs = str2num(get(handles.Fs1,'String'));

% Reads parameters for square and triangle signals
width = str2num(get(handles.width1, 'String'));

% Choose option from popup menu popupmenusignal1
switch get(handles.popupmenusignal1,'Value')  
    case 1
       n = [n1:n2]; x = [(n-n0) == 0];
       
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Impulse Signal');

    case 2
       n = [n1:n2]; x = [(n-n0) >= 0];
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Step Signal');
       
    case 3
       n = [n1:n2]; x = [(n-n0) >= 0].*[(eksp).^(n-n0)];
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Real Exponential Signal');
       
    case 4
       n = [n1:n2]; x = [(n-n0) >= 0].*[A*sin(2*pi*(Frek)*((n-n0)/Fs)+Fase)];
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Sinusoidal Signal');
       
    case 5
       n = [n1:n2]; x = [(n-n0) >= 0].*(rand(1,(n2-n1+1))-0.5);
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Random Signal');

    case 6
       n = [n1:n2]; x = [(n-n0) >= 0];
       ny = [n1:n2]; xy = [(ny-width-n0-1) >= 0];
       x = x - xy;
       
       % Display discrete signal
       axes(handles.axes1)
       stem(n,x,'linewidth',2,'color','b'); 
       title('Discrete Square Signal');

    case 7
       n = [n1:n2]; x = n.*[n >= 0];
       ny = [n1:n2]; xy = ny.*[(ny-width-1) >= 0];
       x = (x - xy)/width;
       nb = [n1+n0:n2+n0];
       
       % Reads signal range
       set(handles.n11,'string',(n1+n0));
       set(handles.n21,'string',(n2+n0));

       % Display discrete signal
       axes(handles.axes1)
       stem(nb,x,'linewidth',2,'color','b'); 
       title('Discrete Angled Triangle Signal');
 
    case 8
       n = [n1:n2]; x = n.*[n >= 0];
       x2 = [zeros(1,width), x(1:end-width)];
       x1 = -x;
       x1 = [zeros(1,0.5*width), x1(1:end-0.5*width)];
       nb1 = n1+n0; nb2 = n2+n0;
       nb = [nb1:nb2];
       
       % Read signal range
       set(handles.n11,'string',(nb1));
       set(handles.n21,'string',(nb2));

       % Returns discrete equilateral triangle signal
       x = (x + 2*x1+x2)/(0.5*width);
       
       % Display discrete signal
       axes(handles.axes1)
       stem(nb,x,'linewidth',2,'color','b'); 
       title('Discrete Equilateral Triangle Signal');
       
    case 9
       n = [n1:n2]; x = n.*[n >= 0];
       x2 = [zeros(1,width), x(1:end-width)];
       x3 = [zeros(1,3*width), x(1:end-3*width)];
       x1 = x;
       x1 = [zeros(1,2*width), x1(1:end-2*width)];
       nb1 = n1+n0; nb2 = n2+n0;
       nb = [nb1:nb2];
       
       % Reads signal range
       set(handles.n11,'string',(nb1));
       set(handles.n21,'string',(nb2));

       % Returns discrete trapezoidal signal
       x = (x - x2 - x1 + x3)/width;
       
       % Display discrete signal
       axes(handles.axes1)
       stem(nb,x,'linewidth',2,'color','b'); 
       title('Discrete Trapezoidal Signal');
end  

9. Run UI, choose one of signals from popupmenusignal1 component, and click Draw buton. The related discrete signal will be displayed in axes1 component:



10. Right-click on pbDraw2 and choose View Callbacks and then choose Callback. Define pbDraw2_Callback() function below to reads signals parameters and displays chosen signal in axes2 component:


% --- Executes on button press in pbDraw2.
function pbDraw2_Callback(hObject, eventdata, handles)
% hObject    handle to pbDraw2 (see GCBO)
% eventdata  reserved - to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global x1;

% Reads n01, n11, and n21
n0 = str2num(get(handles.n02,'String'));
n1 = str2num(get(handles.n12,'String'));
n2 = str2num(get(handles.n22,'String'));
eksp = str2num(get(handles.coef2,'String'));

% Reads sinoisoidal parameters
A = str2num(get(handles.A2,'String'));
Frek = str2num(get(handles.Freq2,'String'));
Fase = str2num(get(handles.Phase2,'String'));
Fs = str2num(get(handles.Fs2,'String'));

% Reads parameters for square, triangle, and trapezoidal signals
width = str2num(get(handles.width2,'String'));

% Choose option from popupmenusignal2
switch get(handles.popupmenusignal2,'Value')  
    case 1
       n = [n1:n2]; x1 = [(n-n0) == 0];
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); title('Discrete Impulse Signal');

    case 2
       n = [n1:n2]; x1 = [(n-n0) >= 0];
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); title('Discrete Step Signal');
       
    case 3
       n = [n1:n2]; x1 = [(n-n0) >= 0].*[(eksp).^(n-n0)];
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); 
       title('Discrete Exponential Signal');
       
    case 4
       n = [n1:n2]; x1 = [(n-n0) >= 0].*[A*sin(2*pi*(Frek)*((n-n0)/Fs)+Fase)];
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); 
       title('Discrete Sinusoidal Signal');
       
    case 5
       n = [n1:n2]; x1 = [(n-n0) >= 0].*(rand(1,(n2-n1+1))-0.5);
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); 
       title('Discrete Random Signal');

    case 6
       n = [n1:n2]; x = [(n-n0) >= 0];
       ny = [n1:n2]; xy = [(ny-width-n0-1) >= 0];
       x1 = x - xy;
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(n,x1,'linewidth',2,'color','r'); 
       title('Discrete Square Signal');

    case 7
       n = [n1:n2]; x = n.*[n >= 0];
       ny = [n1:n2]; xy = ny.*[(ny-width-1) >= 0];
       x1 = (x - xy)/width;
       nb = [n1+n0:n2+n0];
       
       % Reads signal range
       set(handles.n12,'string',(n1+n0));
       set(handles.n22,'string',(n2+n0));

       % Displays discrete signal
       axes(handles.axes2)
       stem(nb,x1,'linewidth',2,'color','r'); 
       title('Discrete Angled Triangle Signal');
 
    case 8
       n = [n1:n2]; x = n.*[n >= 0];
       x2 = [zeros(1,width), x(1:end-width)];
       x3 = -x;
       x3 = [zeros(1,0.5*width), x3(1:end-0.5*width)];
       nb1 = n1+n0; nb2 = n2+n0;
       nb = [nb1:nb2];
       
       % Reads signal range
       set(handles.n12,'string',(nb1));
       set(handles.n22,'string',(nb2));

       % Creates Equilateral Triangle Signal
       x1 = (x + 2*x3+x2)/(0.5*width);
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(nb,x1,'linewidth',2,'color','r'); 
       title('Discrete Equilateral Triangle Signal');
       
    case 9
       n = [n1:n2]; x = n.*[n >= 0];
       x2 = [zeros(1,width), x(1:end-width)];
       x3 = [zeros(1,3*width), x(1:end-3*width)];
       x4 = x;
       x4 = [zeros(1,2*width), x4(1:end-2*width)];
       nb1 = n1+n0; nb2 = n2+n0;
       nb = [nb1:nb2];
       
       % Reads signal range
       set(handles.n12,'string',(nb1));
       set(handles.n22,'string',(nb2));

       % Creates trapezoidal signal
       x1 = (x - x2 - x4 + x3)/width;
       
       % Displays discrete signal
       axes(handles.axes2)
       stem(nb,x1,'linewidth',2,'color','r'); 
       title('Discrete Trapezoidal Signal');
end  

11. Run UI, choose one of signals from popupmenusignal2 component, and click Draw buton. The related discrete signal will be displayed in axes2 component:



12. Right-click on pbAdd and choose View Callbacks and then choose Callback. Define pbAdd_Callback() function below which adds two signals and display the result and its FFT in axes3 and axes4 components:


% --- Executes on button press in pbAdd.
function pbAdd_Callback(hObject, eventdata, handles)
% hObject    handle to pbAdd (see GCBO)
% eventdata  reserved – to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global x;
global x1;

% Reads n11 and n21 for discrete signal 1
n1 = str2num(get(handles.n11,'String'));
n2 = str2num(get(handles.n21,'String'));

% Reads n12 and n22 for discrete signal 2
n12 = str2num(get(handles.n12,'String'));
n22 = str2num(get(handles.n22,'String'));

% Duration     
n = min(min(n1),min(n12)):max(max(n2),max(n22)); 

% Initialization
y1 = zeros(1,length(n)); y2 = y1; 

% Adding two signals
y1(find((n>=min(n1))&(n<=max(n2))==1))=x; 
y2(find((n>=min(n12))&(n<=max(n22))==1))=x1;
y = y1+y2; 

% Clears axes3
cla(handles.axes3,'reset');
axes(handles.axes3)
stem(n,y,'linewidth',1.5,'color','c'); title('The result of adding signal 1 and signal 2');

% Reads sampling frequency
Fs = str2num(get(handles.Fs2,'String'));

nfft = 512; % Length of FFT

% Calculates FFT
Y = fft(y,nfft);
Y = Y(1:nfft/2);

% Calculates magnitude of FFT
my = abs(Y);

% Frequency vector
f = (0:nfft/2-1)*Fs/nfft;

axes(handles.axes4); 
plot(f,my,'linewidth',1.5,'color','c'); grid on;
title('FFT on two added signals'); xlabel('Hz');


13. Run UI form and click on Addition button and you will see the result of adding two signals and its FFT:



14. Right-click on pbMul and choose View Callbacks and then choose Callback. Define pbMul_Callback() function below which multiplies two signals and display the result and its FFT in axes3 and axes4 components:


% --- Executes on button press in pbMul.
function pbMul_Callback(hObject, eventdata, handles)
% hObject    handle to pbMul (see GCBO)
% eventdata  reserved - to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global x;
global x1;

% Reads n11 and n21 for discrete signal 1
n1 = str2num(get(handles.n11,'String'));
n2 = str2num(get(handles.n21,'String'));

% Reads n12 and n22 for discrete signal 2
n12 = str2num(get(handles.n12,'String'));
n22 = str2num(get(handles.n22,'String'));

% Duration     
n = min(min(n1),min(n12)):max(max(n2),max(n22)); 

% Initialization
y1 = zeros(1,length(n)); y2 = y1; 

% Multiplying two signals
y1(find((n>=min(n1))&(n<=max(n2))==1))=x; 
y2(find((n>=min(n12))&(n<=max(n22))==1))=x1;
y = y1.*y2; 

% Clears axes3
cla(handles.axes3,'reset');
axes(handles.axes3)
stem(n,y,'linewidth',1.5,'color','c'); 
title('The result of multiplying of signal 1 and signal 2');

% Reads sampling frequency
Fs = str2num(get(handles.Fs2,'String'));

nfft = 512; % Length of FFT

% Calculates FFT
Y = fft(y,nfft);
Y = Y(1:nfft/2);

% Calculates magnitude of FFT
my = abs(Y);

% Frequency vector
f = (0:nfft/2-1)*Fs/nfft;

axes(handles.axes4); 
plot(f,my,'linewidth',1.5,'color','c'); grid on;
title('FFT on the result of multiplication of two signals'); xlabel('Hz');

15. Run UI form and click on Multiplication button and you will see the result of multiplying two signals and its FFT:



16. Right-click on pbSubs and choose View Callbacks and then choose Callback. Define pbSubs_Callback() function below which substract second signal from the first one and display the result and its FFT in axes3 and axes4 components:


% --- Executes on button press in pbSubs.
function pbSubs_Callback(hObject, eventdata, handles)
% hObject    handle to pbSubs (see GCBO)
% eventdata  reserved - to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global x;
global x1;

% Reads n11 and n21 for discrete signal 1
n1 = str2num(get(handles.n11,'String'));
n2 = str2num(get(handles.n21,'String'));

% Reads n12 and n22 for discrete signal 2
n12 = str2num(get(handles.n12,'String'));
n22 = str2num(get(handles.n22,'String'));

% Duration     
n = min(min(n1),min(n12)):max(max(n2),max(n22)); 

% Initialization
y1 = zeros(1,length(n)); y2 = y1; 

% Adding two signals
y1(find((n>=min(n1))&(n<=max(n2))==1))=x; 
y2(find((n>=min(n12))&(n<=max(n22))==1))=x1;
y = y1-y2; 

% Clears axes3
cla(handles.axes3,'reset');
axes(handles.axes3)
stem(n,y,'linewidth',1.5,'color','c'); 
title('The result of substracting signal 2 from signal 1');

% Reads sampling frequency
Fs = str2num(get(handles.Fs2,'String'));

nfft = 512; % Length of FFT

% Calculates FFT
Y = fft(y,nfft);
Y = Y(1:nfft/2);

% Calculates magnitude of FFT
my = abs(Y);

% Frequency vector
f = (0:nfft/2-1)*Fs/nfft;

axes(handles.axes4); 
plot(f,my,'linewidth',1.5,'color','c'); grid on;
title('FFT on substraction operation'); xlabel('Hz');



17. Right-click on pbConv and choose View Callbacks and then choose Callback. Define pbConv_Callback() function below which convolve the two signals and display the result and its FFT in axes3 and axes4 components:


function pbConv_Callback(hObject, eventdata, handles)
% hObject    handle to pbConv (see GCBO)
% eventdata  reserved - to be defined in a2 future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global x;
global x1;

% Reads n11
n11 = str2num(get(handles.n11,'String'));

% Reads n12
n12 = str2num(get(handles.n12,'String'));

% Borders
n_low = n11+n12;
n_high = length(x) + length(x1);
ny=n_low:n_high-(abs(n_low)+2);
length(ny)

% Convolution
y = conv(double(x),double(x1)); 

length(y)
axes(handles.axes3)
stem(ny,y,'linewidth',1,'color','r'); 
title('Result of convolving two signals');

% Reads sampling frequency
Fs = str2num(get(handles.Fs1,'String'));

nfft = 512; % Length of FFT

% Calculates FFT
Y = fft(y,nfft);
Y = Y(1:nfft/2);

% Calculates magnitude of FFT
my = abs(Y);

% Frequency vector
f = (0:nfft/2-1)*Fs/nfft;

axes(handles.axes4); 
plot(f,my,'linewidth',1.5,'color','c'); grid on;
title('FFT on convolution operation'); xlabel('Hz');





No comments: