Get RMS from FFT

2019-03-05 02:48发布

I got an array of data voltages and I want to get the RMS value from the FFT that has been applied before to that data. I've seen that RMS in time domain should be equal to RMS(fft) / sqrt(nFFT) from Parseval's Theorem, but gives me different results. I'm using these functions: 1)FFT

 public static VectorDPoint FFT(double[] trama, double samplingFreq)
    {
        double fs = samplingFreq;   // Sampling frequency
        double t1 = 1 / fs;          // Sample time
        int l = trama.Length;       // Length of signal

        // Time vector
        //Vector t = Normal(0, l, 1) * t1;

        //// Values vector
        //Vector y = new Vector(trama);

        // 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));

        if (nFFT > 655600)
        { }

        // Create complex array for FFT transformation. Use 0s for imaginary part
        Complex[] samples = new Complex[nFFT];
        for (int i = 0; i < nFFT; i++)
        {
            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);
        s = s / l;

        Vector f = (fs / 2.0) * Linspace(0, 1, (nFFT / 2) + 1);
        VectorDPoint result = new VectorDPoint();

        for (int i = 0; i < (nFFT / 2) + 1; i++)
        {
            result.Add(new DPoint(f[i], 2 * s[i].Modulus));
        }

        s = null;
        f = null;
        samples = null;

        return result;

2) RMS

 public static double RMSCalculate(double[] channelValues, int samplesNumber, double sampleRate, DateTime currentDate)
    {
        double[] times = new double[channelValues.Length];
        double sampleTime = 0.0;
        double period = 0;


            times[0] = currentDate.Second + currentDate.Millisecond / 1000.0;
            sampleTime = 1 / sampleRate;   //s

        // Limited samples
        for (int i = 1; i < channelValues.Length; i++)
        {
            times[i] = times[i - 1] + sampleTime;
        }

        DPoint RMSValues = new DPoint();
            RMSValues.Y = 0;
            if (channelValues.Length == 1)
            {
                double x = channelValues[0];
                double y = channelValues[0];
                RMSValues = new DPoint(x, Math.Abs(y));
            }
            else
            {

                for (int i = 0; i < times.Length - 1; i++)
                {
                    period = 0;

                    if (i + 1 < times.Length)
                    {
                        RMSValues.Y += channelValues[i + 1] * channelValues[i + 1] * (times[i + 1] - times[i]);
                    }
                }

                period = times[times.Length - 1] - times[0];
                RMSValues.Y = RMSValues.Y / period;
                RMSValues.Y = Math.Sqrt(RMSValues.Y);

            }

        return RMSValues.Y;
    }

0条回答
登录 后发表回答