开启左侧

Arduino之按钮

[复制链接]
发表于 2017-7-17 15:28:41 | 显示全部楼层 |阅读模式
本帖最后由 PPeach 于 2017-7-17 15:32 编辑

       我相信很多人在Arduino入门的时候第一件事就是控制LED闪烁,一个最基本的Blink例子就是控制D13引脚连接的LED进行闪烁。
  1. /*
  2.   Blink
  3.   Turns on an LED on for one second, then off for one second, repeatedly.

  4.   Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  5.   it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  6.   the correct LED pin independent of which board is used.
  7.   If you want to know what pin the on-board LED is connected to on your Arduino model, check
  8.   the Technical Specs of your board  at https://www.arduino.cc/en/Main/Products
  9.   
  10.   This example code is in the public domain.

  11.   modified 8 May 2014
  12.   by Scott Fitzgerald
  13.   
  14.   modified 2 Sep 2016
  15.   by Arturo Guadalupi
  16.   
  17.   modified 8 Sep 2016
  18.   by Colby Newman
  19. */


  20. // the setup function runs once when you press reset or power the board
  21. void setup() {
  22.   // initialize digital pin LED_BUILTIN as an output.
  23.   pinMode(LED_BUILTIN, OUTPUT);
  24. }

  25. // the loop function runs over and over again forever
  26. void loop() {
  27.   digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  28.   delay(1000);                       // wait for a second
  29.   digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  30.   delay(1000);                       // wait for a second
  31. }
复制代码
      其中 “LED_BUILTIN” 这个变量即表示D13上连接的LED。学习这个例子的作用是熟悉一下最基本的IO写操作。接下来则应该熟悉的是IO口的读取操作,一般这个时候就会接触到了串口,目的是让自己通过IO读操作的数据又一个比较可观的方式表达出来。
  1. /*
  2.   DigitalReadSerial
  3. Reads a digital input on pin 2, prints the result to the serial monitor

  4. This example code is in the public domain.
  5. */

  6. // digital pin 2 has a pushbutton attached to it. Give it a name:
  7. int pushButton = 2;

  8. // the setup routine runs once when you press reset:
  9. void setup() {
  10.   // initialize serial communication at 9600 bits per second:
  11.   Serial.begin(9600);
  12.   // make the pushbutton's pin an input:
  13.   pinMode(pushButton, INPUT);
  14. }

  15. // the loop routine runs over and over again forever:
  16. void loop() {
  17.   // read the input pin:
  18.   int buttonState = digitalRead(pushButton);
  19.   // print out the state of the button:
  20.   Serial.println(buttonState);
  21.   delay(1);        // delay in between reads for stability
  22. }
复制代码
      这个例子则是让D2的状态能够被读取进来,然后通过串口显示出来。当然我们能在D2上接按钮,接开关或者其他一些开关量的传感器。
       我们通过这两个例子发现了,其实数字口的操作(digitalRead / digitalWrite)都需要在setup中调用pinMode这个语句。
       接触完这两个例子,我们就可以把按钮和灯一起结合使用。我相信很多人能写出这样的一个程序。
  1. int led = 8; // LED接在D8
  2. int button = 7; // Button接在D7

  3. void setup()
  4. {
  5.   pinMode(led, OUTPUT); // 定义D8为输出
  6.   pinMode(button, INPUT); // 定义D7为输入
  7. }

  8. void loop()
  9. {
  10.   int buttonState = digitalRead(button); // 读取按钮状态
  11.   digitalWrite(led, buttonState); // 将Button状态直接传递给LED
  12. }
复制代码
      通过实验,我们发现这个LED其实是按了就亮,不按就灭(这里我们默认连接在D7上的按钮不按状态是关,按了是开;当然存在有些已经硬件上拉的的按钮不按是开,按了是关,这个和具体电路有关,不参与讨论)。
       这样的程序其实就相当于在一个基础的串联电路中连接了一个按钮和灯,按钮按下电路导通,不按下不导通。效果如下左图所示。但是,如果我想用按钮按一下灯亮,再按一下灯灭,这样应该怎么做呢?如下右图所示。
2017-07-17-14-58-18.gif 2017-07-17-15-01-11.gif


       在思考这个是怎么实现的之前,我们先思考一下,如果对于一个基础的串联电路,我将按钮和灯的组合换成开关和灯的组合,那是不是就可以做到开关打开灯亮,关闭灯灭,就像家中的电灯一样,这是为什么呢?
       是不是因为开关他不能保持按下去的状态,而按钮则可以保持关闭的状态?这里就引出一个比较关键的关键字,我们应该如何保持状态?既然硬件上无法保持,那么我们就应该从软件上去思考如何保持一个按钮的状态。
       其实在编程的过程的过程,变量不是只有存数据的功能,还包含了传递状态的功能。这样,我们就可以引入一个变量来暂存灯状态,然后根据这个变量的状态去控制LED的点亮或者熄灭。
  1. const byte led = 8; // LED接在D8
  2. const byte button = 7; // Button接在D7,硬件上拉

  3. boolean ledState = false; // 用来表示LED状态

  4. void setup()
  5. {
  6.   pinMode(led, OUTPUT); // 定义D8为输出
  7.   pinMode(button, INPUT); // 定义D7为输入
  8. }

  9. void loop()
  10. {
  11.   while (digitalRead(button)); // 等待按钮被按下

  12.   // 根据ledState的状态控制LED
  13.   if (ledState == false)
  14.   {
  15.     digitalWrite(led, HIGH);
  16.     ledState = true;
  17.   }
  18.   else if (ledState == true)
  19.   {
  20.     digitalWrite(led, LOW);
  21.     ledState = false;
  22.   }

  23.   delay(500); // 延迟500ms,用来调整按键灵敏度
  24. }
复制代码
      如上程序就是通过ledState这个变量暂存灯的状态,然后根据这个变量的状态去改变灯的开关。这里有两个比较关键的地方需要读者自行思考理解,第一个是这句话。
  1. while (digitalRead(button)); // 等待按钮被按下
复制代码
      第二个则是
  1. delay(500);
复制代码
      这两句话是这个程序比较关键的部分,如果只看语句是很好理解这句话的作用的,但是在程序中的作用是什么?还是希望读者能自己思考一下。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

精彩课程推荐

关于我们

帮助中心

商务合作

点击这里给我发消息

关注微信公众号

Copyright © 2016-2017 i创学院 - 上海享渔教育科技有限公司 Powered by Discuz!     ( 沪ICP备16033954号-1 )