要深入研究信号处理技术和复杂数学是完全可能的,但你必须问自己这是否真的有必要呢?
如果这个显示只是简单的瞬时数值输出,仅用于“指示”而不是连续的图形或数据记录(即不需要重建信号),那么通常可以接受以周期平均代替移动平均。由于不需要存储历史数据,你可以对任意数量的样本进行平均,具体取决于所需的显示更新频率。
虽然这并不“聪明”,但通常已经足够完成任务。下面是一个示例和其使用的测试模拟。
class cPeriodicMean
{
public :
cPeriodicMean( int period ) : m_mean(0),
m_period(period),
m_count(0),
m_sum(0)
{
}
void addSample( int sample )
{
m_sum += sample ;
m_count++ ;
if( m_count == m_period )
{
m_mean = m_sum / m_period ;
m_count = 0 ;
m_sum = 0 ;
}
}
int getMean()
{
return m_mean ;
}
private :
int m_mean ;
int m_period ;
int m_count ;
int m_sum ;
} ;
#include <cstdlib>
#include <cstdio>
#include <windows.h>
int main()
{
cPeriodicMean voltage_monitor( 100 ) ;
for(;;)
{
int sample = 4000 + (std::rand() % 100) - 50 ;
voltage_monitor.addSample( sample ) ;
Sleep(10) ;
int millivolts = voltage_monitor.getMean() ;
printf( "\r%d millivolts ", millivolts ) ;
}
}
这种技术的改进可以产生更加平滑的输出,但是以相同的频率生成结果,方法是将周期均值输出作为移动平均滤波器的输入。如果您使用我的每秒100个样本的示例,并将其通过15个样本的移动平均值,您将使用15秒的采样数据,同时仍然每秒获得一个结果,而且内存使用量很小。
显然,您可以更改周期、移动平均长度和采样率,以获得所需的更新频率的结果。我建议您在需要更新的周期内尽可能多地采样,然后根据您的预算设置移动平均长度。