ADC常用的十大滤波算法(C语言)

一、限幅滤波法

1、方法:

  • 根据经验判断两次采样允许的最大偏差值(设为A)

  • 每次检测到新值时判断:

a. 如果本次值与上次值之差<=A,则本次值有效

b. 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值

2、优点:

  • 能有效克服因偶然因素引起的脉冲干扰

3、缺点

  • 无法抑制那种周期性的干扰

  • 平滑度差

/* A值根据实际调,Value有效值,new_Value当前采样值,程序返回有效的实际值 */
#define A 10
char Value;
char filter()
{char new_Value;new_Value = get_ad(); // 获取采样值if( abs(new_Value - Value) > A)   return Value;     // abs()取绝对值函数return new_Value;
}

二、中位值滤波法

1、方法:

  • 连续采样N次(N取奇数),把N次采样值按大小排列

  • 取中间值为本次有效值

2、优点:

  • 能有效克服因偶然因素引起的波动干扰

  • 对温度、液位的变化缓慢的被测参数有良好的滤波效果

3、缺点:

  • 对流量、速度等快速变化的参数不宜

#define N 11
char filter()
{char value_buf[N];char count, i, j, temp;for(count = 0; count < N; count ++) //获取采样值{value_buf[count] = get_ad();delay();}for(j = 0; j < (N-1); j++){for(i = 0; i < (n-j); i++){if(value_buf[i] > value_buf[i+1]){temp = value_buf[i];value_buf[i] = value_buf[i+1];value_buf[i+1] = temp;}}}return value_buf[(N-1)/2];
}

三、算术平均滤波法

1、方法:

  • 连续取N个采样值进行算术平均运算

  • N值较大时:信号平滑度较高,但灵敏度较低

  • N值较小时:信号平滑度较低,但灵敏度较高

  • N值的选取:一般流量,N=12;压力:N=4

2、优点:

  • 适用于对一般具有随机干扰的信号进行滤波

  • 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动

3、缺点:

  • 对于测量速度较慢或要求数据计算速度较快的实时控制不适用

  • 比较浪费RAM

#define N 12
char filter()
{int sum = 0;for(count = 0; count < N; count++){sum += get_ad(count);} return (char)(sum/N);
}

四、递推平均滤波法

1、方法:

  • 把连续取N个采样值看成一个队列

  • 队列的长度固定为N

  • 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)

  • 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果

  • N值的选取:流量,N=12;压力:N=4;液面,N=4 ~ 12;温度,N=1 ~ 4

2、优点:

  • 对周期性干扰有良好的抑制作用,平滑度高

  • 适用于高频振荡的系统

3、缺点:

  • 灵敏度低

  • 对偶然出现的脉冲性干扰的抑制作用较差

  • 不易消除由于脉冲干扰所引起的采样值偏差

  • 不适用于脉冲干扰比较严重的场合

  • 比较浪费RAM

#define N 10u16 value_buf[N];
u16 sum=0;
u16 curNum=0;u16 moveAverageFilter()
{if(curNum < N){value_buf[curNum] = getValue();sum += value_buf[curNum];curNum++;return sum/curNum;}else{sum -= sum/N;sum += getValue();return sum/N;}
}

五、中位值平均滤波法

1、方法:

  • 相当于“中位值滤波法”+“算术平均滤波法”

  • 连续采样N个数据,去掉一个最大值和一个最小值

  • 然后计算N-2个数据的算术平均值

  • N值的选取:3~14

2、优点:

  • 融合了两种滤波法的优点

  • 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差

3、缺点:

  • 测量速度较慢,和算术平均滤波法一样

  • 比较浪费RAM

char filter()
{char count, i, j;char Value_buf[N];int sum = 0;for(count = 0; count < N; count++){Value_buf[count] = get_ad();} for(j = 0; j < (N-1); j++){for(i = 0; i < (N-j); i++){if(Value_buf[i] > Value_buf[i+1]){temp = Value_buf[i];Value_buf[i] = Value_buf[i+1];Value_buf[i+1] = temp;}}  }    for(count = 1; count < N-1; count ++){sum += Value_buf[count];}return (char)(sum/(N-2));
}

六、限幅平均滤波法

1、方法:

  • 相当于“限幅滤波法”+“递推平均滤波法”

  • 每次采样到的新数据先进行限幅处理,

  • 再送入队列进行递推平均滤波处理

2、优点:

  • 融合了两种滤波法的优点

  • 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差

3、缺点:

  • 比较浪费RAM

