打印
[技术问答]

单片机上使用的几种滤波算法

[复制链接]
771|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bestwell|  楼主 | 2024-9-9 12:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实用单片机采集数据时,往往需要对一些采集的数据进行计算,常用的计算方式比如求平均值、加权平均算法等;本次也记录几个学习过的算法。

1、缓冲滤波算法
算法原理:将数据缓存在一个数组中,每次插入一个数据,就移除最早进入的数据,然后对该数组的数据进行排列后,取中间的部分数据求平均值;

优点:对于采集的数据动态变化较快情况,该算法能够很好的滤除波动误差,使数据趋近一个比较稳定的值。该滤波算法适用于静态数据变化;

缺点:数据计算过程繁多,需要一定的数据进行缓存;

算法实现:C语言

/********************************************************************
*@函数名:BubbleSort(uint16_t *arr, uint16_t n)
*@功  能:冒泡排序算法,将数据按照从小到大的顺序进行排列
*@形  参:arr 指向数据缓存区的指针  n 数据个数
*@返回值:NULL
*@备  注:NULL
********************************************************************/
void BubbleSort(uint16_t *arr, uint16_t n)
{
  uint16_t i, j;
        uint16_t temp;
       
        for(i=0; i<n; i++)
        {
          for(j=i+1; j<n; j++)
                {
                  if(arr[i] > arr[j])
                        {
                          temp = arr[i];
                                arr[i] = arr[j];
                                arr[j] = temp;
                        }
                }
        }
}

/********************************************************************
*@函数名:GetSum(uint16_t *buff, uint16_t start, uint16_t num)
*@功  能:数据求和
*@形  参:buff 指向数据缓存区的指针  num 数据个数
*@返回值:求和结果
*@备  注:NULL
********************************************************************/
uint32_t GetSum(uint16_t *buff, uint16_t start, uint16_t num)
{
  uint16_t i;
  uint32_t        sum = 0;
        num =  num+start;
        for(i=start; i<num; i++)
        {
          sum += buff[i];
        }
        return sum;
}





#define FIFO_SIZE  10
uint16_t FiftBuff[FIFO_SIZE];

/********************************************************************
*@函数名:Fift
*@功  能:缓冲滤波算法
*@形  参:value 需要滤波的数据
*@返回值:滤波后的结果
*@备  注:NULL
********************************************************************/
uint16_t Fift(uint16_t value)
{
        uint8_t i;
        uint32_t sum;
        static uint16_t buf[FIFO_SIZE];
        static uint8_t  num=0;       
       
        if(num >= FIFO_SIZE)
        {                               
          num = 0;
        }
        FiftBuff[num++] = value;

        for(i=0; i<FIFO_SIZE; i++)
        {
         buf[i] = PhCheckBuff[i];
        }

        BubbleSort(buf, FIFO_SIZE);
        sum = GetSum(buf, FIFO_SIZE/4, FIFO_SIZE/2);
        return sum/(FIFO_SIZE/2);
}
2、一阶滞后滤波算法
一阶滞后滤波算法数学计算公式为:



式中:是输出结果,α是滤波系数,是本次采样值,是上一次的输出结果

一阶滤波相当于是将新的采样值与上次的滤波结果计算一个加权平均值,算法的效果就是滞后于系统变化,可以滤除数据的各种干扰,使得系统收敛。a的取值决定了算法的灵敏度,α越大,新采集的值占的权重越大,算法越灵敏,但平顺性差;相反,α越小,新采集的值占的权重越小,灵敏度差,但平顺性好。,其效果图如下所示:蓝色为原始数据,红色为滤波数据;



图1:一阶滞后滤波算法效果图

/********************************************************************
*@函数名:FirstOrderFilter(float newdata, float lastdata, float k)
*@功  能:一阶滤波算法
*@形  参:newdata 新数据   lastdata 上次数据   k 滤波系数
*@返回值:滤波后数据
*@备  注:k : 0.0~1.0   
********************************************************************/
float FirstOrderFilter(float newdata, float lastdata, float k)
{
        lastdata = k*newdata + (1-k)*lastdata;       
        return(lastdata);
}
由于上述的算法具有浮点型运算,所以为了计算效率,在实际计算过程中使用整形进行计算的方式如下:

/********************************************************************
*@函数名:FOL_Filter(uint16_t newdata, uint16_t olddata, uint8_t k)
*@功  能:一阶滞后滤波算法
*@形  参:newdata 新数据   olddata 上次数据   k 滤波系数
*@返回值:滤波后数据
*@备  注:k : 1~255   为减小滤波计算
********************************************************************/
uint16_t FOL_Filter(uint16_t newdata, uint16_t olddata, uint8_t k)
{
    uint32_t result;
    if(newdata < olddata)
    {
        result = olddata - newdata;
        result = result * k;
        result = result + 128;
        result = result>>8; //除以256
        result = olddata - result;
    }
    else if(newdata > olddata)
    {
        result = newdata - olddata;
        result = result * k;
        result = result + 128;
        result = result>>8; //除以256
        result = olddata + result;
    }
    else result = olddata;
    return(result);
}
3、卡尔曼滤波算法
什么是卡尔曼滤波?百度解释为:卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。

具体的原理可以自行百度,本次只提供相关的实现代码:

/********************************************************************
*@函数名:KalmanFilter(float newdata)
*@功  能:卡尔曼滤波
*@形  参:newdata 新数据
*@返回值:滤波后数据
*@备  注:要定义过程噪声和测量噪声
********************************************************************/

