Определить частоту по данным сигнала в MATLAB
У меня есть данные от датчика, и мне нужно найти частоту его. Похоже на fft()
кажется, это путь, но документы MATLAB показывают только, как получить график частот, я не знаю, что делать оттуда.
вот как выглядят мои данные:
2 ответов
один из способов пойти действительно использовать БПФ. Поскольку БПФ дает вам частотное представление сигнала, вы хотите искать максимум, и поскольку БПФ является сложным сигналом, вы захотите сначала принять абсолютное значение. Индекс будет соответствовать нормированной частоте с максимальной энергией. Наконец, если ваш сигнал имеет смещение, как в случае с тем, который вы показываете, вы хотите избавиться от этого смещения перед принятием fft, чтобы вы не получили max в начале координат представление компонента DC.
все, что я описал в одной строке, будет:
[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));
где indexMax-это индекс, в котором можно найти максимальное значение fft.
Примечание: чтобы получить от indexMax до фактической частоты интереса, вам нужно будет знать длину L БПФ (такую же, как длина вашего сигнала) и частоту дискретизации Fs. Частота сигнала будет:
frequency = indexMax * Fs / L;
альтернативно, быстрее и работает довольно хорошо тоже в зависимости от сигнала взять автокорреляция сигнала:
autocorrelation = xcorr(signal);
и найти первый максимум, происходящий после центральной точки автокорреляции. (Автокорреляция будет симметричной с максимумом посередине.) Найдя этот максимум, вы найдете первое место, где смещенный сигнал выглядит более или менее похожим на себя. Т. е. вы находите период вашего сигнала. Поскольку сигнал, сдвинутый на кратное его периоду, всегда будет выглядеть как сам, вы нужно убедиться, что найденный вами максимум действительно соответствует периоду сигнала, а не одному из его кратных.
из-за шума в вашем сигнале абсолютный максимум может очень хорошо произойти в несколько вашего периода вместо самого периода. Поэтому для учета этого шума вы возьмете абсолютный максимум автокорреляции (автокорреляция (длина (автокорреляция)/2+1) , а затем найдете, где автокорреляция больше, чем, скажем, 95% от этого максимального значения впервые во второй половине сигнала. 95%, 99% или какое-либо другое число будет зависеть от того, сколько шума искажает ваш сигнал.
UPDATE: я понимаю, что я предположил, что вы подразумеваете под "частотой" вашего сигнала высоту тона или базовую гармонику или частоту с наибольшей энергией, однако вы хотите посмотреть на это. Если под частотой вы подразумевали частотное представление вашего сигнала, то в первом приближении вы просто хотите построить abs БПФ, чтобы получить представление о том, где энергия:
plot(abs(fft));
если вы хотите понять, почему существует abs, или какую соответствующую информацию вы теряете, не представляя фазу БПФ, вы можете прочитать немного больше о преобразовании DFT, чтобы точно понять, что вы получаете.
Я думаю, что это должно быть
(indexMax-1) * Fs / L
первый элемент abs(fft (x)) - это постоянный ток (DC), или смещение, или среднее значение сигнала, или X0. Отсчитываем от второго элемента (X1). Пожалуйста, дайте мне знать, если я ошибаюсь. Спасибо.
clear all
clc
close all
Fs = 1;
T = 11 % Note this T is deliberately chosen , so that we have about 1.7 cycle of cosine singal
t = 0:Fs:T; % T seconds
L = length(t); % L is the length of sample sequence
bias = 4
signal = sin(t) + bias;
[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));
frequency_method1 = (indexMax-1) * Fs / (L-1);
frequency_method2 = (indexMax-1) * Fs / L;
number_of_cycles_method1 = frequency_method1*T
number_of_cycles_method2 = frequency_method2*T
subplot(2,1,1)
plot(t,signal,'-or') ; grid on;
legend('about 1.7 cycles of cosine signal')
subplot(2,1,2)
plot(abs(fft(signal-mean(signal))),'-xb'); grid on
legend('abs of fft')
number_of_cycles_method1 =
2
number_of_cycles_method2 =
1.8333