#define A 10
#define N 12
char value, i = 0;
char value_buf[N];
char filter()
{char new_value, sum = 0;new_value = get_ad();if(Abs(new_value - value) < A)  value_buf[i++] = new_value;if(i==N)  i=0;for(count = 0; count < N; count++){sum += value_buf[count];}return (char)(sum/N);
}

七、一阶滞后(低通)滤波法

1、方法:

  • 取a=0~1

  • 本次滤波结果=(1-a)本次采样值+a上次滤波结果

2、优点:

  • 对周期性干扰具有良好的抑制作用

  • 适用于波动频率较高的场合

3、缺点:

  • 相位滞后,灵敏度低

  • 滞后程度取决于a值大小

  • 不能消除滤波频率高于采样频率的1/2的干扰信号

/*为加快程序处理速度,取a=0~100*/
#define a 30
char value;
char filter()
{char new_value;new_value = get_ad();return ((100-a)*value + a*new_value);
}

八、加权递推平均滤波法

1、方法:

  • 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权

  • 通常是,越接近现时刻的数据,权取得越大。

  • 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低

2、优点:

  • 适用于有较大纯滞后时间常数的对象

  • 和采样周期较短的系统

3、缺点:

  • 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号

  • 不能迅速反应交易系统当前所受干扰的严重程度,滤波效果差

/* coe数组为加权系数表 */
#define N 12
char code coe[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
char code sum_coe = (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12);
char filter()
{char count;char value_buf[N];int sum = 0;for(count = 0; count < N; count++){value_buf[count] = get_ad();}for(count = 0; count < N; count++){sum += value_buf[count] * coe[count];} return (char)(sum/sum_coe);
}

九、消抖滤波法

1、方法:

  • 设置一个滤波计数器

  • 将每次采样值与当前有效值比较:

  • 如果采样值=当前有效值,则计数器清零

  • 如果采样值>或<当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)

  • 如果计数器溢出,则将本次值替换当前有效值,并清计数器

2、优点:

  • 对于变化缓慢的被测参数有较好的滤波效果,

  • 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动

3、缺点:

  • 对于快速变化的参数不宜

  • 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入交易系统

#define N 12
char filter()
{char count = 0, new_value;new_value = get_ad();while(value != new_value){count++;if(count >= N) return new_value;new_value = get_ad();}return value;
}

十、限幅消抖滤波法

1、方法:

  • 相当于“限幅滤波法”+“消抖滤波法”

  • 先限幅,后消抖

2、优点:

  • 继承了“限幅”和“消抖”的优点

  • 改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统

3、缺点:

  • 对于快速变化的参数不宜

#define A 10
#define N 12
char value;
char filter()
{char new_value, count = 0;new_value = get_ad();while(value != new_value){if(Abs(value - new_value) < A){count++;if(count >= N) return new_value;new_value = get_ad();}return value;}
}

 附录:

1、FIR滤波

FIR有限长滤波器,有限长指的是滤波器的脉冲响应为有限长的序列

输入X经过滤波器H得到滤波后的输出Y

表达成差分方程形式就是:

使用不同的窗函数会有不同的滤波性能(衰减程度和过渡带大小的不一样)

窗函数的介绍以及画出常见窗函数(汉宁窗,矩形窗,汉明窗,布莱克曼窗)的时域图和频谱图-CSDN博客


参考链接:https://blog.csdn.net/weixin_59250390/article/details/134329056

参考代码:

#include <stdlib.h>
#include <math.h>// FIR低通滤波器设计函数
void fir_lowpass(float *input, float *output, int N, float cutoff_freq, float sample_freq) {int i, j;float *b;b = (float *)malloc((N + 1) * sizeof(float));// 设计滤波器系数b[n]float N_normalized = (N - 1) / 2.0;for (i = 0; i < N + 1; i++) {b[i] = (float)(sin(cutoff_freq * 2 * M_PI / sample_freq * (i - N_normalized)) / (i - N_normalized));}// 滤波器滤波float acc = 0.0;for (i = 0; i < N; i++) {acc += input[i] * b[N - i];}output[0] = acc;for (j = 1; j < N; j++) {acc -= input[j - 1] * b[N + 1 - j];acc += input[j + N - 1] * b[N - j];output[j] = acc;}free(b);
}int main() {int N = 10; // 滤波器阶数float cutoff_freq = 0.3; // 截止频率(0.3 * 采样频率)float sample_freq = 1.0; // 采样频率float input[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 输入数据float output[N]; // 输出数据fir_lowpass(input, output, N, cutoff_freq, sample_freq);// 打印输出for (int i = 0; i < N; i++) {printf("%.2f ", output[i]);}return 0;
}

2、卡尔曼滤波

