Home 物联·技术 arduino 《ArduBlock玩转机器人》—按钮控制LED(下),按钮控制进阶篇
《ArduBlock玩转机器人》—按钮控制LED(下),按钮控制进阶篇

《ArduBlock玩转机器人》—按钮控制LED(下),按钮控制进阶篇

0
3

最常见的按钮控制LED,无非是按一次按钮,灯亮,再按一次按钮,灯灭,如此循环。但是,谁说就仅仅如此?

话说我们已经认识到按钮其实就是一个传感器,Arduino获取传感器的数值后,再去执行相应的动作,应该有n种形式。比如,按一下开灯,再按一下关灯;再如连续按两下开灯(所谓鼠标的双击?)按一下关灯;按的时间越久,灯就越亮……是不是很有趣?这也是我们本篇要介绍的——用ArduBlock实现复杂按钮控制。相信,学完这篇后,我们的功力就会大增的。

一、问题描述

本篇主要完成一个项目:按下按钮,LED亮,再按下按钮,LED熄灭。这个项目,新增了常量与变量,逻辑运算符里面的非运算符。为了让按钮的控制更加稳定,我们还需要了解按钮抖动的问题,通过编程优化,实现“消抖”。

二、知识介绍

1.变量和常量

变量与常量是程序编写中比较基本的数据对象。常量,顾名思义就是在程序的运行过程中都不会变化的数据,主要有数字常量、字符常量以及字符串常量等。比如下面这些:

图一

变量分为数字变量、模拟变量、字符变量、字符串变量等,ArduBlock中分别用不同的形状来表示变量。因为在这个项目中,Arduino要不断记录上次的按键状态,所以必须要用到变量。记录状态,我们使用的是数字变量。如果要记录次数,就要用模拟变量了。

图二

2.非运算符

非运算的符号是“!”,在ArduBlock里面直接写作“非”,使用了“非”以后,该语句的值与其后的表达式正好相反。例如图三,表示的是:如果数字针脚3的值为0,非0就是1,也就是真;相反如果数字针脚3的值为1,非1就是0,也就是假。

三、动手实践:按下按钮灯亮,再次按下灯灭

1.硬件搭建

硬件搭建和上篇是一样的,不再具体描述,不清楚的可以查看上篇《按钮控制入门篇》(我们是将LED接在数字针脚3,按钮接在数字针脚4号口,也可以另接)。友情提醒,按钮和LED都是数字模块,要接在数字针脚,同时注意接线次序。(黑线接GND,红线接5V,第三根线接信号针脚)。

2.程序编写

编程之前先分析一下这个项目。第一次按下按钮,LED被点亮,也就是设置LED所在的针脚值为1;第二次按下按钮,LED熄灭,即设置LED所在的针脚值为0;第三次按下按钮,LED点亮……可以列个图表,如下:

按钮状态 LED所在数字针脚数值
第一次按下 1(高电平)
第二次按下 0(低电平)
第三次按下 1(高电平)
第四次按下 0(低电平)
…… ……

通过观察可以发现,每按下一次按钮,LED的状态就会发生改变,我们可以给这个不断改变的数值设置为一个变量,比如k。因为k的值在0、1之间变化,可以在每次按钮按下的时候(读取按钮所在针脚值为1),给变量k做非运算(也就是取反,原来k的值为1,取反会变成0;k值为0,取反会变成1),再将取反以后的k值赋值给LED所在针脚。

参考程序如下:

图四

程序说明:当我们按下按钮,数字针脚4值为1,满足条件,继续往下执行,因为数字变量默认初始值为0,取反以后,k值变为1,设置数字针脚3的值为k,也就是1,LED点亮;同理,再次按下按钮,数字针脚4值为1,满足条件,往下执行。k的值原本为1,取反变成0,设置数字针脚3的值为k,也就是0,LED熄灭。 程序下载成功以后,似乎我们的LED并不那么听按钮的话,按下按钮有时LED亮,有时LED暗,毫无规律可言。为什么会这样呢? 仔细观察,你会发现按下按钮不放开的时候,LED会变暗一点。如果经过这样的提示,你还是没有想出答案,不妨再加个延时吧。看下面的程序:

