一句話解釋按鍵的彈跳:
你來不及放開按鍵之前,程式已經來問第二次了,所以程式不知道你是按了第二次,還是你單純還沒放開。
如果你懶得管那麼多,不妨直接在 loop 裡面加入 delay(100)
,避開明顯的彈跳問題。
如果你想嚴謹一點,那就引用一些現成的庫來用吧。
(以下用例中,我的 MCU 是 ESP32)
如果你什麼都不要,就只要防彈跳,可以考慮 EasyButton 這個 library。
使用方法很簡單,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <ezButton.h>
const int led = 19;
ezButton btn(23);
void setup(){ pinMode(led, OUTPUT);
btn.setDebounceTime(50); }
void loop() {
btn.loop();
if(btn.isPressed()){ digitalWrite(led, !digitalRead(led)); }
}
|
額外送你判斷按下跟放開的時機,可以讓你在按下就觸發,或是放開才觸發。
如果你除了基本的防彈跳,還想要可以定義單擊、雙擊、長按,可以考慮 OneButton。
可參考我的範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <OneButton.h>
OneButton btn;
const int led = 19;
void setup() { pinMode(led, OUTPUT);
btn.setup( 23, INPUT_PULLUP, true );
btn.attachClick(whenSingle); btn.attachDoubleClick(whenDouble); btn.attachLongPressStart(whenLong);
}
void loop() { btn.tick(); }
void whenSingle(){ digitalWrite(led, !digitalRead(led)); } void whenDouble(){ digitalWrite(led, !digitalRead(led)); } void whenLong(){ digitalWrite(led, !digitalRead(led)); }
|
此例中,我單擊、雙擊、長按都觸發一樣的動作,你可以自己定義要分別做什麼動作。