卡尔曼滤波算法是一种用于估计未知变量的状态的数学算法。它可以通过过滤传感器测量值,来估计出最可能的状态值。该算法最初是为航空航天应用而开发的,但现在已广泛应用于各种领域,如自动驾驶汽车、机器人、船舶控制等。卡尔曼滤波算法基于状态空间模型,其中包含系统的状态、测量值和控制输入。利用贝叶斯定理和高斯分布等概率统计学原理,卡尔曼滤波算法可以计算出最优状态估计值和协方差矩阵,从而实现对系统状态的精确估计和预测。
该算法具有高精度、快速收敛、自适应性强等优点,是一种非常有效的状态估计算法。

参考代码:

#include <stdio.h>// 卡尔曼滤波器结构体
typedef struct {float x;          // 状态变量float p;          // 状态误差协方差矩阵float q;          // 过程噪声协方差float r;          // 测量噪声协方差float h;          // 测量矩阵float k;          // 卡尔曼增益float y;          // 测量值
} KalmanFilter;// 卡尔曼滤波器更新函数
void kalmanFilterUpdate(KalmanFilter *kf, float measurement) {kf->y = measurement - kf->h * kf->x;            // 测量更新kf->p = kf->h * kf->p * kf->h->transpose() + kf->r; // 预测误差更新kf->k = kf->p * kf->h->transpose() / (kf->h * kf->p * kf->h->transpose() + 1.0f); // 卡尔曼增益计算kf->x = kf->x + kf->k * kf->y;                  // 状态更新kf->p = (1.0f - kf->k) * kf->p;                 // 预测误差新值
}int main() {KalmanFilter filter;filter.x = 0.0f;filter.p = 1.0f;filter.q = 1e-5f;filter.r = 1.0f;filter.h = 1.0f;float measurement = 1.0f; // 假设的测量值kalmanFilterUpdate(&filter, measurement);printf("状态变量: %f\n", filter.x);printf("状态误差协方差矩阵: %f\n", filter.p);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/31252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT MQTT (二)编译与集成

一、QT MQTT 提供 MQTT 客户端服务的 Qt 专用库基于标准化发布 / 订阅协议&#xff0c;用于在设备和组件之间可靠地共享数据。MQTT 是为保证状态正确性、满足高安全标准和交换最小数据而设计的协议&#xff0c;因此被广泛应用于各种分布式系统和物联网解决方案中。 Qt开发MQT…

【Oracle篇】Oracle数据库坏块处理:rman修复坏块实践与案例分析(第七篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

git配置ssh key

一、生成ssh公钥和私钥对 打开终端&#xff0c;输入命令&#xff0c;-C 后是git邮箱&#xff0c;在 Enter file in which to save the key (/home/my/.ssh/id_rsa): 后可以输入公钥和私钥对保存路径及文件名&#xff0c;默认是 /home/my/.ssh/id_rsa&#xff0c;其它的全部按回…

从0开始C++(五):友元函数运算符重载

友元函数 介绍 C中的友元函数是一种特殊的函数&#xff0c;它可以访问和操作类的私有成员和保护成员。友元函数可以在类的内部或外部声明和定义&#xff0c;但在其声明和定义中需要使用关键字 friend 来标识。友元函数可以是全局函数&#xff0c;也可以是其他类的成员函数。 …

Web APIs--Dom获取属性操作

目录 1.DOM&#xff08;操作网页内容、用户交互&#xff09; 2.DOM对象获取&#xff08;querySelect(‘’)、querySelectAll(‘’)&#xff09; 总结&#xff1a; 3.操作元素内容&#xff08;修改元素的文本更换内容&#xff09; 1. 元素innerText 属性 2.元素.innerHTML…

第一百一十六节 Java 面向对象设计 - Java 终止块

Java 面向对象设计 - Java 终止块 ​try ​块也可以有零个或一个​ finally​ 块。 ​finally ​块总是与 ​try ​块一起使用。 语法 使用 ​finally​ 块的语法是 finally {// Code for finally block }​finally​ 块以关键字 ​finally​ 开始&#xff0c;后面紧跟一对…

深入分析 Android BroadcastReceiver (四)

文章目录 深入分析 Android BroadcastReceiver (四)1. 广播接收器的深入优化与应用1.1 实时性要求高的应用1.1.1 示例&#xff1a;音乐播放器中处理耳机插拔事件1.1.2 动态注册接收器 1.2 处理耗时操作1.2.1 示例&#xff1a;使用 IntentService 处理耗时操作 1.3 安全性管理1.…

【机器学习】深度学习赋能:基于 LSTM 的智能日志异常检测

目录 1. LSTM 简介 2. 日志序列异常检测概述 3. 数据预处理 3.1 日志解析 3.2 数据清洗 3.3 序列化 3.4 特征提取 示例代码 4. 构建 LSTM 模型 4.1 模型结构 4.2 模型构建示例 5. 训练 LSTM 模型 5.1 数据准备 5.2 模型训练 示例代码 6. 异常检测 6.1 异常分数…

处理文本内容的命令和正则表达式

处理文本内容的命令 正则表达式匹配的是文本内容&#xff0c;linux的文本三剑客 都是针对文本内容 文本三剑客&#xff1a; grep 过滤文本内容 sed 针对文本内容进行增删改查 awk 按行取列 文本三剑客都是按行进行匹配。 grep grep的作用就是使用正则表达式来匹配文本内…

虚拟现实环境下的远程教育和智能评估系统(十一)

视频帧画面知识点区域划分 知识点区域精确分割技术: 在深度学习检测模型结果基础上使用基于交并比&#xff08;IoU&#xff09;阈值的目标合并算法&#xff0c;合并过度重合目标区域面积&#xff0c;实现知识点区域精确分割 多模态知识点内容匹配策略: 图像&#xff1a;利用…

【第18章】Vue实战篇之登录界面

文章目录 前言一、数据绑定1. 数据绑定2. 数据清空 二、表单校验1. 代码2. 展示 三、登录1.登录按钮2.user.js3. login 四、展示总结 前言 上一章完成用户注册&#xff0c;这一章主要做用户登录。 一、数据绑定 登录和注册使用相同的数据绑定 1. 数据绑定 <!-- 登录表单 -…

紧凑型计算微型仿生复眼

欢迎关注&#xff1a;GZH《光场视觉》 图1 研制的计算微型复眼的成像原理 1. 导读 微型曲面复眼由于具有大视场成像、大景深成像、体积较小的优势&#xff0c;在机器视觉、无人机导航、生物灵感机器人等领域引起了广泛关注。然而&#xff0c;传统的微型曲面复眼存在设计/加工…

HTTP详细总结

概念 HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 特点 基于TCP协议: 面向连接&#xff0c;安全 TCP是一种面向连接的(建立连接之前是需要经过三次握手)、可靠的、基于字节流的传输层通信协议&#xff0c;在…

SpringMvc—域对象共享数据和视图

一、向request域创建对象 先创建首页&#xff1a; 在testController这个类中&#xff1a; package com.pon.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; Controller public class test…

后台管理系统登录业务分析(图片验证码登录)

文章目录 1、登录业务分析2、登录开发流程2.1、获取图片验证码接口业务2.2、CodeImgServiceImpl2.2.1、响应 2.3、IndexController2.4、SysUserServiceImpl2.5、SysUserMapper.xml 3、springmvc拦截器创建&注册3.1、springmvc拦截器的创建3.2、springmvc拦截器注册3.3、Sys…

【Oracle APEX开发小技巧1】转换类型实现显示小数点前的 0 以 及常见类型转换

在 apex 交互式式网格中&#xff0c;有一数值类型为 NUMBER&#xff0c;保留小数点后两位的项&#xff0c;在 展示时小数点前的 0 不显示。 效果如下&#xff1a; 转换前&#xff1a; m.WEIGHT_COEFFICIENT 解决方案&#xff1a; 将 NUMBER&#xff08;20&#xff0c;2&#xf…

Vue 自定义ElementUI的Loading效果

import { loadingText, messageDuration } from "/settings";import { Loading } from "element-ui"; // loadingText、messageDuration 这两个参数我是调的公共配置文件,按自己需求来 const install (Vue, opts {}) > {/* 全局多彩Loading加载层 *…

cpolar:通过脚本自动更新主机名称和端口号进行内网穿透【免费版】

cpolar 的免费版经常会重新分配 HostName 和 Port&#xff0c;总是手动修改太过麻烦&#xff0c;分享一下自动更新配置文件并进行内网穿透的方法。 文章目录 配置 ssh config编写脚本获取 csrf_token打开登陆界面SafariChrome 设置别名 假设你已经配置好了服务器端的 cpolar。 …

Spring AI 调用 openAI 进行语音识别

Spring AI支持语音识别功能&#xff0c;目前仅支持OpenAI的Transcription模型。 项目搭建&#xff1a; 参考 Spring AI 介绍以及与 Spring Boot 项目整合 源码示例&#xff1a; RestController RequestMapping("/openai") public class OpenAiIAudioTranscriptionC…

1964springboot VUE 智慧社区可视化平台系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE社区可视化平台系统是一套完善的完整信息管理类型系统&#xff0c;结合springboot框架和VUE完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码…