I'm using a STM32 Cortex M0+ controller which does not have FPU. I'm reading 50/60Hz sine wave and I would like to calculate the RMS using the DSP library: keil.com/pack/doc/CMSIS/DSP/html/group__RMS.html. Looking into this library, there are three functions to compute the RMS:

void arm_rms_f32 (const float32_t *pSrc, uint32_t blockSize, float32_t *pResult)
    Root Mean Square of the elements of a floating-point vector. 
void arm_rms_q15 (const q15_t *pSrc, uint32_t blockSize, q15_t *pResult)
    Root Mean Square of the elements of a Q15 vector. 
void arm_rms_q31 (const q31_t *pSrc, uint32_t blockSize, q31_t *pResult)
    Root Mean Square of the elements of a Q31 vector. 

As the micro doesn't have FPU, is it more convenient to avoid floating calculation and use Q15 or Q31 format? If so, do I need to convert the data from the ADC to Q15/Q31 format, right?

In the other hand, my AC signal has DC bias equal to Vcc/2 or 1.65V. Converting this to digital, it is equal to 2048. But when I sampling, this value actually varies from 2044 to 2052 (my noise floor I guess) I have seen several methods to deal with this offset:

  1. Subtract a fixed value of 2048 from each ADC reading. This is no so good as I said above this value may vary slightly. Also, if I want to detect zero cross it may cause errors to choose exactly 2048 as reference.
  2. Sample the DC bias and average it
  3. Leave it and get the DC value as RMS result when there's no input signal
  4. Use a more sophisticated software high pass filter
  5. Use the formula below

I would appreciate some recommendation about this.

enter image description here


Using Fixed Point is a good Idea. other than providing a huge numberspace, floating point has only drawbacks: slower to process, sideeffects, less precision.

Fixpoint is in most cases the better choice. In fact a DSP manufacturer with a floting and a fixpoint line told me once, fixpoint is driven by simulation tools like matlab to transfer their code 1:1 to the embedded world. But the fixpoint devices are better in almost all application.

To your DC Bias problem:

if your input signal has stable amplitudes (on average) you not even need to sample it. Then you can derive it from the input data

so, to process it, try if a simple median filter gets the job done. a median filter is easy to implement. create an array with a odd number of elements and feed in your dc-offset value with dropping the oldest value. so if your Array has 9 Elements just index it with index is idx=(idx++)%9;

Then create a second array of same size and sort the values of the first array into the second. (less than 25 Elements: use insertion sort or shellsort)

The Median is always the middle element, like in case of 9 elements its at Index 4 (9>>1=4)

While a simple moving average has the characteristic of a fir filter, the median filter is much like a IIR filter, but much simpler to compute and it is stable!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy