This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RMS calculations and sqrt function?

Other Parts Discussed in Thread: TM4C123GH6PGE

Hi all,

I've got a program that runs an RMS algorithm on a TM4C123GH6PGE (formerly LM4F232H5QD) to do an equipment-protection function. We take a full line cycle of current values at 60 Hz, square each one, add them all together, divide by the number of samples, and then square root the result.

Obviously a fairly math-intensive operation.

My problem is our numbers are coming out wrong: they are much higher than the true value. I took the data in our input buffer, imported it into Excel, ran the calculation there, and ended up with a lower number. I've checked the code and it appears to be doing the algorithm correctly, so now I'm wondering if I'm losing precision somewhere. I'm using double precision floating point, and I'm wondering if the multiply, divide, or sqrt operations might be giving me lower-precision answers.

For reference, I already know about the CMSIS DSP library for the LM4/TM4C line, but I have not yet integrated this. I am using the standard c multiply and divide operators, and the sqrt function. Do I need CMSIS to avoid precision loss?

  • I very much doubt that lack of precision is the problem.

    Why not do the calculation, for debugging purposes, in stages and compare to Excel's calculations. Try in order of complexity:

    1) Just add each value

    2) Square then add each value

    3) Square then add each value and divide by the number of samples

    3) Square then add each value and divide by the number of samples then square root the lot

    Then you will know which operation is causing the problem. Divide and conquer.

  • Hi,

    You need a final scaling - > divide by 2048 - working with samples as received is a good thing but take into account what those represent - each should be scaled by the amplitude (operation called normalization - not to be confounded to the similar name in floating point) then multiplied by a scale factor to give you the real value. Doing some math  before applying the theoretical formula will reveal you the right algorithm. 

  • Had you considered this:

         // Enable lazy stacking for interrupt handlers.  This allows floating-point
        // instructions to be used within interrupt handlers, but at the expense of
        // extra stack usage.
        //
        ROM_FPULazyStackingEnable();

    Thus - if your stack was insufficient - this may explain... 

    And - piecewise testing (as suggested) is likely to "miss this!"

  • We found the problem, it turns out that occasionally we *are* getting a big current spike that's throwing off our readings. It is not related to the math precision, fortunately.

    This isn't running in an interrupt handler (it's evaluated on a "when we have time" basis) so blowing the stack isn't a problem here - but we do have other routines which do run in interrupt handlers, so cb1_mobile's pointer to this function is still going to be incredibly useful.

    Thank you all for your help.