EEVblog Electronics Community Forum

Electronics => Projects, Designs, and Technical Stuff => Topic started by: Red_Micro on June 10, 2020, 01:47:26 pm

Title: RMS calculation in cheap microcontroller
Post by: Red_Micro on June 10, 2020, 01:47:26 pm
I sometimes see that RMS calculation is done using some kind of DSP or more high end microcontroller. I'm using this STM32 microcontroller (https://www.st.com/resource/en/datasheet/stm32g030c6.pdf) and I would like to know if it could do RMS.

I need to read 60 Hz current from a current transformer through an op-amp as shown below. I don't have values in the drawing because I'm just illustrating the concept. I've heard that one can use an external precision rectifier to sense the peak and calculate RMS from that. In my case I have the signal with a DC shift, and I think that doing RMS would be more robust against noise compared to just sensing the peak.

Any suggestions?

Title: Re: RMS calculation in cheap microcontroller
Post by: NiHaoMike on June 10, 2020, 01:50:48 pm
Square each sample, take the average, then take the square root.
Title: Re: RMS calculation in cheap microcontroller
Post by: Ian.M on June 10, 2020, 02:19:48 pm
Any MCU with a hardware multiplier can handle RMS measurements if there is an internal or external ADC with enough precision and a max sample rate two or more orders of magnitude faster than the period of highest significant harmonic in the input signal, and the MCU has enough MIPS to do a 16x16 bit => 32 bit multiply and a 32 bit accumulate for each input sample + some housekeeping to track time between either min. or max. peaks or zero crossings to determine the duration of a full cycle of the input waveform.   The square root only has to be handled once per input waveform period, so doesn't need to be fast or efficient.   Only really slow low end 8 bit MCUs would have a problem with processing the RMS calculation fast enough for a line frequency signal.

Therefore if a MCU has got a hardware multiplier, and doesn't need to handle other computationally intensive tasks during the measurement cycle, you can pretty much assume its capable of real-time line frequency RMS calculations.
Title: Re: RMS calculation in cheap microcontroller
Post by: coppice on June 10, 2020, 02:36:49 pm
Any MCU with a hardware multiplier can handle RMS measurements if there is an internal or external ADC with enough precision and a max sample rate two or more orders of magnitude faster than the period of highest significant harmonic in the input signal, and the MCU has enough MIPS to do a 16x16 bit => 32 bit multiply and a 32 bit accumulate for each input sample + some housekeeping to track time between either min. or max. peaks or zero crossings to determine the duration of a full cycle of the input waveform.   The square root only has to be handled once per input waveform period, so doesn't need to be fast or efficient.   Only really slow low end 8 bit MCUs would have a problem with processing the RMS calculation fast enough for a line frequency signal.

Therefore if a MCU has got a hardware multiplier, and doesn't need to handle other computationally intensive tasks during the measurement cycle, you can pretty much assume its capable of real-time line frequency RMS calculations.
Remember that before you multiply those samples you probably need to do an accurate DC estimation and removal, because few ADCs can be trusted to have a stable offset value.
Title: Re: RMS calculation in cheap microcontroller
Post by: Ian.M on June 10, 2020, 03:01:26 pm
Good point.  So  for each sample, there's one more accumulate to do on the signed ADC result to keep tracking the DC offset, and a subtract to remove the average offset calculated in a previous cycle before the multiply.  Sample rate vs MIPS would have to be really tight for that to be a problem.  To get the average offset, the accumulated offset only has to be divided by the number of samples per cycle once in each cycle, so it should be practical to update the average offset with no more than two cycles lag.
Title: Re: RMS calculation in cheap microcontroller
Post by: WattsThat on June 10, 2020, 03:23:27 pm
If your load is linear, then yes, you could calculate rms from the peak. This is another way of saying if your current waveform is a perfect sine wave with no distortion, they you can get there just knowing the peak to peak value.

Ultimately, it comes down to what load is, how much distortion exists and how accurate you need the resulting value to be. What’s been described above in post #2 works for any waveform, within the constraints described with respect to the input signal and the measuring hardware.

There’s a world of difference between the current that flows into a purely resistive load and what flows into a switch mode power supply.
Title: Re: RMS calculation in cheap microcontroller
Post by: SiliconWizard on June 10, 2020, 03:24:18 pm
Also note that depending on what you do with the RMS value, you don't necessarily have to compute the (expensive) square root.
Title: Re: RMS calculation in cheap microcontroller
Post by: Kleinstein on June 10, 2020, 03:45:53 pm
One can do the offset removal after summing up the squares from the same data-set. One just has to keep track on the average (sum).  I have done RMS in software with an 8 Bit AVR (with HW multiplier, 10 bit ADC). For some 20 kHz sampling it took less than 4 MHz CPU clock.

