当两个金属触点(Contact)关闭或打开时,它将会产生多个信号,我们称之为Bounce。Debounce是一个硬体设备或是软件,确保金属触点关闭或打开时,只有一个信号将会产生。
这里我们使用Arduino为多个开关作Debounce
Arduino Playground里有一个Bounce程序库,但是有限制
- 不能启用单晶片内部的上拉电阻(pull-up resistor),因此,每个开关必须连接一个外部上拉电阻
- 编写代码时,不能在setup内检测开关的状态。因此,当按下开关同时开机,将不能检测到开关的状态
- 使用多个开关时,编写代码会比较麻烦
Adafruit有一例子,可以完美解决以上问题。只需更改byte buttons[] = {4, 5, 6, 7, 8, 9} ,就可以使用很多开关了。- #define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
-
- // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
- byte buttons[] = {4, 5, 6, 7, 8, 9};
-
- // This handy macro lets us determine how big the array up above is, by checking the size
- #define NUMBUTTONS sizeof(buttons)
-
- // we will track if a button is just pressed, just released, or 'currently pressed'
- byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
-
- void setup() {
- byte i;
-
- // set up serial port
- Serial.begin(9600);
- Serial.print("Button checker with ");
- Serial.print(NUMBUTTONS, DEC);
- Serial.println(" buttons");
- // pin13 LED
- pinMode(13, OUTPUT);
-
- // Make input & enable pull-up resistors on switch pins
- for (i=0; i< NUMBUTTONS; i++) {
- pinMode(buttons[i], INPUT);
- digitalWrite(buttons[i], HIGH);
- }
- }
-
- void check_switches()
- {
- static byte previousstate[NUMBUTTONS];
- static byte currentstate[NUMBUTTONS];
- static long lasttime;
- byte index;
- if (millis() < lasttime) {
- lasttime = millis(); // we wrapped around, lets just try again
- }
-
- if ((lasttime + DEBOUNCE) > millis()) {
- return; // not enough time has passed to debounce
- }
- // ok we have waited DEBOUNCE milliseconds, lets reset the timer
- lasttime = millis();
-
- for (index = 0; index < NUMBUTTONS; index++) {
- justpressed[index] = 0; // when we start, we clear out the "just" indicators
- justreleased[index] = 0;
-
- currentstate[index] = digitalRead(buttons[index]); // read the button
- if (currentstate[index] == previousstate[index]) {
- if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
- // just pressed
- justpressed[index] = 1;
- }
- else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
- // just released
- justreleased[index] = 1;
- }
- pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
- }
- //Serial.println(pressed[index], DEC);
- previousstate[index] = currentstate[index]; // keep a running tally of the buttons
- }
- }
-
- void loop() {
- check_switches(); // when we check the switches we'll get the current state
-
- for (byte i = 0; i < NUMBUTTONS; i++) {
- if (justpressed[i]) {
- Serial.print(i, DEC);
- Serial.println(" Just pressed");
- // remember, check_switches() will CLEAR the 'just pressed' flag
- }
- if (justreleased[i]) {
- Serial.print(i, DEC);
- Serial.println(" Just released");
- // remember, check_switches() will CLEAR the 'just pressed' flag
- }
- if (pressed[i]) {
- Serial.print(i, DEC);
- Serial.println(" pressed");
- // is the button pressed down at this moment
- }
- }
- }
复制代码 我稍为修改了上面例子,让按钮按下时,只产生一个信号。如果想再产生另一个信号,那就必须释放按钮,再按一下按钮。使用此方法来更改电子闹钟的时间,将是非常简单与方便。- #define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty
-
- // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
- byte buttons[] = {4, 5, 6, 7, 8, 9};
-
- // This handy macro lets us determine how big the array up above is, by checking the size
- #define NUMBUTTONS sizeof(buttons)
-
- // we will track if a button is just pressed, just released, or 'currently pressed'
- byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
-
- byte previous_keystate[NUMBUTTONS], current_keystate[NUMBUTTONS];
-
- void setup() {
- byte i;
- // set up serial port
- Serial.begin(9600);
- Serial.print("Button checker with ");
- Serial.print(NUMBUTTONS, DEC);
- Serial.println(" buttons");
- // pin13 LED
- pinMode(13, OUTPUT);
- // Make input & enable pull-up resistors on switch pins
- for (i=0; i< NUMBUTTONS; i++) {
- pinMode(buttons[i], INPUT);
- digitalWrite(buttons[i], HIGH);
- }
- }
-
- void check_switches()
- {
- static byte previousstate[NUMBUTTONS];
- static byte currentstate[NUMBUTTONS];
- static long lasttime;
- byte index;
- if (millis() < lasttime) {
- // we wrapped around, lets just try again
- lasttime = millis();
- }
- if ((lasttime + DEBOUNCE) > millis()) {
- // not enough time has passed to debounce
- return;
- }
- // ok we have waited DEBOUNCE milliseconds, lets reset the timer
- lasttime = millis();
- for (index = 0; index < NUMBUTTONS; index++) {
- justpressed[index] = 0; // when we start, we clear out the "just" indicators
- justreleased[index] = 0;
- currentstate[index] = digitalRead(buttons[index]); // read the button
- if (currentstate[index] == previousstate[index]) {
- if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
- // just pressed
- justpressed[index] = 1;
- }
- else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
- justreleased[index] = 1; // just released
- }
- pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
- }
- previousstate[index] = currentstate[index]; // keep a running tally of the buttons
- }
- }
-
- void loop() {
- check_switches(); // when we check the switches we'll get the current state
- for (byte i = 0; i < NUMBUTTONS; i++) {
- current_keystate[i]=justpressed[i];
- if (current_keystate[i] != previous_keystate[i]) {
- if (current_keystate[i]) execute_Justpressed(i);
- }
- previous_keystate[i]=current_keystate[i];
- }
- }
-
- void execute_Justpressed(byte thisButton_pressed) {
- Serial.print("You press this button: ");
- Serial.println(thisButton_pressed);
- }
复制代码 本帖最后由 西门庆33 于 22-12-2013 12:43 AM 编辑
|