RMS计算直流偏移 [英] RMS calculation DC offset

查看:239
本文介绍了RMS计算直流偏移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在MCU(微控制器,资源受限)中实现正弦波的RMS计算. MCU缺少FPU(浮点单元),因此我宁愿停留在整数域中.捕获是通过10位ADC进行的.

I need to implement an RMS calculations of sine wave in MCU (microcontroller, resource constrained). MCU lacks FPU (floating point unit), so I would prefer to stay in integer realm. Captures are discrete via 10 bit ADC.

在寻找解决方案时,我在Edgar Bonet的这里找到了一个很好的解决方案: https://stackoverflow.com/a/28812301/8264292

Looking for a solution, I've found this great solution here by Edgar Bonet: https://stackoverflow.com/a/28812301/8264292

似乎完全符合我的需求.但是我有一些疑问.

Seems like it completely suits my needs. But I have some questions.

  1. 输入为230 VAC,50 Hz的主电源.它已经变了&通过硬件补偿,就可以变为0-1V(峰峰值)正弦波,我可以用ADC捕获该正弦波,获得0-1023读数.硬件经过校准,以使260 VRMS(即约-368:+368峰峰值)输入变为0-1V峰值输出.如果我也想保留在整数域中,我如何恢复"原始波RMS值?单位可以变化,毫伏也可以. 我的第一个猜测是从输入样本中减去512(DC偏移),然后像Edgar Bonet的答案一样进行这种魔术"转换.但是我意识到这是错误的,因为直流偏移不是固定的.取而代之的是从0V开始偏置. IE. 130 VAC输入将产生0-500 mV峰峰值输出(到目前为止无法正常工作的250-750 mV). 使用实际RMS减去DC偏移量,我需要从平方和中减去样本的平方和.像这个公式一样:
  1. Input are mains 230 VAC, 50 Hz. It's transformed & offset by hardware means to become 0-1V (peak to peak) sine wave which I can capture with ADC getting 0-1023 readings. Hardware are calibrated so that 260 VRMS (i.e. about -368:+368 peak to peak) input becomes 0-1V peak output. How can I "restore" back original wave RMS value providing I want to stay in integer realm too? Units can vary, mV will do fine also. My first guess was subtracting 512 from the input sample (DC offset) and later doing this "magic" shift as in Edgar Bonet answer. But I've realized it's wrong because DC offset aren't fixed. Instead it's biased to start from 0V. I.e. 130 VAC input would produce 0-500 mV peak to peak output (not 250-750 mV which would've worked so far). With real RMS to subtract the DC offset I need to subtract squared sum of samples from the sum of squares. Like in this formula:

所以我最终得到了以下功能:

So I've ended up with following function:

#define INITIAL 512
#define SAMPLES 1024
#define MAX_V 368UL // Maximum input peak in V ( 260*sqrt(2) )
/* K is defined based on equation, where 64 = 2^6,
 * i.e. 6 bits to add to 10-bit ADC to make it 16-bit 
 * and double it for whole range in -peak to +peak
 */
#define K (MAX_V*64*2)

uint16_t rms_filter(uint16_t sample)
{
    static int16_t rms = INITIAL;
    static uint32_t sum_squares = 1UL * SAMPLES * INITIAL * INITIAL;
    static uint32_t sum = 1UL * SAMPLES * INITIAL;

    sum_squares -= sum_squares / SAMPLES;
    sum_squares += (uint32_t) sample * sample;
    sum -= sum / SAMPLES;
    sum += sample;
    if (rms == 0) rms = 1;    /* do not divide by zero */
    rms = (rms + (((sum_squares / SAMPLES) - (sum/SAMPLES)*(sum/SAMPLES)) / rms)) / 2;
    return rms;
}

...
// Somewhere in a loop
getSample(&sample);
rms = rms_filter(sample);
...
// After getting at least N samples (SAMPLES * X?)
uint16_t vrms = (uint32_t)(rms*K) >> 16;
printf("Converted Vrms = %d V\r\n", vrms);

看起来不错吗?还是我做错了什么?

Does it looks fine? Or am I doing something wrong like this?

  1. SAMPLES(窗口大小?)数字与F(50Hz)和我的ADC捕获率(每秒采样数)有何关系? IE.如果我的捕获速度为X sps,我需要多少真实样本才能馈入rms_filter()才能获得真实RMS值?至少如何评估所需的最少N个样本?

