How to find the exact frequencies from a spectrogram plot?

6 views (last 30 days)
I have a spectrogram plot generated from oscilloscope data. I want to know what the exact frequency is at Maximum intensity. How do I got about extracting this type of information from the spectrogram and accompanying [S,F,T] data.
clear;
close all;
clc;
%% Initialization
struct = readmatrix('filename.csv');
shift = struct(6,2); %Horizontal Offset [s]
samp_interval = struct(2,2); %Sampling interval [s]
Fs = 1/samp_interval; %Sampling frequency [Hz]
total_t = struct(1,2)*samp_interval; %Total sampling time [s]
time = (struct(:,4)-shift)*1e9; %time [ns]
voltage = struct(:,5)*1000; %raw voltage data [V]
%% Highpass filter
high = 3e11;
voltage = highpass(voltage,high,Fs);
%% Spectrogram Setup
nfft = 2^nextpow2(length(voltage)); %FFT size (reduces time domain aliasing)
%Number of frequency samples
nspec = 1024*30; %Number of windows
wind = blackman(nspec); %Reduces side lobes that hide weaker signals
noverlap = nspec/2; %Overlap of windows
%% FFT Computation
freq_fft = (0:(nfft/2-1))*(Fs/nfft);
volt_f = fft(voltage,nfft);
%% Spectrogram
[s,f,t] = spectrogram(voltage ,wind,noverlap,nspec,Fs,'yaxis');
%% Plots
figure(1)
spectrogram(voltage,wind,noverlap,nspec,Fs,'yaxis')
ylim([0 15]); yticks(0:1:15); colormap('jet')
% figure(2)
% plot(freq_fft,abs(volt_f(1:nfft/2)))
% title('Single-Sided Amplitude Spectrum of V(t)')
% xlabel('Frequency (Hz)')
% ylabel('|V(f)|')
% axis tight

Accepted Answer

Mathieu NOE
Mathieu NOE on 20 Apr 2023
hello
a FFT based method will always give you the result with a frequency resolution that depends on the fft length and sampling rate Fs
df = Fs/nfft , so you cannot get better than this accuracy with a fft approach (yes you could zero padd to increase the resolution but that has also its limits
better do this :
as your signal seems to be a simple tone (sinewave) , why not simply measure the time diffrence between consecutive zero crossing points ? (NB here the x values are obtained by linear interpolation for maximal precision).
also your amplitude does not seem to vary with time , so what do you mean by saying I want to plot the intensity vs time if possible.
would be nice to provide your data
so far , try this
% dummy data
n = 300;
x = 22*(0:n-1)/n;
y = sin(x+0.1*x.^2);
threshold = 0; %
t0_pos1 = find_zc(x,y,threshold);
period = diff(t0_pos1); % delta time of crossing points
freq = 1./period; % signal frequency
figure(1)
subplot(2,1,1),plot(x,y,'b.-',t0_pos1,threshold*ones(size(t0_pos1)),'*r','linewidth',2,'markersize',12);grid on
xlim([x(1) x(end)]);
title('Signal plot');
legend('signal','crossing points');
xlabel('time (s)')
ylabel('Amplitude')
subplot(2,1,2),plot(t0_pos1(2:end),freq,'b.-','linewidth',2,'markersize',12);grid on
xlim([x(1) x(end)]);
title('Signal rate (frequency)');
xlabel('time (s)')
ylabel('Hz')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Zx] = find_zc(x,y,threshold)
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
Zx = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end

More Answers (0)

Community Treasure Hunt

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

Start Hunting!