张春 发表于 7 天前

STM32常用数据采集滤波算法

比方,STM32举行滤波处理时,主要目的是处理数据采集过程中可能产生的噪声和尖刺信号。这些噪声可能来自电源干扰、传感器自身的不稳固性或其他外部因素。
1.一阶互补滤波

方法:取a=0~1,本次滤波结果=(1-a)本次采样值+a前次滤波结果 优点:对周期性干扰具有良好的抑制作用适用于颠簸频率较高的场合 缺点:相位滞后,敏捷度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号。
int firstOrderFilter(int newValue, int oldValue, float a)
{
        return a * newValue + (1-a) * oldValue;
} https://i-blog.csdnimg.cn/direct/f57c99caebd04d76aecb1db6988b3463.jpeg
2.中位值滤波

方法:连续采样N次(N取奇数)把N次采样值按大小分列取中间值为本次有效值 优点:能有效降服因偶然因素引起的颠簸干扰;对温度、液位等变革缓慢的被测参数有良好的滤波效果 缺点:对流量,速率等快速变革的参数不宜。
//中值滤波算法
int middleValueFilter(int N)
{
    int value_buf;
    int i,j,k,temp;
    for( i = 0; i < N; ++i)
    {
      value_buf = HAL_ADC_GetValue(&hadc1);       
                               
    }
    for(j = 0 ; j < N-1; ++j)
    {
      for(k = 0; k < N-j-1; ++k)
      {
            //从小到大排序,冒泡法排序
            if(value_buf > value_buf)
            {
                temp = value_buf;
                value_buf = value_buf;
                value_buf = temp;
            }
      }
    }
               
    return value_buf[(N-1)/2];
} https://i-blog.csdnimg.cn/direct/df9c3bf71187417f80dd4467b6ac78c0.png
3.算术均匀滤波

方法:连续取N个采样值举行算术均匀运算; N值较大时:信号平滑度较高,但敏捷度较低 N值较小时:信号平滑度较低,但敏捷度较高 N值的选取:一样平常流量,N=12;压力:N=4 优点:试用于对一样平常具有随机干扰的信号举行滤波。这种信号的特点是有一个均匀值,信号在某一数值范围附近上下颠簸。 缺点:测量速率较慢或要求数据盘算较快的及时控制不适用。
int averageFilter(int N)
{
   int sum = 0;
   short i;
   for(i = 0; i < N; ++i)
   {
      sum += HAL_ADC_GetValue(&hadc1);       
   }
   return sum/N;
} https://i-blog.csdnimg.cn/direct/ee312c4b3f6b4f13abe5fdfba7a3ed70.png
4.滑动均匀滤波

方法:把连续取N个采样值当作一个队列,队列的长度固定为N。每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先辈先出原则)。把队列中的N个数据举行算术均匀运算,就可获得新的滤波结果。 N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4 优点:对周期性干扰有良好的抑制作用,平滑度高;试用于高频振荡的系统 缺点:敏捷度低;对偶然出现的脉冲性干扰的抑制作用较差,不适于脉冲干扰较严重的场合 比较浪费RAM(改进方法,减去的不是队首的值,而是上一次得到的均匀值)
//平滑均值滤波
#define N 10
int value_buf;
int sum=0;
int curNum=0;
int moveAverageFilter()
{
    if(curNum < N)
    {
      value_buf = HAL_ADC_GetValue(&hadc1);
      sum += value_buf;
                          curNum++;
      return sum/curNum;
    }
    else
    {
      sum -= sum/N;
      sum += HAL_ADC_GetValue(&hadc1);
      return sum/N;
    }
} https://i-blog.csdnimg.cn/direct/0b2dd63ccf7d4a88bce6124b360629bc.png
5.限幅均匀滤波

方法:相当于“限幅滤波法”+“递推均匀滤波法” 每次采样到的新数据先辈行限幅处理再送入队列举行递推均匀滤波处理 优点:对于偶然出现的脉冲性干扰,可消除有其引起的采样值偏差。 缺点:比较浪费RAM
//限幅平均滤波
#define A 50      //限制幅度阈值
#define M 12
int data;
int First_flag=0;
int LAverageFilter()
{
int i;
int temp,sum,flag=0;
data=HAL_ADC_GetValue(&hadc1);
        for(i=1;i<M;i++)
        {
                temp=HAL_ADC_GetValue(&hadc1);
                if((temp-data)>A||((data-temp)>A))
                {
                  i--;flag++;
                }
                else
                {
                        data=temp;
                }
        }
for(i=0;i<M;i++)
{
    sum+=data;
}
returnsum/M;
} 6.卡尔曼滤波

