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 语句呢?我认为是可行的。经过实验我认为只要延长时间,读两次数即可。

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

原文地址:https://www.cnblogs.com/FBsharl/p/9973236.html

时间: 2024-07-30 19:11:27

Arduino 开关控制小灯持续亮之具体思路的相关文章

1-STM32嵌入LUA开发(控制小灯闪耀)

今天因为想让STM32完美的处理字符串,所以就想着让STM32嵌入lua,本来想用f103c8t6,但是一编译就提示内存不足...... 所以单片机的型号选择的 \ 我下载到了RBT6的芯片上测试的 先说一下最终实现的效果吧,就是用lua语言控制单片机的PC13  每间隔500Ms反转一次 实现功能的部分 static int lua_led_on(lua_State *L) { PCout(13) = 1; return 1; } static int lua_led_off(lua_Stat

arduino入门学习实现语音控制LED灯

需要的准备的硬件arduino+PC+麦克风实现语音命令控制LED灯的亮灭. 首先需要将写好的arduino程序烧录到arduino uno主板中,下面是代码如下: int val;//定义变量val int ledpin=10;//定义数字接口13 void setup() { Serial.begin(9600);//设置波特率为9600,这里要跟软件设置相一致.当接入特定设备(如:蓝牙)时,我们也要跟其他设备的波特率达到一致. pinMode(ledpin,OUTPUT);//设置数字10

驱动控制开发板上的四个LED小灯

在上一章了解了开发linux驱动程序的步骤,在本章会完成一个真正意义上的linux驱动,该驱动用来控制开发板上的四个LED小灯,通过向驱动发送数据可以控制LED小灯的开关. 首先介绍了LED驱动的实现原理,虽然linux驱动直接与硬件打交道,但并不是linux驱动直接向硬件中的内存写数据,而是与本机的I/O内存进行交互.Linux内核的内存管理模块负责同步I/O内存与硬件中的数据.每一个连接linux的硬件在I/O内存中都会有映射首地址. 其次是编写LED驱动.以下创建一个设备文件,第一步:使用

哪个开关控制哪盏灯

QUESTION: 房间里面有三盏灯,屋外有三个开关,分别控制着三盏灯,只有进入房间,才能看到哪盏灯是亮的.请问如何只进入房间一次,就能指明哪个开关控制哪盏灯??? ANSWER: 假设开关编号为A,B,C.打开开关A,但不进入房间:等过了大约若干分钟后,关闭开关A,并且打开开关B:同时迅速进入房间内,并且用手摸房间内不亮的两盏灯以确定哪盏灯发热.设[房间内亮着的灯.不亮但温度较高的灯.不亮但温度较低的灯]的编号分别为L1.L2.L3. 判断的结果是:开关A控制L2:开关B控制L1:开关C控制L

arduino 红外遥控器控制LED灯

/* 日期:2016.9.1 功能:红外遥控器控制LED灯 开,关,闪烁 元件: 跳线公公头 * 5 led, 220欧电阻 红外接收管,红外遥控 接线: 红外灯面向自己从左到右分别接 IO3, GND, 5V LED 负极接GND 正极串联电阻接 IO5 红外1-9口编码: FF30CF 1 FF18E7 2 FF7A85 3 FF10EF 4 FF38C7 5 FF5AA5 6 FF42BD 7 FF4AB5 8 FF52AD 9 参考:http://www.arduino.cn/threa

四、按键控制LED灯亮灭

材料: 1.SAGOO UNO 1块: 2.按键模块 1块: 3.杜邦线若干. 步骤: 1.按照下图连接按键模块和UNO: SAGOO UNO引脚                                      按键模块引脚 3V3  <------------------------------------>    V(电源) GND <------------------------------------>    G(电源) Pin2  <----------

51点亮第一个小灯

#include <reg52.h> sbit LED=P0^0;//sbit 小写 ,P必须大写 void main() { LED=0; while(1);//程序停止在这里 // while(1)   //无限循环 // { //  LED=0;   // //} } 一般来说这样就可以点亮小灯了,但是学习板考虑因素很多这里就不多说.下面的就可以点亮小灯 #include <reg52.h> sbit LED=P0^0;//sbit 小写 ,P必须大写 sbit ADDR0=

socket通信——多角度控制LED灯亮灭

今天以物联网网关(网关链接)以服务器,在多个客户端就做一个非常简单的功能:点亮或熄灭网关上的LED灯.目前想到了三种方式,分别是:TCP&UDP测试工具.自编Java客户端和Mono Android客户端.相信这会很有意思的. 1.服务器端 在使用或编写客户端之前,首先来看看服务器端代码,其专门通过串口烧进网关内部 OutputPort led = new OutputPort((Cpu.Pin)GPIO_NAMES.PF8, false); Socket sc; Socket ss = new

云中树莓派(4):利用声音传感器控制Led灯

云中树莓派(1):环境准备 云中树莓派(2):将传感器数据上传到AWS IoT 并利用Kibana进行展示 云中树莓派(3):通过 AWS IoT 控制树莓派上的Led 云中树莓派(4):利用声音传感器控制Led灯 1. 声音传感器及其配置 声音传感器如下图所示: 将 VCC 引脚接入树莓派 5V 引脚,将 GND 引脚接入树莓派 GND 引脚,将 OUT 引脚接入树莓派 GPIO20. 要注意,模块在环境声音强度达不到设定阈值时,OUT输出高电平(1),当外界环境声音强度超过设定阈值时,模块O