Hi,大家好!又跟大家见面啦!在上一次讲解按键开关临近结束的时候,我们提到在正常的使用过程中,美中有不足,按键开关还有一个小问题需要解决。那是什么问题呢?
每当你按下或抬起按键开关的一瞬间,由于读取信号的操作是持续进行的,又由于按键自身的物理元器件的问题,每次触碰的一瞬间,可能会发生多次短暂的物理接触,以至于最终产生的信号发生了抖动。为了消除这种抖动,让按键变得更加好用,这次我们一起来试试看如何解决这个问题!这一次的学习过程中,我们用到了之前在《另一种时间延迟》中学过的知识点。如果你对此还有印象,那将会对这一次的学习有很大的帮助呢!
好!介绍的差不多了。还是老环节,先准备一下我们需要的材料。
硬件方面
图片来源:Arduino电路配件
具体包括如下:
- Arduino UNO电路板(1块)
- 面包板(1块)
- 10k电阻(1个)
- 按键开关(1个)
- 面包线(3根)
咦?是不是看起来很像上一次在《按键开关》那一节中所使用的硬件啊!哼哼!其实不单是硬件用的一样,连电路的连接也是一摸一样呢!同样的,这次我们对按键测试所使用的LED神灯,用的还是Arduino UNO电路板上自带的那一盏!
软件方面不多说,依然是Arduino官方提供的IDE。
连接电路
图片来源:Arduino连接开关按键电路示意图
既然和上一次的电路连接一样,就不多啰嗦了,我们直接进入最后一步!
添加几行代码首先,还是新建一个项目窗口。
图片来源:Arduino官方IDE
然后向其中添加如下代码:
- // 定义按键输入针脚号常量,
- // 并初始化为2号针脚。
- const int buttonPin = 2;
- // 定义LED输入针脚号常量,
- // 并初始化为13号针脚。
- // 注:此处我们使用的LED神灯是Arduino UNO电路板自带,
- // 此神灯对应的针脚号默认为13,此数值不得随意更改,
- // 所以这里定义的数值13是为了和默认值相对应。
- const int ledPin = 13;
- // 定义记录LED神灯当前状态的变量,
- // 并初始化状态为HIGH。
- int ledState = HIGH;
- // 定义记录按键当前状态的变量
- int buttonState;
- // 定义记录按键最近一次状态变化的变量,
- // 并初始化状态为LOW。
- int lastButtonState = LOW;
- // 定义记录最近一次抖动的时间变量,
- // 并初始化时间为0毫秒。
- long lastDebounceTime = 0;
- // 定义延迟抖动的时间变量,
- // 并初始化为50毫秒。
- long debounceDelay = 50;
- // 对Arduino电路板或相关状态进行初始化方法
- void setup() {
- // 设置按键的针脚为输入状态
- pinMode(buttonPin, INPUT);
- // 设置电路板上LED神灯的针脚状态为输出状态
- pinMode(ledPin, OUTPUT);
- // 设置电路板上LED神灯的初始状态,
- // 此处因为变量ledState的初始状态为HIGH,
- // 所以LED神灯的初始状态为亮。
- digitalWrite(ledPin, ledState);
- }
- // 系统调用,无限循环方法
- void loop() {
- // 读取按键的状态
- int reading = digitalRead(buttonPin);
- // 判断当前的按键状态是否和之前有所变化
- if (reading != lastButtonState) {
- // 如果按键发生了变化,
- // 则重新设置最近一次抖动的时间。
- lastDebounceTime = millis();
- }
- // 判断按键按下或抬起的状态时间间隔是否大于延迟抖动的时间长度。
- // 方法millis()可以获取当前时间,单位统一为毫秒。
- if ((millis() - lastDebounceTime) > debounceDelay) {
- // 判断当前的按键状态是否和之前有所变化
- if (reading != buttonState) {
- // 如果发生了变化,
- // 则更新按键状态变量。
- buttonState = reading;
- // 判断按键的状态是否为按下,
- // 只有在按键按下的时候,
- // 才改变LED神灯的状态。
- if (buttonState == HIGH) {
- // 如果LED神灯当前为亮度,
- // 则变为灭。如果为灭,
- // 则变为亮。
- ledState = !ledState;
- }
- }
- }
- // 最终改变电路板上LED神灯的状态
- digitalWrite(ledPin, ledState);
- // 更新按键最近一次状态变化的变量
- lastButtonState = reading;
- }
复制代码
好!总共的代码就是酱紫!看起来有些长呢!其实也只是看起来而已啦!老实说这里并没有出现任何新的面孔,唯一看起来有点绕的,就是对时间延迟的控制。如果觉得有些吃力,可以回顾一下《另一种时间延迟》小节所学的内容。之所以能够最终解决抖动问题,其实就是通过加入时间延迟来解决的。通过延长按键状态改变的时间长度,来最终消除信号的抖动。
图片来源:Arduino官方IDE的文件编辑菜单选项
点击上图中标有向右指向的箭头图标,将代码一键烧入Arduino UNO电路板。现在试试看,每次单击按键,电路板上的LED神灯会不会有所变化?如果一切正常,现在每单击一下按键,LED神灯的状态就会变化一次。在《按键开关》那一节,是每次按下按键,点亮LED神灯。抬起按键,LED神灯熄灭。而现在是每单击一次按键,LED神灯变化一次。可以体会一下它们之间的不同。
总结通过这次学习,我们解决了按键的信号抖动的问题。解决的核心方法呢,是通过引入时间延迟,来消除信号抖动。技术来说并没有碰到新内容,难点就在于对时间延迟的理解。
下期预告通过前两次学习,我们发现每次连接按键总要外加一个10k的电阻。在电路合理连接的情况下,能不能不引入电阻,直接就能使用按键呢!好!下一次,我们将一起学习一种如何不用外接电阻,也能正常使用按键的方法!
ohcoder的系列精彩Arduino教程:
Arduino教程-初识Arduino(包含本教程目录):http://www.51hei.com/bbs/dpj-41334-1.html
Arduino教程-开篇:http://www.51hei.com/bbs/dpj-41335-1.html
Arduino教程-点亮LED神灯:http://www.51hei.com/bbs/dpj-41336-1.html
Arduino教程-让LED神灯闪烁:http://www.51hei.com/bbs/dpj-41337-1.html
Arduino教程-让LED神灯亮度渐变:http://www.51hei.com/bbs/dpj-41338-1.html
Arduino教程-获取输入数字信号:http://www.51hei.com/bbs/dpj-41339-1.html
Arduino教程-获取输入模拟信号:http://www.51hei.com/bbs/dpj-41340-1.html
Arduino教程-另一种时间延迟:http://www.51hei.com/bbs/dpj-41331-1.html
Arduino教程-按键开关:http://www.51hei.com/bbs/dpj-41341-1.html
Arduino教程-停止抖动!:http://www.51hei.com/bbs/dpj-41333-1.html
Arduino教程-抛弃外部电阻!:http://www.51hei.com/bbs/dpj-41332-1.html
Arduino教程-用按键开关计数:http://www.51hei.com/bbs/dpj-41330-1.html
………后续持续更新中请打开:http://www.51hei.com/bbs/dpj-41334-1.html
|