Подтвердить что ты не робот

Определить частоту из данных сигнала в MATLAB

У меня есть данные от датчика, и мне нужно найти его частоту. Похоже, что fft() - это путь, но MATLAB docs только показывает, как получить график частот, я не знаю, что делать дальше.

Вот как выглядят мои данные:

enter image description here

4b9b3361

Ответ 1

Один из способов - действительно использовать fft. Поскольку fft дает вам частотное представление сигнала, вы хотите найти максимум, и поскольку fft является сложным сигналом, сначала вы должны принять абсолютное значение. Индекс будет соответствовать нормированной частоте с максимальной энергией. Наконец, если ваш сигнал имеет смещение, как в случае с тем, который вы показываете, вы хотите избавиться от этого смещения перед тем, как принять fft, чтобы вы не получили max в начале координат, представляющем компонент DC.

Все, что я описал, помещено в одну строку:

[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));

где indexMax - это индекс, в котором можно найти максимальное значение fft.

Примечание. Чтобы получить от indexMax фактическую интересующую вас частоту, вам нужно знать длину L fft (такую ​​же, как длина вашего сигнала), и частоту дискретизации Fs. Тогда частота сигнала будет:

frequency = indexMax * Fs / L;

В качестве альтернативы, быстрее и достаточно хорошо работать в зависимости от вашего сигнала, возьмите автокорреляцию своего сигнала:

autocorrelation = xcorr(signal);

и найдите первый максимум, следующий после центральной точки автокорреляции. (Автокорреляция будет симметричной с ее максимумом в середине.) Найдя этот максимум, вы найдете первое место, где сдвинутый сигнал выглядит более или менее похожим на себя. То есть вы находите период своего сигнала. Так как сигнал, сдвинутый на кратный его периоду, всегда будет выглядеть как сам, вам нужно убедиться, что максимум, который вы находите, действительно соответствует периоду сигнала, а не одному из его кратных.

Из-за шума в вашем сигнале абсолютный максимум может очень хорошо произойти в кратность вашему периоду, а не самому периоду. Поэтому для учета этого шума вы должны принять абсолютный максимум автокорреляции (автокорреляция (длина (автокорреляция)/2 + 1), а затем найти, где автокорреляция больше, чем, скажем, 95% от этого максимального значения для первого 95%, 99% или какое-то другое число будет зависеть от того, сколько шума искажает ваш сигнал.

ОБНОВЛЕНИЕ: Я понимаю, что я предполагал, что вы подразумеваете под "частотой" вашего сигнала шаг или базовую гармонику или частоту с наибольшей энергией, однако вы хотите посмотреть на нее. Если по частоте вы имели в виду частотное представление вашего сигнала, то в первом приближении вы просто хотите построить абс БПФ, чтобы получить представление о том, где находится энергия:

plot(abs(fft));

Если вы хотите понять, почему существует абс, или какая соответствующая информация вы теряете, не представляя фазу fft, вы можете прочитать немного больше о преобразовании DFT, чтобы точно понимать, что вы получаете.

Ответ 2

Я думаю, что это должно быть

 (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