ADC 读取电位器旋钮,用回差消除临界值档位跳动

2023-10-29 02:59

本文主要是介绍ADC 读取电位器旋钮,用回差消除临界值档位跳动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

就是比如,用电位器当旋钮做风扇调速,划分出10 个速度档位,对应10 个ADC 转换结果的阈值。如果直接比较阈值,当旋钮拧到临近阈值的地方时,ADC 结果的微小跳动会导致风扇档位在两个级别之间不停左右横跳,因此想到了利用回差来消除抖动。

回差原理

原理很简单,类似拿运放正反馈当迟滞比较器。如果只有两个档位,阈值是500,超过500 是2 档,低于500 是1 档,回差数值是100。那么如果当前位于1 档,电位器往大拧,想要调到2 档,ADC 的值要大于500 + 100 = 600。而如果当前位于2 档,要降回1 档,ADC 的值要小于500 - 100 = 400。

也就是说,阈值是动态的,和当前的位置有关。如果ADC 的值刚好是601,跳到了2 档,然后跳回1 档的阈值就瞬间变成了400,ADC 必须下降200 以上才能跳回1 档。同理,如果下降到400 跳回了1 档,再要到2 档就得上升200。所以只要ADC 的微小抖动范围不超过两倍回差,档位就不会跳动。其实这就是用一个区间替代了单一的阈值,然后原先跟阈值做的比较就变成了和区间上下界的比较。

在这里插入图片描述

回差实现

那么如果有很多档位,又该如何实现回差呢?也很简单,就是先保存当前的档位,判断阈值的时候,大于等于当前档位的所有阈值加上回差,小于的则减去回差,用图来表示就是下面这样:

在这里插入图片描述
图中的意思是,假设ADC 的结果最大值是2000,从0 开始,把ADC 的取值划分为四个档位,进入四个档位的阈值分别是0、500、1000、1500,如果0 < ADC < 500,就代表第一个档位。实际程序中是只用上界来判断档位的,比如:

int 阈值[] = {500, 1000, 1500};// 根据ADC 的值计算出对应的档位
int 计算档位() {for(int i = 0; i < sizeof(阈值); ++i) {if(ADC < 阈值[i]){    // 只用上界,也就是只用小于判断return i;}}return 3;
}

如果ADC 小于500,则为第0 档,否则ADC 肯定大于等于500,后面不用重复判断下界,只用接着判断ADC 是否小于1000。如果表查完了,说明ADC 大于1500,所以返回第3 档。用这种查表法的好处是:

  1. 省去复杂的乘除法。如果单片机不支持硬件直接算乘法,用查表可以省下调用乘法库函数的开销;
  2. 区间划分更灵活,可以方便的按实际需求做修正,实现不均匀的区间;
  3. 可以直观的实现回差,和上面的图对应;

也可以用累加:

int 计算档位() {int 阈值 = 500;for(int i = 0; i < 3; ++i) {if(ADC < 阈值){return i;}阈值 += 500;}return 3;
}

缺点就是不方便实现不均匀的划分。实际应用经常遇到非线性的传感元件,比如光敏或热敏电阻,可以用非线性的阈值表负负得正,给它修正成近似线性的。

然后按上面说的思路,在函数里加上对回差的处理:

int 阈值[] = {500, 1000, 1500};
int 回差 = 100;// 计算ADC 的值对应的档位,需要输入当前的档位来计算回差
int 计算档位(int current) {for(int i = 0; i < sizeof(阈值); ++i) {int r = 阈值[i];if(i >= current) { // 如果是大于等于当前档位的阈值,就加上回差r += 回差;}else {  // 否则减去回差r -= 回差;}if(ADC < r){    // 再用叠加了回差的阈值判断档位return i;}}return 3;
}

用累加法的和这个差不多,就不重复写了。

档位惯性

要是加了回差还不行,比如可能存在一些幅度较大的干扰信号,那么可以考虑再加上惯性:如果要从当前档位跳到其他档位,ADC 必须连续多次采样都跳出了当前档位。也可以叫做弹性吧,一松手就回去了。这和按键消抖的算法差不多,就不写例子了。

这篇关于ADC 读取电位器旋钮,用回差消除临界值档位跳动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/297820

相关文章

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati