深入研究信号处理技术和复杂的数学是可能的,但你必须问自己是否真的有必要?
如果此显示是一个简单的瞬时数字输出,用于“仅指示”而不是连续图形或数据日志(即您不需要重建信号),那么通常完全可以接受,简单地采用周期性平均线而不是移动平均线。由于这不需要历史存储,因此您可以根据需要对尽可能多的样本进行平均,这将取决于所需的显示更新频率。
它并不聪明,但通常足以完成任务。这是一个示例及其使用的测试模拟。
class cPeriodicMean
{
public :
cPeriodicMean( int period ) : m_mean(0),
m_period(period),
m_count(0),
m_sum(0)
{
// empty
}
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 ;
} ;
// Test Simulation
#include <cstdlib>
#include <cstdio>
#include <windows.h> // for Sleep to simulate sample rate
int main()
{
// Average over 100 samples
cPeriodicMean voltage_monitor( 100 ) ;
for(;;)
{
// Simulate 4000mV +/- 50mV input
int sample = 4000 + (std::rand() % 100) - 50 ;
voltage_monitor.addSample( sample ) ;
// Simulate 100Hz sample rate
Sleep(10) ;
// Current output
int millivolts = voltage_monitor.getMean() ;
printf( "\r%d millivolts ", millivolts ) ;
}
}
这种技术的改进将产生更平滑的输出但以相同的频率生成结果,将使用周期性平均输出作为移动平均滤波器的输入。如果您要使用我的每秒 100 个样本和 100 个样本周期的示例,然后将其通过 15 个样本移动平均值,您将使用 15 秒的采样数据,同时仍然每秒获得一个结果,几乎没有额外的内存用法。
显然,您可以更改周期、移动平均长度和采样率,以便以您需要的更新频率获得您需要的结果。我建议您在需要更新的时间段内尽可能多地采样,然后根据您的意愿制作移动平均线。