极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12376|回复: 3

OCROBOT进阶教程02——按键控制LED(消抖应用,不使用delay)

[复制链接]
发表于 2016-2-21 17:02:03 | 显示全部楼层 |阅读模式
本帖最后由 Soul110 于 2016-2-22 15:53 编辑

消抖
      消抖是为了避免在按键按下或是抬起时电平剧烈抖动带来的影响。也就是在一段时间内检查两次来确保按键被按下。如果不消抖,按键一次会被代码识别为多次按下。利用millis()功能来记录按键按下后的时间。

为什么不用delay():
     虽然创建一个使用delay()的闪烁LED很简单,并且许多例子将很短的delay用于消除开关抖动,delay()确实拥有很多显著的缺点。在delay函数使用的过程中,读取传感器值、计算、引脚操作均无法执行,因此,它所带来的后果就是使其他大多数活动暂停。其他操作定时的方法请参加millis()函数和它的例子。大多数熟练的程序员通常避免超过10毫秒的delay(),除非程序非常简单。 但某些操作在delay()执行时任然能够运行,因为delay函数不会使中断失效。通信端口RX接收到得数据会被记录,PWM(analogWrite)值和引脚状态会保持,中断也会按设定的执行。


本教程采用硬件为:
ALPHA 并行扩展板      一块;
ALPHA MEGA328-U   一块;
ALPHA 微动开关模块   一块;
ALPHA 11 LED模块     一块。
搭建电路
1. ALPHA MEGA328-U模块插入并行扩展版1号槽位。
2. ALPHA 11 LED模块插入1号槽位,堆叠于MEGA328-U上。
3. ALPHA 微动开关模块插入并行扩展板2号槽位。
4. USB线连接计算机与ALPHA MEGA328-U。

如图:

本次实验目的为红、绿、蓝三个按键,在经过消抖时间的处理下,能够各自控制对应的LED的灯的亮灭。
  1. /*
  2. Debounce
  3. 每次按键按下,输入脚从低电平到高电平,输出引脚就被触发从低电平到高电平或者高电平到低电平。
  4. 两次触发之间设置一个最小延时来消除抖动。
  5. 三个按键对应三盏LED灯,各自按键控制对应的LED灯,互不干扰
  6. */


  7. const int buttonPin1 = 15;    //初始化按键引脚
  8. const int buttonPin2 = 16;
  9. const int buttonPin3 = 17;
  10. const int ledPin1 = 2;      // 初始化LED的引脚
  11. const int ledPin2 = 3;  
  12. const int ledPin3 = 4;  

  13. int ledState1 = HIGH;         // 设置LED输出脚状态为高电平
  14. int ledState2 = HIGH;
  15. int ledState3 = HIGH;
  16. int buttonState1;             // 设置读取输入脚的状态
  17. int buttonState2;      
  18. int buttonState3;      
  19. int lastButtonState1 = LOW;   // 上一次读取到的输入状态为低电平
  20. int lastButtonState2 = LOW;   // 上一次读取到的输入状态
  21. int lastButtonState3 = LOW;   // 上一次读取到的输入状态


  22. long lastDebounceTime1 = 0;  // 最后一次输出脚触发时间
  23. long lastDebounceTime2 = 0;
  24. long lastDebounceTime3 = 0;
  25. long debounceDelay = 50;    // 设置消抖时间,增加它,如果输出不稳定

  26. void setup() {
  27.   pinMode(buttonPin1, INPUT);   //初始化按键的输入模式
  28.   pinMode(buttonPin2, INPUT);
  29.   pinMode(buttonPin3, INPUT);
  30.   pinMode(ledPin1, OUTPUT);   //初始化灯的输出模式
  31.   pinMode(ledPin2, OUTPUT);
  32.   pinMode(ledPin3, OUTPUT);

  33.   
  34.   digitalWrite(ledPin1, ledState1);// 设置LED状态为高电平
  35.   digitalWrite(ledPin2, ledState2);
  36.   digitalWrite(ledPin3, ledState3);
  37. }

  38. void runing1()                    //第一个按键对应第一盏灯
  39. {  if ((millis() - lastDebounceTime1) > debounceDelay) // 比较按键的相差时间,若大于消抖时间,则说明时间不管读取到什么,时间已经比消抖延时长,所以认为它是真实的当前状态
  40.      {        if (digitalRead(buttonPin1) != buttonState1)   // 如果按键状态改变:
  41.               {
  42.                  buttonState1 = digitalRead(buttonPin1); // 新的按键状态为high才会触发LED
  43.             if (buttonState1 == HIGH)                 //如果按键状态为高时,
  44.                    {
  45.                        ledState1 = !ledState1;            //改变对应的灯的电平
  46.                     }
  47.                 }
  48.    }
  49.     digitalWrite(ledPin1, ledState1); // 输出LED灯的状态
  50.    lastButtonState1 = digitalRead(buttonPin1); // 存储读取到的信息.按键会变成上次的输入状态:
  51. }

  52. void runing2()             //第2个按键对应第2盏灯
  53. {  if ((millis() - lastDebounceTime2) > debounceDelay)
  54.      {        if (digitalRead(buttonPin2) != buttonState2)  
  55.               {
  56.                  buttonState2 = digitalRead(buttonPin2);
  57.             if (buttonState2 == HIGH)
  58.                    {
  59.                        ledState2 = !ledState2;            
  60.                     }
  61.                 }
  62.    }
  63.     digitalWrite(ledPin2, ledState2);
  64.    lastButtonState2 = digitalRead(buttonPin2);
  65. }

  66. void runing3()                   //第3个按键对应第3盏灯
  67. { if ((millis() - lastDebounceTime3) > debounceDelay)
  68.      {        if (digitalRead(buttonPin3) != buttonState3)  
  69.               {
  70.                  buttonState3 = digitalRead(buttonPin3);
  71.             if (buttonState3 == HIGH)
  72.                    {
  73.                        ledState3 = !ledState3;
  74.                     }
  75.                 }
  76.    }
  77.     digitalWrite(ledPin3, ledState3);
  78.    lastButtonState3 = digitalRead(buttonPin3);
  79. }
  80. void loop() {
  81.   if (digitalRead(buttonPin1)!= lastButtonState1) //读取按键状态,存储到变量  // 检查是否按下按键(也就是输入了low或high),自从上一次按下之后你已经等了很久(忽略噪声的情况下)如果按键状态改变,那就是按下了或者是噪声
  82.   {
  83.        lastDebounceTime1 = millis(); // 重置消抖时间
  84.    }
  85.      runing1();   //调用第一个按键的函数
  86.     if (digitalRead(buttonPin2)!= lastButtonState2) //读取按键状态,存储到变量  // 检查是否按下按键(也就是输入了low或high),自从上一次按下之后你已经等了很久(忽略噪声的情况下)如果按键状态改变,那就是按下了或者是噪声
  87.   {
  88.        lastDebounceTime1 = millis(); // 重置消抖时间
  89.    }
  90.     runing2();    //调用第二个按键的函数

  91.    if (digitalRead(buttonPin3)!= lastButtonState3) //读取按键状态,存储到变量  // 检查是否按下按键(也就是输入了low或high),自从上一次按下之后你已经等了很久(忽略噪声的情况下)如果按键状态改变,那就是按下了或者是噪声
  92.   {
  93.        lastDebounceTime1 = millis(); // 重置消抖时间
  94.    }
  95.     runing3();   //调用第三个按键的函数
  96. }
