单片机ADC采样算法----卡尔曼滤波
关于卡尔曼滤波,看看百度百科上的定义
算法的核心思想是,根据当前的仪器"测量值" 和上一刻的 "预测量" 和 "误差",计算得到当前的最优量. 再 预测下一刻的量, 里面比较突出的是观点是. 把误差纳入计算, 而且分为预测误差和测量误差两种.通称为 噪声. 还有一个非常大的特点是,误差独立存在, 始终不受测量数据的影响。
下来先了解一个卡尔曼滤波中几个参数的含义:概率(Probability),随即变量(Random Variable),高斯或正态分配(Gaussian Distribution)还有State-space Model等等。
关于卡尔曼公式的含义及推导,网上已经有很多文章了,这里不在赘述,直接看C代码的实现。
/*R值固定,Q值越大,代表越信任测量值,Q值无穷大,代表只用测量值。Q值越小,代表越信任模型预测值,Q值为0,代表只用模型预测值。
*/
//参数一
float KalmanFilter( float 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; //返回估计值
}
现在测试一下卡尔曼滤波的效果,通过函数发生器产生一个锯齿波,送到单片机的AD口,单片机读取采集到的AD数据后,经过卡尔曼滤波算法,然后将采样的数据和滤波后的数据通过串口发生出来,并在串口波形显示软件上显示。
void main( void )
{while( 1 ){val1 = ReadVol_CH3(); //读取AD采样数据dat = ( float )val1;dat = KalmanFilter( dat ); //卡尔曼滤波printf("A%d\r\n",val1); //打印结果printf("B%2f\r\n",dat);}
}
现在看一下滤波的结果
蓝色曲线为原始采样的数据曲线,橙色曲线为经过卡尔曼滤波后的曲线。
下面改变Q和R的值在测试一下滤波效果。
修改后的参数如下
//参数二
unsigned long kalman_filter( unsigned long ADC_Value )
{float LastData;float NowData;float kalman_adc;static float kalman_adc_old = 0;static float P1;static float Q = 0.0003;static float R = 5;static float Kg = 0;static float P = 1;NowData = ADC_Value;LastData = kalman_adc_old;P = P1 + Q;Kg = P / ( P + R );kalman_adc = LastData + Kg * ( NowData - kalman_adc_old );P1 = ( 1 - Kg ) * P;P = P1;kalman_adc_old = kalman_adc;return ( unsigned long )( kalman_adc );
}
测试波形
蓝色曲线为原始采样的数据曲线,橙色曲线为经过卡尔曼滤波后的曲线。
和第一次测试的波形图对比后可以发现,第二次经过卡尔曼滤波后的波形变化非常大,参数改变后锯齿波被滤成接近于直线了。
可以看到不同的R、Q值会对测量结果有很大的影响。
Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏
R:测量噪声,R增大,动态响应变慢,收敛稳定性变好
具体各个参数的如何选择,只有在应用中根据测量结果,自己慢慢调整。目前还没有找到权威的资料来讲解这些参数如何选择。
单片机ADC采样算法----卡尔曼滤波相关推荐
- 单片机ADC采样算法----递推平均值采样法
在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...
- c语言adc采集取平均值,单片机ADC采样算法----递推平均值采样法
在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...
- 单片机ADC采样算法----一阶低通滤波
关于低通滤波,先看一下百度百科上的定义. 算法实现的公式如下: y(n) = q*x(n) + (1-q)*y(n-1) 其中Y(n)为输出,x(n)为输入,y(n-1)为上一次输出值,其中 ...
- 单片机ADC采样算法----平均值采样法
单片机在模拟电路中使用的时候,经常需要用到AD功能,而通过单片机ADC采集回来的数据往往不能直接使用,在不同场合下需要对采集到的数据要通过不同的算法对数据进行处理,先来看看最简单的平均值采样法. 平均 ...
- 单片机ADC采样算法----有效值采样法
在使用单片机ADC功能采样数据时,通常情况下用平均值计算就够了,但是在计算功率时就需要用有效值来计算真正做功的情况.如果是标准的正弦波的话,正弦波的峰值是有效值得1.414倍,可以通过峰值来计算有效值 ...
- 单片机ADC采样算法----限幅消抖滤波法
限幅消抖滤波法相当于"限幅滤波法"+"消抖滤波法" . 下面直接看C代码的实现 #define A 200 #define N 20 //返回两个整数差 ...
- 单片机ADC采样算法----消抖滤波法
消抖滤波法的实现步骤为:设置一个滤波计数器,将每次采样值与当前有效值比较,如果采样值等于当前有效值,则计数器清零.如果采样值不等于当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出),如 ...
- 单片机ADC采样算法----加权递推平均滤波法
加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权.通常是,越接近现时刻的数据,权取得越大.给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低. 下面直接看C代码的实现 d ...
- 单片机ADC采样算法----限幅平均滤波法
限幅平均滤波法相当于"限幅滤波法"+"递推平均滤波法",每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理. 下面看C代码的实现 #define ...
最新文章
- ThinkPHP5.1接收post、get参数
- tomcat服务器配置及加固
- python正则group()的用法—正则提取括号内以及其他符号内内容
- hdu 1723(简单dp)
- gj13 asyncio并发编程
- docker下交叉编译环境配置
- JavaScript中的一些特殊用法(一)
- jqueryd登录异步请求 java,ajaxd的js和jquery实现
- Android RecyclerView加载复杂布局
- 行为型设计模式(1)—— 责任链模式(Chain of Responsibility Pattern)
- 16. CSS 轮廓
- nginx常用配置模板
- 学习PMbok对pmp考试的认知理解和itto输入输出的整理笔记
- Ubuntu中vim脚本保存失败,E45错误提示。
- (随笔)区块链是什么??
- 100种网站推广方法全集
- mysql联合主键意义_mysql设置联合主键的意义
- Android API统计
- Web必备性能压力测试工具WebBench与ApcheBench(ab)详解
- endnote 使用方法
热门文章
- 创建ASPState数据库
- NET2.0配置文件加密(WEBWindows)
- django之关系及查询,数据类型,约束,分页
- 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借助TopSelf、服务类】)【转载】...
- 数据结构——平衡二叉树
- Git学习笔记(四)
- 0804------算法笔记----------最长公共子序列
- android获取手机的IMSI码
- linux中python进程,如何检查进程在python中运行(在linux中)?
- 07-02 测试报告-allure