/*
        Q: 过程噪声,Q增大,动态响应变快,收敛稳定性变坏
        R: 测量噪声,R增大,动态响应变慢,收敛稳定性变好
        其中p的初值可以随便取,但是不能为0(为0的话卡尔曼滤波器就认为已经是最优滤波器了)
  q,r的值需要我们试出来,讲白了就是(买的破温度计有多破,以及你的超人力有多强)
  r参数调整滤波后的曲线与实测曲线的相近程度,r越小越接近。
  q参数调滤波后的曲线平滑程度,q越小越平滑。
*/
//过程噪音  
#define P_Q   0.1
//测量噪声
#define M_R   0.01
float KalmanFilter(float newdata)
{
   static float lastdata=0;
   //其中p的初值可以随便取,但是不能为0(为0的话卡尔曼滤波器就认为已经是最优滤波器了)
   static float p=0.01;
   float        q = P_Q, r = M_R, kGain = 0;
       
   p = p+q;
   kGain = p/(p+r);  //卡尔曼滤波系数
   newdata = lastdata + (kGain*(newdata-lastdata));
   p = (1-kGain)*p;
   lastdata = newdata;  
   return newdata;
}






使用特权

评论回复
沙发
中国龙芯CDX| | 2024-9-18 12:40 | 只看该作者
一阶滤波都有哪些优势以及方法?

使用特权

评论回复
板凳
jtracy3| | 2024-10-3 07:59 | 只看该作者
与移动平均类似,但给予最近的采样值更高的权重。需要注意权重分配的合理性,以及可能的延时问题。

使用特权

评论回复
地板
backlugin| | 2024-10-3 09:20 | 只看该作者
滤波算法需要满足系统的实时性要求,不能占用过多的CPU时间。

使用特权

评论回复
5
rosemoore| | 2024-10-3 10:41 | 只看该作者
对于变化较为缓慢的数据如温度、物体的位置等,可以选用限幅滤波法;而对于需要去除高频噪声的情况,可以选择低通滤波器。

使用特权

评论回复
6
sdlls| | 2024-10-3 11:52 | 只看该作者
一些滤波算法如递推平均滤波法和中位值平均滤波**占用较多的RAM,因此在资源有限的单片机系统中需要特别考虑这一点。

使用特权

评论回复
7
claretttt| | 2024-10-3 13:09 | 只看该作者
在设计滤波算法时,要考虑单片机系统的抗干扰能力。可以通过增加硬件滤波电路、优化软件算法等方式提高系统的抗干扰能力。

使用特权

评论回复
8
yorkbarney| | 2024-10-3 14:44 | 只看该作者
滤波参数的选择直接影响滤波效果。例如,在滑动平均滤波法中,需要确定窗口大小;在中值滤波法中,需要确定滤波点数。

使用特权

评论回复
9
gygp| | 2024-10-3 16:23 | 只看该作者
移动平均滤波会引入延时,且对于快速变化的信号可能不适用。

使用特权

评论回复
10
sanfuzi| | 2024-10-3 19:42 | 只看该作者
在进行滤波运算时,要注意数值稳定性,避免出现溢出或精度损失等问题。可以使用定点数运算代替浮点数运算,以提高运算效率。

使用特权

评论回复
11
lzmm| | 2024-10-4 13:52 | 只看该作者
滤波算法的效果往往与硬件电路的设计密切相关。在设计电路时,要考虑信号的输入输出方式、电源稳定性等因素,以提高滤波效果。

使用特权

评论回复
12
plsbackup| | 2024-10-4 15:31 | 只看该作者
不同的滤波算法有不同的适用场景和优缺点。例如,一阶滞后滤波算法适合用于滤除高频噪声,而算术平均滤波适合用于滤除随机噪声。

使用特权

评论回复
13
rosemoore| | 2024-10-4 17:15 | 只看该作者
结合两种或多种滤波方法的优点,如结合低通滤波和高通滤波。需要注意各滤波器参数的协调和整体性能。

使用特权

评论回复
14
uytyu| | 2024-10-4 18:53 | 只看该作者
根据实际信号的特点调整滤波器参数,以达到最佳滤波效果。

使用特权

评论回复
15
plsbackup| | 2024-10-4 20:30 | 只看该作者
了解噪声的特性和来源,选择最适合的滤波算法来抑制噪声。

使用特权

评论回复
16
chenci2013| | 2024-10-4 22:07 | 只看该作者
对于一些实时性要求较高的应用,滤波算法的计算速度和响应速度也是需要考虑的重要因素。

使用特权

评论回复
17
lzmm| | 2024-10-5 09:29 | 只看该作者
滤波算法的计算量大小不一,对于资源有限的单片机来说,需要特别注意滤波算法的计算资源消耗。

使用特权

评论回复
18
plsbackup| | 2024-10-5 11:03 | 只看该作者
滤波算法在长时间运行中保持稳定,不会因为累积误差而导致性能下降。

使用特权

评论回复
19
chenci2013| | 2024-10-5 12:39 | 只看该作者
在限幅滤波法中,需要根据被测对象的具体情况设定合适的门限值A;在算术平均滤波法和递推平均滤波法中,需要选择合适的N值以平衡信号平滑度和灵敏度。

使用特权

评论回复
20
modesty3jonah| | 2024-10-5 14:25 | 只看该作者
有时候单一的滤波算法可能无法满足所有需求,可以尝试结合多种滤波算法来达到更好的效果。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

1649

帖子

1

粉丝