2013-03-07 17 views

risposta

18

Un modo per andare è infatti quello di utilizzare una FFT. Dato che il fft ti dà la rappresentazione in frequenza del segnale, vuoi cercare il massimo, e dato che il fft è un segnale complesso, vorrai prima prendere il valore assoluto. L'indice corrisponderà alla frequenza normalizzata con la massima energia. Infine, se il tuo segnale ha un offset, come nel caso di quello che mostri, vuoi eliminare quell'offset prima di prendere il fft in modo da non ottenere un massimo sull'origine che rappresenta il componente DC.

Tutto ciò che ho descritto messo in una sola riga sarebbe:

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

dove indexMax è l'indice in cui il valore massimo FFT può essere trovato.

Nota: per passare da indexMax alla frequenza effettiva di interesse, è necessario conoscere la lunghezza L del fft (uguale alla lunghezza del segnale) e la frequenza di campionamento Fs. La frequenza del segnale sarà quindi:

frequency = indexMax * Fs/L; 

In alternativa, più veloce e lavorare abbastanza bene anche a seconda del segnale si ha, prendere l'autocorrelazione del segnale:

autocorrelation = xcorr(signal); 

e trovare il primo massimo che si verifica dopo il punto centrale dell'autocorrelazione. (L'autocorrelazione sarà simmetrica con il suo massimo al centro.) Trovando quel massimo, trovi il primo punto in cui il segnale spostato sembra più o meno uguale a se stesso. Cioè trovi il periodo del tuo segnale. Poiché il segnale spostato da un multiplo del suo periodo sarà sempre uguale a se stesso, è necessario assicurarsi che il massimo che si trova effettivamente corrisponda al periodo del segnale e non a uno dei suoi multipli.

A causa del rumore nel segnale, il massimo assoluto potrebbe verificarsi in un multiplo del periodo invece del periodo stesso. Quindi, per tenere conto di quel rumore, si prenderà il massimo assoluto dell'autocorrelazione (autocorrelazione (lunghezza (autocorrelazione)/2 + 1), quindi si troverà dove l'autocorrelazione è più grande, ad esempio, del 95% di quel valore massimo per il primo il tempo nella seconda metà del segnale: 95%, 99% o qualche altro numero dipenderà da quanto rumore corrompe il segnale

AGGIORNAMENTO: mi rendo conto che ho pensato che intendessi per "frequenza" del tuo segnale il pece o base armonica o frequenza con la maggior energia, tuttavia si vuole guardarla Se per frequenza si intendesse la rappresentazione in frequenza del segnale, quindi in prima approssimazione, si desidera solo tracciare gli addominali della FFT per ottenere un idea di dove sia l'energia:

plot(abs(fft)); 

Se vuoi capire perché c'è un abs o quali informazioni rilevanti stai perdendo non rappresentando la fase del fft, potresti voler leggere un po 'di più sulla trasformazione DFT per capire esattamente cosa ottieni.

+0

Il segnale che ho è da alcune oscillazioni misurati usando un estensimetro. Voglio trovare la frequenza di quelle oscillazioni. Usando il metodo 'fft' che hai postato, ottengo 0,0357 per la frequenza, ma guardando la trama, ci sono circa 10 cicli al secondo, quindi non dovrei ottenere circa 10 per la frequenza? – edc1591

+0

Se hai 10 oscillazioni al secondo, è un periodo di 0,1 o una frequenza di 10 Hz. Quali sono i valori per indexMax, L e F? Esegui anche la trama (abs (fft)) per confermare che hai un grande picco e che indexMax è l'indice corretto per dove si verifica quel picco. Nel grafico mostro che c'è un offset negativo nel segnale, il che significa che ci sarà anche un picco vicino allo zero per il tuo fft che rappresenta il componente DC. Potrebbe essere quello che stai misurando. In questo caso, prendi il fft di (media del segnale (segnale)) invece di rimuovere quel componente DC. – Lolo

+0

Il picco che stavo ottenendo era zero (indexMax = 1). Ho fatto quello che hai detto sottraendo la media (segnale) e ora sto ottenendo circa 9,8 Hz per la frequenza, che sembra giusto! Grazie mille per l'aiuto !! – edc1591

0

ritengo che dovrebbe essere

(indexMax-1) * Fs/L 

Il primo elemento di abs (FFT (x)) è la corrente continua (DC), o polarizzazione, o media di segnale, o X0. Contiamo dal secondo elemento (X1). Per favore fatemi sapere se ho torto. Grazie. enter image description here

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