我用MAX30102传感器来计算心率。这个感应器发出一束光,测量动脉血+皮肤+肌肉和其他东西吸收了多少(虚假的解释)。所以,很大一部分数据是连续值,一小部分是动脉搏动血液(我可以用来计算脉搏)。信号处理的第一项是移除直流分量。我尝试使用带浮动变量的过滤器,现在我发现没有使用它的实现(我将把这段代码放在微控制器中,我想要最好的性能)。我测试了新功能,它运行得很好,但我无法理解它。所以我在这里寻求帮助来理解这个函数中使用的数学。
以下数字有助于解释:
// Average DC Estimator
static int16_t averageDCEstimator(int32_t *p, uint16_t x)
{
*p += ((((long) x << 15) - *p) >> 4);
return (*p >> 15);
}*p是在过去计算的平均值,所以新平均值使用过去的平均值加上实际测量的样本。X是实际测量的样本(传感器发送的数据有18位)。
发布于 2019-08-08 01:32:37
这看起来是一个近似的运行平均值。它类似于加窗的平均值,只不过每一个新的增加值都会对平均值产生一定的影响。因此,它总是偏向于最新的价值。作为一种奖励,它不需要缓冲以前的值。让我们把它拆开。
首先,让我们谈谈单位。x << 15将x左移15位,有效地将其乘以32768。还请注意,最终平均值将存储在p中的值向右移动15位。
这表明存储在p上的值使用了一个称为“定点”的数学技巧,在这里,您使用整数的额外位,就好像它们是小数位一样。
因此,p上的值是当前定点运行的平均值.当x到达时,它被转换成定点,然后计算它与当前运行平均值的偏差。
然后取这个增量,并将其右移4位,有效除以16。这个值被加到运行平均值中。这意味着,每一个新的值可以影响平均数大约十六分之一。换句话说,一个单一的新值对当前平均值有6.25%的影响。
发布于 2019-08-08 02:54:34
请注意,当uint16_t x经常超过32767时,此平均值是错误的。
这个低通滤波器的输出最终将接近x。当x高于int16_t范围时,*p >> 15的转换最终会导致未定义的行为。
推荐为x <= 32767保险
发布于 2019-08-08 04:36:58
P点32位数据的地址。当您返回p>>15时,这将是32位值,但是您的代码返回16位无符号。首先,我建议您使用uint32_t,如果您的平均值不再是负值。您还提到您的传感器数据为18位,但x值为uint16_t。您忽略了来自传感器的2位数据(MSB和MSB-1)。我建议您使用uin32_t中的所有值。如果要返回16位值,可以使用类型转换。例如;
返回(Uint16_t)(您的值);此时您必须确保您的数据不应高于2^16;
https://stackoverflow.com/questions/57404009
复制相似问题