# RMS value calculation using micro-controller

how to calculate the RMS value of an AC signal (220v,50c/s) using micro-controller. i m using stm32f3 controller and its A/D convertor has 72MHZ clock frequency.

• Multiply it by 0.7071? – Majenko Oct 21 '14 at 18:18
• @Majenko - only if it's a clean sine wave. – brhans Oct 21 '14 at 22:53

You can digitize samples of the waveform at a high frequency, square them, then feed that into a low-pass filter. Take the square root of the output of the LPF.

The cutoff frequency (and order) of the low pass filter is a trade-off between output ripple and response time (for example, after the input waveform changes). A simple IIR low pass filter might be sufficient.

Since you know the mains frequency there are faster-responding filters such as the boxcar filter Andy suggests, assuming you have enough RAM to support that approach and arrange things to have an integer number of samples in a power line cycle.

Take a bunch of consecutive samples (say 100). Square each one numerically. Add them all together to produce an accumulated value. Divide by the number of samples and finally take the square root.

That's the basic method. If you want a rolling RMS value then for each new sample remove the oldest (squared) from the accumulated value and add the new one squared to the accumulated value.

RMS is basically the same as calculating standard deviation: -

Except you don't need to know $\bar x$ (mean value) because in RMS it's assumed to be zero.

• Things tend to work nicely if N is a power of two. If you can stick to integer divides, then your divides become shifts. – Scott Seidman Oct 21 '14 at 19:19
• Never thought of it that way... some years ago I implemented a rolling standard deviation filter using only convolution. – Scott Seidman Oct 21 '14 at 19:20
• @ScottSeidman Interesting. Do you have a link to your convoluted solution? :) – AaronD Oct 21 '14 at 19:27
• @ScottSeidman No link I'm afraid - just too many years designing power meters. If you chopped an arm off it'd be written in the bone marrow. – Andy aka Oct 21 '14 at 19:59
• In Matlabese (N should be odd, no error check): function y=movingvar(X,N) X=X(:); XSQR=X.*X; convsig=ones(1,N); y=(conv(convsig,XSQR)-(conv(convsig,X).^2)/N)/(N-1); y=y(ceil(N/2):length(X)+floor(N/2)); – Scott Seidman Oct 21 '14 at 21:13

If the signal is a sine wave, for best precision you should adjust the sampling frequency to the input signal, to have a constant number of samples per period, for example by detecting zero crossings.

I did this many years ago for a power analysis equipment (which calculates harmonics, distortion, phases...).