图五

好了,这时就能看出,当按下按钮的时候,LED明暗交替。因为我们写在“主程序”中的代码是不断循环执行的,Arduino运行的速度太快了,如果不加延时,当按下按钮的一刹那间,程序已经跑了n次了,执行了n次的条件判断。也就是说,按下的一刹那,Arduino已经发现n次“按钮按下”的动作,当然就没有办法达到我们原来 “按下亮,再按下暗” 的目的了。

四、动手实践:让按钮控制变得稳定些吧

1、神奇的“当循环”

如何让按钮控制变得稳定呢?加了500毫秒的延时后,我们如果能够准确控制按钮的按下、放开的节奏,似乎也可以稳定控制LED的状态了。但是,这也太没有技术含量吧!

给个小思路:当按下按钮而没有放开的时候,Arduino能不能就不执行下面的修改LED状态(设定数字针脚3)的语句,直到放开按钮后才继续执行? 答案当然是肯定的,ArduBlock教育版中就有这样的语句:“当……”,我们可以在修改变量k的代码前加上这么一句:

图六

仔细观察,发现上述程序多了一个“当循环”,并且执行部分没有任何语句。这个结构我们在下个专题会具体介绍,这里先简单了解一下,它的功能是,当【条件满足】后面的条件成立时,就一直执行【执行】语句后面的内容。我们这里的【当】的作用是,如果按钮不放开,就一直空循环。谁叫你按下按钮不放开啊,不放开就空循环,就一直等待,谁怕谁啊,哈哈!

2、关于消抖

不敢说就很稳定了。在测试中我们还是会发现,偶尔几次按下还会有“控制失灵”的感觉。莫非我们的程序有问题还是Arduino不听话?其实,这种不稳定是按钮抖动引起的。什么是按钮的抖动呢?一般情况下,按钮所用的开关都为机械弹性开关,当机械触电断开、闭合时,由于机械触电的弹性作用,按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而,按键开关在闭合及断开的瞬间均伴随有一连串的抖动。

如果你觉得这种抖动还是不好理解,那请你把一颗玻璃珠扔在水泥地板上吧。是否看到玻璃珠在不停地跳跃?按键抖动也就是这样的道理。我们自以为就按下一次按钮,但是Arduino却能检测到多次的开关闭合和断开的动作,执行了多次我们肉眼无法识别的LED开和关的动作。

所谓“消抖”是为了避免在按键按下或是抬起时电平剧烈抖动带来的影响。按键的消抖,可用硬件或软件两种方法。对于我们来说,用软件形式消抖比较简单,不用改造按钮。在Arduino的示例程序Digital——>Debounce中提供了一个解决方案,有代码基础的同学可以参考。什么?看不懂!不用担心,ArduBlock也能实现消抖的。

软件消抖的算法也有很多种,最简单的就是不断检测按键值,直到按键值稳定。实现方法:假设未按键时输入1,按键后输入为0,抖动时不定。可以做以下检测:检测到按键输入为0之后,延时5ms~10ms,再次检测,如果按键还为0,那么就认为有按键输入。延时的5ms~10ms恰好避开了抖动期。 其实还可以更简单,先贴代码,再分析:

图七

哈哈,就加了两句延迟,分别延迟100毫秒。为什么要延时两次?说出来很简单,既然“按下”刹那会抖,“放开”刹那当然也会抖的。至于延时的时间根据不同的按钮来定。拿到新按钮时,可以多测试几次,以便找到合适的延迟时间。一般来说按钮对反映速度不会太苛刻,我们用了2次延时100毫秒,也没有发现什么不妥。

好吧,按钮抖动这个难题就这么so easy的解决了,容我仰天长啸三声吧,哈哈哈……

五、拓展应用

学会了使用ArduBlock实现按钮控制LED,是不是发现之前对学习机器人的担忧多余了,代而替之的是一种跃跃欲试的冲动?良好的开端,成功的一半,我们已经慢慢走近机器人神秘而又单纯的世界了。继续动起来罗。还是那句话,如果有困难,那就关注我们的下一个专题,跟我们一起使用ArduBlock玩转机器人。