Apply a time window to my fft

35 Ansichten (letzte 30 Tage)
shawn finley
shawn finley am 16 Aug. 2021
Kommentiert: Star Strider am 18 Aug. 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.

Akzeptierte Antwort

Star Strider
Star Strider am 16 Aug. 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 Kommentare
shawn finley
shawn finley am 18 Aug. 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 am 18 Aug. 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.
.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Fourier Analysis and Filtering finden Sie in Help Center und File Exchange

Produkte


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by