复制代码



稍后会上传效果视频……
希望本教程会对大家有所帮助!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2016-3-23 16:40:45 | 显示全部楼层
楼主你好。我用了三个按钮测试了你的程序,有一个问题。就是三个按钮的程序我看了全是一样的。为什么就我第一个按钮,快速的按下去,它全能亮灭及时(原谅我用及时这个词- - )。第二个按钮和第三个按钮快速的按总是会两步了或者灭不了。我把针脚,继电器,按钮全部都替换了,还都是程序里的runing能及时接受到==  我向知道这是为什么  。。头好疼- -
回复 支持 反对

使用道具 举报

发表于 2016-3-23 17:57:41 | 显示全部楼层
我是一个林胖子 发表于 2016-3-23 16:40
楼主你好。我用了三个按钮测试了你的程序,有一个问题。就是三个按钮的程序我看了全是一样的。为什么就我第 ...

应该是我程序有不稳定的地方,我会马上更改,并且更新为精简版,谢谢你帮我检查
回复 支持 反对

使用道具 举报

发表于 2016-4-12 17:11:41 | 显示全部楼层
我是一个林胖子 发表于 2016-3-23 16:40
楼主你好。我用了三个按钮测试了你的程序,有一个问题。就是三个按钮的程序我看了全是一样的。为什么就我第 ...
  1. /*
  2. Debounce
  3. 每次按键按下,输入脚从低电平到高电平,输出引脚就被触发从低电平到高电平或者高电平到低电平。
  4. 两次触发之间设置一个最小延时来消除抖动。
  5. */


  6. const int buttonPin = 15;    // 按键引脚
  7. const int ledPin = 2;      // LED


  8. int ledState = HIGH;         // 输出脚状态
  9. int buttonState;             // 读取输入脚
  10. int lastButtonState = LOW;   // 上一次读取到的输入状态


  11. long lastDebounceTime = 0;  // 最后一次输出脚触发时间
  12. long debounceDelay = 50;    // 消抖时间,增加它,如果输出不稳定

  13. void setup() {
  14.   pinMode(buttonPin, INPUT);
  15.   pinMode(ledPin, OUTPUT);

  16.   // 设置LED状态
  17.   digitalWrite(ledPin, ledState);
  18. }

  19. void loop() {
  20.   //读取按键状态,存储到变量
  21.   int reading = digitalRead(buttonPin);

  22.   // 检查是否按下按键(也就是输入了low或high),自从上一次按下之后你已经等了很久(忽略噪声的情况下)
  23.   // 如果按键状态改变,那就是按下了或者是噪声
  24.   if (reading != lastButtonState) {
  25.     // 重置消抖时间
  26.     lastDebounceTime = millis();
  27.   }

  28.   if ((millis() - lastDebounceTime) > debounceDelay) {
  29.     // 不管读取到什么,时间已经比消抖延时长,所以认为它是真实的当前状态

  30.     // 如果按键状态改变:
  31.     if (reading != buttonState) {
  32.       buttonState = reading;

  33.       // 新的按键状态为high才会触发LED
  34.       if (buttonState == HIGH) {
  35.         ledState = !ledState;
  36.       }
  37.     }
  38.   }

  39.   // 设置LED:
  40.   digitalWrite(ledPin, ledState);

  41.   // 存储读取到的信息.后面会变成上次的输入状态:
  42.   lastButtonState = reading;
  43. }

复制代码
亲,这是一个按键的消抖程序哦!
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 03:54 , Processed in 0.039837 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表