The effective bandwidth can (and often will, if there is no anti aliasing filter) be even higher than the sampling speed if the signal is not correlated with the sampling or some pseudo random spacing is used (or assumed as an approximation). The BW limit is the speed of the S&H stage, not the Nyquist limit.
Title: Re: RMS calculation in cheap microcontroller
Post by: Red_Micro on June 10, 2020, 04:42:35 pm
Actually, I'm working on an application as described in the document attached. Has anyone heard about those Walsh Functions?
Title: Re: RMS calculation in cheap microcontroller
Post by: coppice on June 10, 2020, 04:47:04 pm
Actually, I'm working on an application as described in the document attached. Has anyone heard about those Walsh Functions?
Walsh functions are one of the standard things you learn about in a DSP course, even though they seldom get applied in practical systems. They are typically used as an illustration that any set of basis functions complying with certain conditions can be used to decompose a waveform, and that decomposition into a series of sine waves is not unique.
Title: Re: RMS calculation in cheap microcontroller
Post by: ejeffrey on June 10, 2020, 05:03:31 pm
if there is an internal or external ADC with enough precision and a max sample rate two or more orders of magnitude faster than the period of highest significant harmonic in the input signal,

That is probably dramatic overkill in 99% of situations.  Its not a big deal because even that is fairly modest by modern MCU standards: to look at the 7th harmonic of 60 Hz with 100x oversampling is still only 48 kHz, so essentially audio speed and even low end microprocessors will have hundreds of clock cycles per sample.   But if you are pressed for cycles for whatever reason you could usually go much slower than that.  To figure out exactly how low you can go you would need more specifications such as the required accuracy, expected amount of harmonic content, and so on.
Title: Re: RMS calculation in cheap microcontroller
Post by: nfmax on June 10, 2020, 05:57:37 pm
If you are happy with an exponentially-filtered estimate of the RMS of the AC component of a signal - more or less what an old analogue RMS-reading meter would indicate - and your data points are sampled at constant intervals, you can use a fast recursive algorithm to calculate the exponentially-weighted mean (DC level) and variance (square of the AC RMS value), sample by sample:

Code: [Select]
  diff := x - mean
  incr := alpha * diff
  mean := mean + incr
  variance := (1 - alpha) * (variance + diff * incr)

To start up, set the value of mean to the first sample value x, and set the value of variance to zero, then iterate starting from the second sample. Constant alpha (0 < alpha < 1) sets the 'time constant' of the filter; variables diff and incr are used for temporary storage. Take the square root of variance if and when you need the actual RMS value.

Source: https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf (https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf)

Implementation using fixed-point arithmetic is left as an excercise for the reader  ;D
Title: Re: RMS calculation in cheap microcontroller
Post by: Bassman59 on June 10, 2020, 07:58:47 pm
If you are happy with an exponentially-filtered estimate of the RMS of the AC component of a signal - more or less what an old analogue RMS-reading meter would indicate - and your data points are sampled at constant intervals, you can use a fast recursive algorithm to calculate the exponentially-weighted mean (DC level) and variance (square of the AC RMS value), sample by sample:

Code: [Select]
  diff := x - mean
  incr := alpha * diff
  mean := mean + incr
  variance := (1 - alpha) * (variance + diff * incr)

To start up, set the value of mean to the first sample value x, and set the value of variance to zero, then iterate starting from the second sample. Constant alpha (0 < alpha < 1) sets the 'time constant' of the filter; variables diff and incr are used for temporary storage. Take the square root of variance if and when you need the actual RMS value.

Source: https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf (https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf)

Implementation using fixed-point arithmetic is left as an excercise for the reader  ;D

Ah, you beat me to it -- I'm doing the same thing now!
Title: Re: RMS calculation in cheap microcontroller
Post by: coppice on June 10, 2020, 08:24:31 pm
If you are happy with an exponentially-filtered estimate of the RMS of the AC component of a signal - more or less what an old analogue RMS-reading meter would indicate - and your data points are sampled at constant intervals, you can use a fast recursive algorithm to calculate the exponentially-weighted mean (DC level) and variance (square of the AC RMS value), sample by sample:

Code: [Select]
  diff := x - mean
  incr := alpha * diff
  mean := mean + incr
  variance := (1 - alpha) * (variance + diff * incr)

To start up, set the value of mean to the first sample value x, and set the value of variance to zero, then iterate starting from the second sample. Constant alpha (0 < alpha < 1) sets the 'time constant' of the filter; variables diff and incr are used for temporary storage. Take the square root of variance if and when you need the actual RMS value.

Source: https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf (https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf)

Implementation using fixed-point arithmetic is left as an excercise for the reader  ;D
What's fast about that? At 3 multiplies per sample its not faster than other ways of achieving the same outcome.
Title: Re: RMS calculation in cheap microcontroller
Post by: pardo-bsso on June 11, 2020, 01:50:36 pm
What's fast about that? At 3 multiplies per sample its not faster than other ways of achieving the same outcome.

In the linked paper they do a nice derivation of why it works and also avoids loss of precision and numerical stability errors for large sample sets.

But as with almost everything, it depends on your needs and use case.