Malay
颜色选择
阳光橙
深夜黑
天空蓝
葡萄紫
薄荷绿
深海蓝
首页
论坛
佳礼报道
新闻
搜索
1794
查看
0
回复

[分享] 使用Arduino为多个开关作Debounce

[复制链接]

楼主: 西门庆33       显示全部楼层   阅读模式

楼主
发表于 22-12-2013 12:37 AM | 显示全部楼层 |阅读模式

当两个金属触点(Contact)关闭或打开时,它将会产生多个信号,我们称之为Bounce。Debounce是一个硬体设备或是软件,确保金属触点关闭或打开时,只有一个信号将会产生。

这里我们使用Arduino为多个开关作Debounce

Arduino Playground里有一个Bounce程序库,但是有限制
  • 不能启用单晶片内部的上拉电阻(pull-up resistor),因此,每个开关必须连接一个外部上拉电阻
  • 编写代码时,不能在setup内检测开关的状态。因此,当按下开关同时开机,将不能检测到开关的状态
  • 使用多个开关时,编写代码会比较麻烦

Adafruit有一例子,可以完美解决以上问题。只需更改byte buttons[] = {4, 5, 6, 7, 8, 9} ,就可以使用很多开关了。
  1. #define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty

  2. // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
  3. byte buttons[] = {4, 5, 6, 7, 8, 9};

  4. // This handy macro lets us determine how big the array up above is, by checking the size
  5. #define NUMBUTTONS sizeof(buttons)

  6. // we will track if a button is just pressed, just released, or 'currently pressed'
  7. byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

  8. void setup() {
  9.   byte i;

  10.   // set up serial port
  11.   Serial.begin(9600);
  12.   Serial.print("Button checker with ");
  13.   Serial.print(NUMBUTTONS, DEC);
  14.   Serial.println(" buttons");
  15.   // pin13 LED
  16.   pinMode(13, OUTPUT);

  17.   // Make input & enable pull-up resistors on switch pins
  18.   for (i=0; i< NUMBUTTONS; i++) {
  19.     pinMode(buttons[i], INPUT);
  20.     digitalWrite(buttons[i], HIGH);
  21.   }
  22. }

  23. void check_switches()
  24. {
  25.   static byte previousstate[NUMBUTTONS];
  26.   static byte currentstate[NUMBUTTONS];
  27.   static long lasttime;
  28.   byte index;
  29.   if (millis() < lasttime) {
  30.      lasttime = millis(); // we wrapped around, lets just try again
  31.   }

  32.   if ((lasttime + DEBOUNCE) > millis()) {
  33.     return; // not enough time has passed to debounce
  34.   }
  35.   // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  36.   lasttime = millis();

  37.   for (index = 0; index < NUMBUTTONS; index++) {
  38.     justpressed[index] = 0;       // when we start, we clear out the "just" indicators
  39.     justreleased[index] = 0;

  40.     currentstate[index] = digitalRead(buttons[index]);   // read the button
  41.     if (currentstate[index] == previousstate[index]) {
  42.       if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
  43.           // just pressed
  44.           justpressed[index] = 1;
  45.       }
  46.       else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
  47.           // just released
  48.           justreleased[index] = 1;
  49.       }
  50.       pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
  51.     }
  52.     //Serial.println(pressed[index], DEC);
  53.     previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  54.   }
  55. }

  56. void loop() {
  57.   check_switches();      // when we check the switches we'll get the current state

  58.   for (byte i = 0; i < NUMBUTTONS; i++) {
  59.     if (justpressed[i]) {
  60.       Serial.print(i, DEC);
  61.       Serial.println(" Just pressed");
  62.       // remember, check_switches() will CLEAR the 'just pressed' flag
  63.     }
  64.     if (justreleased[i]) {
  65.       Serial.print(i, DEC);
  66.       Serial.println(" Just released");
  67.       // remember, check_switches() will CLEAR the 'just pressed' flag
  68.     }
  69.     if (pressed[i]) {
  70.       Serial.print(i, DEC);
  71.       Serial.println(" pressed");
  72.       // is the button pressed down at this moment
  73.     }
  74.   }
  75. }
