How to find the frequency and amplitude of an oscillating signal?

조회 수: 77 (최근 30일)
Rohan Kokate
Rohan Kokate 2023년 11월 29일
댓글: Star Strider 2023년 12월 1일
Hello,
I have a pressure signal which oscillates at a certain frequency and amplitude at steady-state. Is there a way to use the raw data (pressure and time) to find the frequency and amplitude of the oscillations. The raw data does have a little noise. I have attached an example image of the signal that I have along with an excel sheet which has the raw data. I believe FFT is the way to go but I have zero experience/background in using it.
Any help would be greatly appreciated.
Thank you in advance!

채택된 답변

Star Strider
Star Strider 2023년 11월 29일
편집: Star Strider 2023년 11월 29일
One approach —
T1 = readtable('book1.xlsx', 'VariableNamingRule','preserve')
T1 = 50×2 table
Time [s] P5 [psia] ________ _________ 3094.8 118.37 3097.1 116.52 3099.7 118.26 3102.2 120.05 3104.6 119.49 3107.1 116.54 3109.6 117.33 3112.1 119.37 3114.5 120.24 3117 117.57 3119.4 116.61 3121.9 118.29 3124.4 120.15 3126.8 119.49 3129.4 116.46 3131.8 117.45
VN = T1.Properties.VariableNames;
t = T1{:,1};
s = T1{:,2};
figure
plot(t,s)
grid
checkTime = [mean(diff(t)) std(diff(t))] % Check Sampling Time Variation
checkTime = 1×2
2.4724 0.0631
Fs = 1/mean(diff(t)); % Mean Sampling Frequency
[sr,tr] = resample(s,t,Fs); % Resample To Constant Sampling Intervals (Required For Signal Ptocessing)
Fn = Fs/2; % Nyquist Frequency
L = size(T1,1); % Signal LEngth
NFFT = 2^nextpow2(L); % Use This Value To Make The 'fft' More Efficient
FTs = fft((s-mean(s)).*hann(L), NFFT)/L; % Discrete Windowed Fourier Transform
Fv = linspace(0, 1, NFFT/2+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
[pks,locs,width] = findpeaks(abs(FTs(Iv))*2, 'MinPEakProminence',0.25, 'WidthReference','halfheight');
Peak_Frequency = Fv(locs)
Peak_Frequency = 0.0885
Peak_Magnitude = pks
Peak_Magnitude = 0.8425
Peak_Width = width*Fv(2)
Peak_Width = 0.0168
idx = find(diff(sign(abs(FTs(Iv))*2-(pks/2))));
for k = 1:numel(idx)
idxrng = max(1,idx(k)-1) : min(idx(k)+1,Iv(end));
hpf(k) = interp1(abs(FTs(idxrng))*2, Fv(idxrng), pks/2);
end
figure
plot(Fv, abs(FTs(Iv))*2)
hold on
plot(hpf, [1 1]*pks/2, '-k')
hold off
grid
xlabel('Frequency (Hz)')
ylabel('Magnitude')
title('Fourier Transform')
text(Peak_Frequency, Peak_Magnitude, sprintf('\\leftarrow Frequency = %.3f Hz\n Magnitude = %.3f',Peak_Frequency, Peak_Magnitude), 'Horiz','left')
text(hpf(2), pks/2, sprintf('\\leftarrow FWHM = %.3f Hz', Peak_Width))
EDIT — (29 Nov 2023 at 18:28)
Added text calls to Forueir Transform plot.
.
  댓글 수: 8
Rohan Kokate
Rohan Kokate 2023년 12월 1일
Oh, I get it now. I will try to read a bit more to get more clarity. Thanks for all the help!
Star Strider
Star Strider 2023년 12월 1일
As always, my pleasure!
Essentially, the more frequencies that exist in a signal, the more the total energy is distributed among them.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Paul
Paul 2023년 11월 30일
편집: Paul 2023년 11월 30일
Hi Rohan,
For this signal, the output of fft without windowing gives a very good estimate of the amplitude and frequency of the signal.
Read and plot the data.
T = readtable('book1.xlsx', 'VariableNamingRule','preserve');
t = T{:,1};
p5 = T{:,2};
figure
plot(t,p5),grid
Get a rough estimate of its amplitude and frequency
[highpeaks,locs] = findpeaks(p5);
lowpeaks = -findpeaks(-p5);
amplitudeEstimate = (mean(highpeaks)-mean(lowpeaks))/2;
frequencyEstimate = 1./mean(diff(t(locs)));
The data is not equally spaced, but we'll assume it is for a first cut and use the mean dt to define a sampling frequency. Not necessarily a recommended approach, but may be good enough for a first cut because the deviation is not too large.
plot(1./diff(t))
Fs = 1/mean(diff(t));
Compute the FFT
P5 = fft(p5-mean(p5))/numel(p5);
f = (0:numel(P5)-1)/numel(P5)*Fs;
If you want to use a window, the scaling has to be modified
whann = hann(numel(p5));
P5hann = fft((p5-mean(p5)).*whann)/sum(whann);
Plot the results
plot(f,2*abs(P5),'-o',f,2*abs(P5hann),'-o'),grid
yline(amplitudeEstimate,'m'),xline(frequencyEstimate,'m')
xlim([0 Fs/2]),xlabel('Frequency (Hz)'),ylabel('Amplitude')
legend('Raw','Windowed')
You can probably sharpen this analysis by being more careful in dealing with the non-equally spaced samples, and maybe zero padding the fft's as well.

카테고리

Help CenterFile Exchange에서 Measurements and Feature Extraction에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by