2017-04-21 4 views
0

J'ai un signal d'entrée et j'ai calculé sa FFT. Après cela, j'ai besoin de calculer son RMS SEULEMENT à une bande de fréquence, pas pour tout le spectre.Obtenir RMS à chaque fréquence

J'ai résolu le calcul RMS de l'ensemble du spectre en appliquant le théorème de Parseval, mais comment calculer ce type de RMS "sélectif"? J'ai calculé les index correctement pour obtenir les trois fréquences d'intérêt (F0, FC, F1), mais en appliquant RMS à cette bande passante, il semble que le théorème de Parseval ne soit pas retenu. Je reçois une fréquence unique de 10 KHz, le RMS du spectre total FFT est correct, mais son RMS sélectif à la fréquence de 10 KHz me donne un mauvais résultat (-0.4V de RMS correct) et devrait me donner presque le même résultat car j'ai seulement une frecuency dans le spectre. Ici vous pouvez voir mes RMS calcul sélectif:

public static double RMSSelectiveCalculation(double[] trama, double samplingFreq, double F0, double Fc, double F1) 
    { 
    //Frequency of interest   
     double fs = samplingFreq; // Sampling frequency 
     double t1 = 1/fs;   // Sample time 
     int l = trama.Length;  // Length of signal 
     double rmsSelective = 0; 
     double ParsevalB = 0; 
     double scalingFactor = fs; 
     double dt = 1/fs; 

     // We just use half of the data as the other half is simetric. The middle is found in NFFT/2 + 1 
     int nFFT = (int)Math.Pow(2, NextPow2(l)); 
     double df = fs/nFFT; 
     if (nFFT > 655600) 
     { } 

     // Create complex array for FFT transformation. Use 0s for imaginary part 
     Complex[] samples = new Complex[nFFT]; 
     Complex[] reverseSamples = new Complex[nFFT]; 
     double[] frecuencies = new double[nFFT]; 
     for (int i = 0; i < nFFT; i++) 
     { 
      frecuencies[i] = i * (fs/nFFT); 

      if (i >= trama.Length) 
      { 
       samples[i] = new MathNet.Numerics.Complex(0, 0); 
      } 
      else 
      { 
       samples[i] = new MathNet.Numerics.Complex(trama[i], 0); 
      } 
     } 

     ComplexFourierTransformation fft = new ComplexFourierTransformation(TransformationConvention.Matlab); 
     fft.TransformForward(samples); 
     ComplexVector s = new ComplexVector(samples); 
     //The indexes will get the index of each frecuency 
     int f0Index, fcIndex, f1Index; 
     double k = nFFT/fs; 
     f0Index = (int)Math.Floor(k * F0); 
     fcIndex = (int)Math.Floor(k * Fc); 
     f1Index = (int)Math.Ceiling(k * F1); 

     for (int i = f0Index; i <= f1Index; i++) 
     { 
      ParsevalB += Math.Pow(Math.Abs(s[i].Modulus/scalingFactor), 2.0); 
     } 

     ParsevalB = ParsevalB * df; 

     double ownSF = fs/l; //This is a own scale factor used to take the square root after 

     rmsSelective = Math.Sqrt(ParsevalB * ownSF); 

     samples = null; 
     s = null; 

     return rmsSelective; 

    } 
+0

Avez-vous pas posé cette même question à plusieurs reprises, par exemple [Obtenir RMS à partir de FFT] (http://stackoverflow.com/questions/43452138/getting-rms-from-fft) et [Obtenir RMS à partir de FFT] (http://stackoverflow.com/questions/43363860/get-rms -de-fft)? –

Répondre

0

Une estimation de la densité de puissance spectrale PSD est donnée par le carré de grandeur de la FFT.

Le RMS d'une section avec une certaine bande passante est la racine de la zone de la PSD de cette section.

Donc, pratiquement, il suffit d'intégrer la valeur absolue de la FFT entre la fréquence inférieure et supérieure.

MATLAB example

+0

voir ma réponse s'il vous plaît –