复制代码
我稍为修改了上面例子,让按钮按下时,只产生一个信号。如果想再产生另一个信号,那就必须释放按钮,再按一下按钮。使用此方法来更改电子闹钟的时间,将是非常简单与方便。
  1. #define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty

  2. // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
  3. byte buttons[] = {4, 5, 6, 7, 8, 9};

  4. // This handy macro lets us determine how big the array up above is, by checking the size
  5. #define NUMBUTTONS sizeof(buttons)

  6. // we will track if a button is just pressed, just released, or 'currently pressed'
  7. byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

  8. byte previous_keystate[NUMBUTTONS], current_keystate[NUMBUTTONS];

  9. void setup() {
  10.   byte i;
  11.   // set up serial port
  12.   Serial.begin(9600);
  13.   Serial.print("Button checker with ");
  14.   Serial.print(NUMBUTTONS, DEC);
  15.   Serial.println(" buttons");
  16.   // pin13 LED
  17.   pinMode(13, OUTPUT);
  18.   // Make input & enable pull-up resistors on switch pins
  19.   for (i=0; i< NUMBUTTONS; i++) {
  20.     pinMode(buttons[i], INPUT);
  21.     digitalWrite(buttons[i], HIGH);
  22.   }
  23. }

  24. void check_switches()
  25. {
  26.   static byte previousstate[NUMBUTTONS];
  27.   static byte currentstate[NUMBUTTONS];
  28.   static long lasttime;
  29.   byte index;
  30.   if (millis() < lasttime) {
  31.     // we wrapped around, lets just try again
  32.     lasttime = millis();
  33.   }
  34.   if ((lasttime + DEBOUNCE) > millis()) {
  35.     // not enough time has passed to debounce
  36.     return;
  37.   }
  38.   // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  39.   lasttime = millis();
  40.   for (index = 0; index < NUMBUTTONS; index++) {
  41.     justpressed[index] = 0;       // when we start, we clear out the "just" indicators
  42.     justreleased[index] = 0;
  43.     currentstate[index] = digitalRead(buttons[index]);   // read the button
  44.     if (currentstate[index] == previousstate[index]) {
  45.       if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
  46.         // just pressed
  47.         justpressed[index] = 1;
  48.       }
  49.       else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
  50.         justreleased[index] = 1; // just released
  51.       }
  52.       pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
  53.     }
  54.     previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  55.   }
  56. }

  57. void loop() {
  58.   check_switches();      // when we check the switches we'll get the current state
  59.   for (byte i = 0; i < NUMBUTTONS; i++) {
  60.     current_keystate[i]=justpressed[i];
  61.     if (current_keystate[i] != previous_keystate[i]) {
  62.       if (current_keystate[i]) execute_Justpressed(i);
  63.     }
  64.     previous_keystate[i]=current_keystate[i];
  65.   }
  66. }

  67. void execute_Justpressed(byte thisButton_pressed) {
  68.   Serial.print("You press this button: ");
  69.   Serial.println(thisButton_pressed);   
  70. }
复制代码
本帖最后由 西门庆33 于 22-12-2013 12:43 AM 编辑

评分

参与人数 1积分 +50 收起 理由
pic + 50 努力贡献, 加分奖励

查看全部评分

回复

使用道具 举报

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

本版积分规则

 WeChat
 CARI App
Get it FREE Google play
 Instagram
cari_malaysia
FOLLOW
- 版权所有 © 1996-2019 Cari Internet Sdn Bhd 佳礼网络有限公司 (483575-W) -
Private Cloud provided by IPSERVERONE
0.187887s Gzip On
快速回复 返回顶部 返回列表