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:
- 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.
- Sample the DC bias and average it
- Leave it and get the DC value as RMS result when there's no input signal
- Use a more sophisticated software high pass filter
- Use the formula below
I would appreciate some recommendation about this.