Arduino 开关控制小灯持续亮之具体思路

Arduino 开关控制小灯持续亮之具体思路

为什么写这篇文章:

我们用开关控制灯的亮灭的时候,希望只需要按一下按键就可以做到灯一直亮着。而在《Arduino魔法书》中——有弹性的按键这一节主要讲了消除抖动函数,但是没有讲这个程序的原理。

书中的代码如下

const int LED = 9;
const int BUTTON = 2;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;

void setup() {
  pinMode(LED,OUTPUT);
  pinMode(BUTTON,INPUT);
  // put your setup code here, to run once:

}

boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);
  if(last != current)
  {
    delay(5);
    current = digitalRead(BUTTON);
  }
  return current;
}
void loop() {
currentButton = debounce(lastButton);
if (lastButton ==LOW && currentButton == HIGH)
{
  ledOn = !ledOn;
}
 lastButton = currentButton;
 digitalWrite(LED,ledOn);            
  // put your main code here, to run repeatedly:

}

首先,我们假设没有抖动,只关注 loop()函数的部分,
currentButton = debounce(lastButton);
这时等价于
current = digitalRead(BUTTON);

第一次按——开灯

首先需要想的是:
当按下的时候,灯能够一直亮着。
如果使用digitalRead来读当前的值,当按完以后,灯就会熄灭。所以,利用一个条件语句:条件是:按下按键,动作(或者结果)是灯持续亮。
用代码表示如下

所以必须更改原来的条件和动作。先考虑动作,不妨把灯亮变成一个状态量,而不是临时读取的量,这里定义为 ledOn. 
那么接下来需要想的是如何更改 ledOn 这个值呢?那就是通过按键的状态变化来考虑了。另外,我们也想要灯亮时再次按下按键的时候,能够熄灭灯。所以可以用到一个反转语句:
ledOn = !ledOn;
接下来就是条件的问题了:无论你是想持续点亮灯还是熄灭灯,这时候按键的状态总是 HIGH,而之前的状态总是 LOW.
所以你可以用以下语句决定是否执行反转语句:
if(lastButton = LOW&& currentButton = HIGH);
来进行判断。

第一次以后

然后之下的语句:lastButton = currentButton,此时,lastButton 的值变为 HIGH,然后重新返回 loop()函数的第一行,进入debounce()函数,此时,你已经不再按键了,所以返回的 currentButton 的值为LOW,然后已经返回值后执行下一条语句,也就是if()的条件语句,因为lastButton = HIGH ,currentBUTTON = LOW ,所以不满足条件,直接执行 lastButton = currentButton,这时,lastButton 和 currentButton 的值都为 LOW。

第二次按——关灯

下一次你再进行按键的时候,就会反转 ledOn的数值,ledOn熄灭。

最后,我们来考虑消除抖动

之所以要消除抖动,是因为如果不消除抖动,currentButton 的值是不确定的,所以会导致结果的无法预测,不能人为地掌控。

如何消除抖动呢,书中写道5ms之后,抖动一般都会消失,所以 delay(5); 之后再次读取数值。
但是需要时时刻刻读取吗?不需要,所以可以加一个条件语句。
也就是 if (last! = current)
如果没必要进行5ms的等待了再次读取,那么程序变成这样:

boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);
  if(last != current)
  return current;
}

此时如果last = current ,返回值都是没有消除抖动的,所以消除抖动需要有一个 if 也需要延时delay.

那么,如果没有if 语句呢?我认为是可行的。经过实验我认为只要延长时间,读两次数即可。

之所以会存在抖动,我认识是抖动的时间远远地长于程序运行一条语句的时间,此时需要延时再进行读数。





猜你喜欢

转载自www.cnblogs.com/FBsharl/p/9973236.html