Plotting the frequency spectrum of square wave generated with an osciloscope

28 views (last 30 days)
To summarize this, I need to obtain the frequency spectrum of a signal that has a square wave form with a 500 hz frequency and 5.020 peak to peak voltage amplitude (this means that I would have an amplitude of 5.020 / 2). These parameters come from the osciloscope imput parameters that were selected to generated this square wave. I don't know how to make the frequency spectrum plot look better. Maybe this could be solved by selecting a better sampling frequency, I am currently working without one, as you can see in line 2 of my code.
this is my code:
n = 20; %number of times I want the cycle to repeat in the plot.
t = 0:1e-6:(n*0.002); %time vector
f = 500; %Hz
A = 5.020; %volts
x = (A/2)*square(2*pi*t*f); %square wave function
nfft = 1024; %length of the FTT
X = fft(x,nfft) ;
X = X(1:nfft/2); %considering the symmetry
figure(1);
plot(t,x);
title('señal cuadrada periódica')
xlabel('Ampligtud')
ylabel('tiempo(s)')
mx = abs(X); %getting rid of the imaginary part
fv = (0:nfft/2-1)*((1*(n*0.002)^(-1))/nfft); %frequency vector
figure(2)
plot(fv,mx);
title('espectro de frecuencia')
xlabel('intensidad')
ylabel('Frecuencia')

Accepted Answer

Mathieu NOE
Mathieu NOE on 5 Sep 2022
Hello Maria
when I saw this line
X = fft(x,nfft) ;
I thought that your intention was to do fft with averaging multiple chuncks of nfft (1024) long buffers of the entire signal
but unfortunately this code does only takes the first nfft points of the data and do a single fft computation on it
Doc says :
% FFT(X,N) is the N-point FFT, padded with zeros if X has less
% than N points and truncated if it has more.
If you want to do linear averaging (and with overlap as in my code ) here my little demo below. Also note I used a hanning window.
The sampling frequency depends of how high in the frequency range you want to go.. you can easily change that by yourself.
I select Fs and nfft so that the frequency vector has bins matching the signal frequency (500 Hz) and harmonics :
df = Fs / nffft = 5e4 / 1000 = 50 Hz = 1/10 of 500 Hz (signal)
Also the spectrum is displayed in dB scale by defalut (as I do alot of noise and vibration analysis) but you can easily remove that portion of the code and display in linear range instead
hope it helps
Code :
n = 20; %number of times I want the cycle to repeat in the plot.
Fs = 5e4;
dt = 1/Fs;
f = 500; %Hz
t = (0:dt:(n/f))'; %time vector
A = 5.020; %volts
x = (A/2)*square(2*pi*t*f); %square wave function
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NFFT = 1000; %
OVERLAP = 0.75; % 75 % of nfft = overlap length
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 1 : time domain plot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure(1),
plot(t,x);grid on
title(['Time plot / Fs = ' num2str(Fs) ' Hz ']);
xlabel('Time (s)');ylabel('Amplitude');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 2 : averaged FFT spectrum
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[freq, spectrum_raw] = myfft_peak(x,Fs,NFFT,OVERLAP);
figure(2),plot(freq,20*log10(spectrum_raw));grid on
df = freq(2)-freq(1); % frequency resolution
title(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(df,3) ' Hz ']);
xlabel('Frequency (Hz)');ylabel('Amplitude (dB)');
function [freq_vector,fft_spectrum] = myfft_peak(signal, Fs, nfft, Overlap)
% FFT peak spectrum of signal (example sinus amplitude 1 = 0 dB after fft).
% Linear averaging
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer percentage of overlap % (between 0 and 0.95)
[samples,channels] = size(signal);
% fill signal with zeros if its length is lower than nfft
if samples<nfft
s_tmp = zeros(nfft,channels);
s_tmp((1:samples),:) = signal;
signal = s_tmp;
samples = nfft;
end
% window : hanning
window = hanning(nfft);
window = window(:);
% compute fft with overlap
offset = fix((1-Overlap)*nfft);
spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_spectrum = 0;
for i=1:spectnum
start = (i-1)*offset;
sw = signal((1+start):(start+nfft),:).*(window*ones(1,channels));
fft_spectrum = fft_spectrum + (abs(fft(sw))*4/nfft); % X=fft(x.*hanning(N))*4/N; % hanning only
end
fft_spectrum = fft_spectrum/spectnum; % to do linear averaging scaling
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_spectrum = fft_spectrum(select,:);
freq_vector = (select - 1)*Fs/nfft;
end

More Answers (0)

Community Treasure Hunt

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

Start Hunting!