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

news/2024/10/30 15:46:02/

就是比如,用电位器当旋钮做风扇调速,划分出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 必须连续多次采样都跳出了当前档位。也可以叫做弹性吧,一松手就回去了。这和按键消抖的算法差不多,就不写例子了。


http://www.ppmy.cn/news/445429.html

相关文章

计算机网络面试

计算机网络面试 OSI七层模型 七层网络体系结构各层的主要功能: 应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等。表示层:主要负责数据格式的转换,如加密解密、转换翻译、压缩解压缩等。…

谷歌手机号无法验证

改用谷歌浏览器 在谷歌浏览器的设置里面找到语言设置&#xff0c;更改成英语&#xff08;美国&#xff09;

【其他】如何注册谷歌账号,遇到“此电话号码无法用于进行验证”怎么办?

如何注册谷歌账号&#xff0c;遇到“此电话号码无法用于进行验证”怎么办 注&#xff1a;经测试成功&#xff0c;需要把google浏览器的语言设置成英文&#xff08;美国&#xff09;&#xff0c;且保留这一项。 是否可以保留中文&#xff0c;暂时未做测试。

关于Google大陆手机号不能验证的问题

在浏览器上注册。 一、选择一个合适的工具与浏览器。 二、清除浏览器缓存。 三、将浏览器语言更改为English&#xff0c;重启浏览器。 四、正常注册。

谷歌创建新账号时手机号码无法验证

关于新建谷歌账号时&#xff0c;出现手机号码无法验证问题的解决方案&#xff01;&#xff01;&#xff01;&#xff01; 直接在手机号码键入框内键入&#xff1a; 86 手机号码 例如&#xff1a;86 1xxxxxxxxxx 注意事项&#xff1a;1、数字6之后加一个空格再输入手机号码

在chrome上,谷歌账号无法登陆的解决办法

找到chrome安装目录&#xff0c;找到chrome_proxy.exe 打开&#xff0c;就能解决问题

注册gmail账号,手机无法接受验证码的问题

有时候需要使用到gmail账号来进行一些工作&#xff0c;发现直接注册会卡在手机验证码那一步无法继续进行下去。百度了一些资料发现一个切实可行的方法。 以chrome浏览器为例&#xff0c;将语言设置成English&#xff0c;然后再重新进行注册就可以接收到验证码了。

谷歌邮箱此号码无法用于验证

注册谷歌邮箱在手机验证码这一步的时候&#xff0c;使用86(国内)地区手机号会提醒此号码无法用于验证