【发布时间】:2015-06-10 12:53:07
【问题描述】:
我正在尝试计算波形的 RMS 值,但遇到了一些问题。
我每 x 微秒采样一次,这是由中断触发的。样本存储在一个数组中,每次取一个样本时,它会将最后一个值推到数组中的下一个点并输入一个新值。当我取样本时,我将它平方并除以 20(每个样本的数量周期,假设波形固定频率)然后将其放入我的数组中,我还将它添加到一个总和值,当我达到 20 个样本时,我减去第一个样本并添加最后一个样本。
value 20 = value 19 //INT16 values
value 19 = value 18
...
value1 = (sample * sample)/20
sumvalue += value1
sumvalue -= value20
然后我调用一个 RMS 函数,它取该值,除以最后计算的 RMS 值(或者如果尚未计算,则除以 1)加上最后一个 RMS 值,然后将所有值除以 2。
CalcRMS(sumvalue)
INT32 tempsum
if(RMS)
tempsum = (sumvalue/RMS + RMS)/2
else
tempsum = (sumvalue + 1)/2
RMS = tempsum
然后我将 RMS 输出到屏幕。唯一的问题是我的 RMS 值一直在变化,即使波形是恒定的。如果我在那里运行一个直流值,我的 RMS 会保持稳定,但会以正弦波推进,它会发疯。
希望有人能指出我正确的方向。我不希望直接得到答案,只是一些轻推让我回到正轨。
【问题讨论】:
-
我不确定最后两个 RMS 值之间的平均值,因为这会在帧之间增加额外的“平均值”计算。由于您正在处理定点数,因此您可能想测试是否出现溢出错误。为此,请尝试使用较低幅度的正弦波馈送您的算法。最后,这可能会有所帮助:stackoverflow.com/questions/1058813/… 以及:en.wikipedia.org/wiki/Algorithms_for_calculating_variance
-
这种代码:'value 20 = value 19 //INT16 values value 19 = value 18 ...'是一个巨大的CPU周期浪费。相反,请使用循环队列。
-
可能花费的时间太长,并且在班次中途再次调用了中断。我将尝试将值放入缓冲区并使用指针来索引值。
-
20 个样本不足以获得准确的读数,您的描述正是我所期望的。你基本上得到了波形的随机部分。除非您的读数被计时以精确覆盖单波交流电。
-
如果你想想收敛到一个稳定值意味着什么,它意味着你的 value1 = value20。给定 x[i] = sin(t[i]) 和 value=x*x/20,这对关于谐波函数周期的采样率提出了非常具体的要求。换言之,t[1] 和 t[20] 必须相对于正弦曲线落在同一位置。这有意义吗?
标签: c fixed-point rms