Apply a time window to my fft

64 vues (au cours des 30 derniers jours)
shawn finley
shawn finley le 16 Août 2021
Commenté : Star Strider le 18 Août 2021
I have an excel file (to big to attach) that I am reading a signal from it is in time and volts. I want to apply and time window to my fft to make it increment along the signal and give me the frequencies. Now with my current MATLAB set up I do NOT have signal toolbox and other such tools, therefore I need to construct a for-loop to do my iterations a window if you will. I need help applying the for-loop. I have attached my current code, I believe that if this is done right I will end up with and array of frequencies and then an array of velocities that I can plot.
I believe that the for-loop should go before the fft and end before the %plot frequency.

Réponse acceptée

Star Strider
Star Strider le 16 Août 2021
My version of MATLAB cannot run images of code.
Perhaps something like this would work:
t = linspace(0, 100, 1000);
s = sin(21*pi*5*t);
Ts = t(2)-t(1);
Fs = 1/Ts;
Fn = Fs/2;
seglen = 100;
Fv = linspace(0, 1, fix(seglen/2)+1)*Fs;
Iv = 1:numel(Fv);
FTs = zeros(fix(numel(t)/seglen), seglen);
for k = 1:10
idx = k : k+seglen-1;
FTs(k,:) = fft(s(idx))/seglen;
seg(k) = k;
end
figure
surf(Fv, seg, abs(FTs(:,Iv))*2)
grid on
xlabel('Frequency')
ylabel('Time (segment)')
title('STFT Matrix')
figure
surf(Fv, seg, abs(FTs(:,Iv))*2, 'EdgeColor','none')
grid on
xlabel('Frequency')
ylabel('Time (segment)')
view(90,90)
title('Spectrogram')
axis('tight')
Experiment to get appropriate results with your signals.
.
  16 commentaires
shawn finley
shawn finley le 18 Août 2021
Thank you fot the clairifacation.
If i wanted to calculate the PSD of the fft I would want to do that inside the loop correct?
Star Strider
Star Strider le 18 Août 2021
As always, my pleasure.
If i wanted to calculate the PSD of the fft I would want to do that inside the loop correct?
Yes. This code just calculates the Fourier transform, so one approach to calculating the PSD would be to simply square it (using element-wise operations, so .^), or express it as:
PSD = (abs(FTs(Iv,:))*2).^2
or:
PSD = 20*log10(abs(FTs(Iv,:))*2)
That would work with my existing code.
A more typical approach is the pwelch calculation, so one option is adapting my code to work with it:
uz = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/714127/U296_10000.zip')
uz = 1×1 cell array
{'U296_10000.xlsx'}
T1 = readtable(uz{1}, 'VariableNamingRule','preserve')
T1 = 10001×3 table
TIME CH4 (PDV) CH1 (Det) ___________ __________ _________ -0.0002 -0.003 0.03 -0.0002 -0.0026016 0.0099219 -0.0002 -0.0026 0.01 -0.0002 -0.0026 0.03 -0.0002 -0.0030016 0.0099219 -0.0002 -0.0034016 0.0099219 -0.0002 -0.0034 0.03 -0.0002 -0.0026016 -0.010078 -0.0002 -0.0022 -0.01 -0.0002 -0.0026016 0.0099219 -0.0002 -0.0022016 -0.010078 -0.0002 -0.0026 -0.01 -0.0002 -0.0030016 -0.010078 -0.00019999 -0.0026016 -0.010078 -0.00019999 -0.003 0.01 -0.00019999 -0.0026 -0.01
% t = linspace(0, 10, 250).'; % Transpose To Column Vector
% s = sin(2*pi*5*t);
t = T1.TIME;
s = T1.('CH4 (PDV)');
Ts = mean(diff(t))
Ts = 4.0000e-10
% Tsd = std(diff(t))
Fs = 1/Ts
Fs = 2.5000e+09
% Ts = t(2)-t(1);
% Fs = 1/Ts;
Fn = Fs/2;
seglen = 50; % Shorten 'seglen' to 50 (Changed)
nseg = fix(numel(t)/seglen);
nfft = 1024; % FFT Length (Added)
Fv = linspace(0, 1, fix(nfft/2)+1)*Fn;
Iv = 1:numel(Fv);
% FTs = zeros(nfft, nseg);
FTs = zeros(2^nextpow2(seglen)*2+1, nseg); % Change To Use 'pwelch'
f = linspace(0, 1, size(FTs,1))*Fn; % Apparently, 'pwelch' Cannot Work With 'Fs' As Defined Here
for k = 1:nseg
idx = k : k+seglen-1;
sv = s(idx) - mean(s(idx)); % Added
% FTs(:,k) = fft(s(idx))/seglen;
% FTs(:,k) = fft(sv,nfft)/seglen; % Added - Changed
FTs(:,k) = pwelch(sv); % Call 'pwelch'
seg(k) = median(t(idx));
end
figure
% hsp = surfc(seg, Fv, abs(FTs(Iv,:))*2);
hsp = surfc(seg, f, FTs);
colormap(turbo)
hsp(1).EdgeColor = 'none';
grid on
xlabel('Time (segment)')
ylabel('Frequency')
title('STFT Matrix')
figure
surf(seg, f, FTs, 'EdgeColor','none')
colormap(turbo)
grid on
xlabel('Time (segment)')
ylabel('Frequency')
view(0,90)
title('Spectrogram')
axis('tight')
Ax = gca;
Ax.TickDir = 'both';
Ax.XMinorTick = 'on';
Ax.YMinorTick = 'on';
Ax.XTickLabelRotation = 45;
figure
hcf = contourf(seg, f, FTs);
colormap(turbo)
grid on
xlabel('Time (segment)')
ylabel('Frequency')
title(' Contour Plot Of STFT Matrix')
Ax = gca;
Ax.TickDir = 'both';
Ax.XMinorTick = 'on';
Ax.YMinorTick = 'on';
Ax.XTickLabelRotation = 45;
This simply adapts pwelch to my existing code, although changing any of the existing parameters may break it.. A more robust implementation is in the spectrogram and similar functions.
.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Time-Frequency Analysis dans Help Center et File Exchange

Produits


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by