Hi everyone, this code performs the FFT of a signal in real time. When reproducing a sinusoidal signal at 440 Hz, the code does not show the correct frequency in the graph

1 view (last 30 days)
%................................................................
%Script Matlab usato per acquisire un segnale dalla porta seriale
% ed eseguire una FFT del segnale ricevuto
%................................................................
s = serialport('COM4', 9600); %Inizializzazione porta seriale
configureTerminator(s, "LF"); % terminatore di riga(ogniqualvolta viene letto il carattere LF viene considerata terminata la stringa)
%....................................................
%Genero un grafico che mi facilita la visualizzazione
% dell'acquisizione dei punti grezzi del segnale
%....................................................
fig = figure; %creo la figura
plt = animatedline; %plot dati grezzi
plt.LineWidth = 3; %impostazione grafica
%Creo un pulsante di START per avviare la comunicazione
c = uicontrol;
c.String = "START";
c.Callback=@(src,event)start_reading(s);
x = 0:1023; %Definisco un array di 1024 valori
for j= 1:1024 % di tutti valori nulli
x(j)=0;
end
i=1; %Inizializzo contatore
fine=0; %Definisco un parametro per la fine acquisizione
y = 0; %Variabile utilizzata per implementare il grafico animato in tempo reale
while (fine~=1)
y = y+1; %Leggo i dati dalla porta seriale e li visualizzo
tmp = str2double(readline(s)); % in tempo reale, solo per avere la certezza che
addpoints(plt, y ,tmp); % la lettura dei dati sia effettivamente partita
%(questa funzione può benissimo essere rimossa)
tmp = str2double(readline(s)); %creo il segnale x(t) andando a salvare nell'array
x(i)=tmp; %volta per volta il valore letto sulla porta seriale
i=i+1;
if i>1024
fine=1; %il processo di lettura si arresta acquisiti tutti i 1024 valori
write(s, 'f', "uint8"); %Si scrive sulla COM il carattere 'f' pere interrompere l'acquisizione
% del microcontrollore
end
end
clear s; %chiusura della porta COM
%.................................
%definizione parametri del segnale
%.................................
Fs = 1205; % Frequenza di campionamento
T = 1/Fs; % Periodo di campionamento
L = 1024; % lunghezza del segnale
t = (0:L-1)*T; % vettore del tempo
X=x(~isnan(x)); %elimina tutti i valore di errore generati nella lettura della porta COM
new_length=length(X); %se si sono generati errori nela fase di lettura dati la lunghezza del vettore risulta minore del dovuto
different_lenght=1024-new_length;
z=zeros(different_lenght); %si genera un vettore di zeri lungo pari al difetto di valori persi durante la lettura dei dati
x1=[X,z];
%.........................................
%grafico del segnale nel dominio del tempo
%.........................................
figure
subplot(2,1,1)
plot(t(1:1024),x1(1:1024))
title('dominio del tempo')
%...............................................
%grafico del segnale nel dominio della frequenza
%...............................................
n = 2^nextpow2(L);
dim = 2;
Y = fft(x1,n,dim); %eseguo la FFT del segnale nel tempo
P2 = abs(Y/L);
P1 = P2(:,1:n/2+1);
P1(:,2:end-1) = 2*P1(:,2:end-1);
subplot(2,1,2)
plot(0:(Fs/n):(Fs/2-Fs/n),P1(1:n/2))
axis([50 700 0 1000])
title('dominio della frequenza')
%.................................
%.................................
function start_reading(s) %funzione start reading
write(s, 't', "uint8"); % per avviare l'acquisizione del microcontrollore e l'invio dei dati sulla COM
%basta inviare il carattere "c" sulla COM
end

Answers (1)

Ashutosh Singh Baghel
Ashutosh Singh Baghel on 18 Oct 2021
Hi Andrea,
I beleive you wish to have a plot of reproduced sinusoidal signal of frequency 440Hz. Please try to change the axis coordinates as
axis([50 700 0 1]);
The current axis is providing a very diminished version of plot to veiw.
Also, feel free to see this example code for plotting a sinusoidal signal of 440Hz.
fs = 1205; %Sampling frequency
fm = 440; %Sinusoidal Signal Frequency
symbol_duration = 1;
t = linspace(0,symbol_duration,fs);
x = sin(2*pi*fm*t);
L = 1024; %Signal Length
X = abs(fft(x,fs)/L);
f=(1:fs);
plot(f(1:1024),X(1:1024));
axis([50 700 0 1])
Please refer to the following documentation link for 'fft' and 'axis'.

Tags

Community Treasure Hunt

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

Start Hunting!