推荐答案

我没有测试您的代码,但是在我看来它应该可以正常工作. 就我个人而言,我不会以这种方式实现该功能.我会 而是删除了信号之前的直流部分,试图 计算RMS值.可以通过发送原始数据来估算DC部分 信号通过低通滤波器.用伪代码是

I did not test your code, but it looks to me like it should work fine. Personally, I would not have implemented the function this way. I would instead have removed the DC part of the signal before trying to compute the RMS value. The DC part can be estimated by sending the raw signal through a low pass filter. In pseudo-code this would be

rms = sqrt(low_pass(square(x - low_pass(x))))

您写的基本上是

rms = sqrt(low_pass(square(x)) - square(low_pass(x)))

它实际上并没有太大的区别.第一个公式, 但是,可以为您省去繁琐的工作.另外,通过去除直流分量 在计算平方之前,最终要乘以较小的数字, 这可能有助于为定点实现分配位.

It shouldn't really make much of a difference though. The first formula, however, spares you a multiplication. Also, by removing the DC component before computing the square, you end up multiplying smaller numbers, which may help in allocating bits for the fixed-point implementation.

无论如何,我建议您使用 合成数据,然后再提交到MCU.

In any case, I recommend you test the filter on your computer with synthetic data before committing it to the MCU.

SAMPLES(窗口大小?)数字与F(50Hz)和我的ADC有什么关系 捕获率(每秒采样数)?

How does SAMPLES (window size?) number relates to F (50Hz) and my ADC capture rate (samples per second)?

常数SAMPLES控制低通的截止频率 过滤器.截止值应足够小以至于几乎可以完全去除 信号的50赫兹部分.另一方面,如果市电 供应不是完全稳定,您要测量的数量将 随时间缓慢变化,您可能希望截止值足够高 捕捉这些变化.

The constant SAMPLES controls the cut-off frequency of the low pass filters. This cut-off should be small enough to almost completely remove the 50 Hz part of the signal. On the other hand, if the mains supply is not completely stable, the quantity you are measuring will slowly vary with time, and you may want your cut-off to be high enough to capture those variations.

这些单极点低通滤波器的传递函数是

The transfer function of these single-pole low-pass filters is

H(z) = z / (SAMPLES * z + 1 − SAMPLES)

其中

  • z = exp(i 2πf/f₀),
  • i是虚数单位
  • f是信号频率,
  • f₀是采样频率

如果f₀f(这是进行良好采样所需要的),则可以近似 这是通过模拟滤波器实现的:

If f₀ ≫ f (which is desirable for a good sampling), you can approximate this by the analog filter:

H(s) = 1/(1 + SAMPLES * s / f₀)

其中,s =i2πf,截止频率为f and/(2π* SAMPLES).收益 那么在f = 50  Hz时

where s = i2πf and the cut-off frequency is f₀/(2π*SAMPLES). The gain at f = 50 Hz is then

1/sqrt(1 + (2π * SAMPLES * f/f₀)²)

此处的相关参数是(SAMPLES * f/f₀),它是 采样窗口内适合的50Hz信号周期. 如果您适合一个时期,则让大约15%的信号通过 过滤器.如果您适合两个月期等,则减半.

The relevant parameter here is (SAMPLES * f/f₀), which is the number of periods of the 50 Hz signal that fit inside your sampling window. If you fit one period, you are letting about 15% of the signal through the filter. Half as much if you fit two periods, etc.

如果您设计一个 在该特定频率下使用 Notch 进行过滤.如果你不想 深入研究数字滤波器设计理论,最简单的此类滤波器可能 是一个简单的移动平均线,其平均周期为 20毫秒.不过,这在RAM中具有不小的成本,因为您必须 在循环缓冲区中保存完整的20毫秒样本.

You could get perfect rejection of the 50 Hz signal if you design a filter with a notch at that particular frequency. If you don't want to dig into digital filter design theory, the simplest such filter may be a simple moving average that averages over a period of exactly 20 ms. This has a non trivial cost in RAM though, as you have to keep a full 20 ms worth of samples in a circular buffer.

这篇关于RMS计算直流偏移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