核心思想:根据当前的仪器"测量值" 和上一刻的 “猜测量” 和 “误差”,盘算得到当前的最优量,再猜测下一刻的量。内里比较突出的是观点是:把误差纳入盘算,而且分为猜测误差和测量误差两种,通称为噪声。还有一个非常大的特点是:误差独立存在,始终不受测量数据的影响。
优点:巧妙的融合了观测数据与估计数据,对误差举行闭环管理,将误差限定在一定范围。适用性范围很广,时效性和效果都很优秀。
缺点:必要调参,参数的大小对滤波的效果影响较大。
//卡尔曼滤波
int KalmanFilter(int inData)
{
                static float prevData = 0;   //先前数值 上一次滤波后的数据,作为下一次滤波的初始值
                static float p = 10, q = 0.001, r = 0.001, kGain = 0;    // q控制误差r控制响应速度
               
            //更新估计误差方差
                p = p + q;
            //计算卡尔曼增益
                kGain = p / ( p + r );                                    
            //计算本次滤波估计值
                inData = prevData + ( kGain * ( inData - prevData ) );
            //更新测量方差
                p = ( 1 - kGain ) * p;                                    
                prevData = inData;
                return inData;                                             //返回滤波值
} https://i-blog.csdnimg.cn/direct/5a40b0a54ee34a28aac7be79dee3081b.png
prevData:生存上一次滤波后的数据,用于下一次的滤波。 p:估计误差方差,表现当前估计值的不确定性。 q:过程噪声方差,表现系统模型的不确定性。 r:测量噪声方差,表现测量数据的不确定性。 kGain:卡尔曼增益,决定了测量数据和估计数据对当前状态估计的影响程度。
初始化静态变量
更新估计误差方差
盘算卡尔曼增益
更新估计值
更新估计误差方差
生存当前估计值
返回滤波后的值
7.限幅滤波

核心思想:根据经验判断,确定两次采样允许的最大偏差值(设为A),每次检测到新值时判断: 假如本次值与前次值之差<=A,则本次值有效,假如本次值与前次值之差>A,则本次值无效,放弃本次值,用前次值取代本次值。 优点:能降服偶然因素引起的脉冲干扰 缺点:无法抑制周期性的干扰,平滑度差
#defineA 51
u16 Value1;

u16 filter1()
{
u16 NewValue;
        Value1 = ftable;
NewValue = ftable;
        b++;
        a++;
        if(a==255) a=0;
        if(b==255) b=1;
if(((NewValue - Value1) > A) || ((Value1 - NewValue) > A))
        {
                print_host(ftable,NewValue);
    return NewValue;
        }
else
        {
               print_host(ftable,Value1);
   return Value1;
        }
} 8.加权递推均匀滤波

核心思想: 是对递推均匀滤波法的改进,即差异时刻的数据加以差异的权;通常是,越接近现时刻的数据,权取得越大,给予新采样值的权系数越大,则敏捷度越高,但信号平滑度越低。 优点: 适用于有较大纯滞后时间常数的对象,和采样周期较短的系统。 缺点: 对于纯滞后时间常数较小、采样周期较长、变革缓慢的信号;不能迅速反应系统当前所受干扰的严重程度,滤波效果差。
#define FILTER8_N 12
int coe = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};    // 加权系数表
int sum_coe = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12; // 加权系数和
int filter_buf;
int filter8()
{
int i;
int filter_sum = 0;
filter_buf = ftable;               
        a++;
        if(a==255)   a=0;
for(i = 0; i < FILTER8_N; i++)
{
    filter_buf = filter_buf; // 所有数据左移,低位仍掉
    filter_sum += filter_buf * coe;
}
filter_sum /= sum_coe;
//        printf("%d\n",filter_sum);
return filter_sum;
}

void pros8(void)
{
        u16 i=0;
        for(i=0;i<255;i++)
        {
   print_host(ftable,filter8());
        }
} 9.消抖滤波

方法: 设置一个滤波计数器,将每次采样值与当前有效值比较: 假如采样值=当前有效值,则计数器清零; 假如采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出); 假如计数器溢出,则将本次值更换当前有效值,并清计数器。 优点: 对于变革缓慢的被测参数有较好的滤波效果; 可克制在临界值附近控制器的反复开/关跳动或显示器上数值抖动。 缺点: 对于快速变革的参数不宜; 假如在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。
#define FILTER9_N 51
u16 i = 0;
u16 Value;
u16 filter9()
{
int new_value;
        Value = ftable;
new_value = ftable;               
        b++;
        if(b==255)   b=1;
if(Value != new_value)
        {
    i++;
    if(i > FILTER9_N)
                {
      i = 0;
      Value = new_value;
    }
}
else   i = 0;
return Value;
}

void pros9(void)
{
        u16 i=0;
        for(i=0;i<255;i++)
        {
   print_host(ftable,filter9());
        }
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: STM32常用数据采集滤波算法