“開關抖動”:
由於按鍵是基於彈簧-阻尼系統的機械部件,所以當按下一個按鍵時,讀到的信號並不是從低到高,而是在高低電平之間跳動幾毫秒之后才最終穩定。

代碼解讀:
1 const int LED = 9; 2 const int BUTTON = 2; 3 boolean lastButton = LOW; 4 boolean currentButton = HIGH; 5 boolean ledOn = false; 6 7 // The setup() function runs once each time the micro-controller starts 8 void setup() 9 { 10 pinMode(LED, OUTPUT); 11 pinMode(LED, INPUT); 12 } 13 14 /* 15 * 消抖動函數:傳入前一個按鍵狀態,返回當前消抖動的按鍵狀態 16 * - 這里所謂的消抖動,實際上就是如果檢測到電壓變化后先不操作,因為可能是抖動階段的 17 * 電壓改變,等5m之后(等電平穩定下來)再讀取當前值,避開抖動階段。 18 * - 如果沒有使用消抖動函數,在抖動的過程中電壓多次變化,會得到很多次“按鈕按下”的 19 * 結論,從而造成短時間內頻繁的開燈關燈。 20 */ 21 boolean debounce(boolean last) { 22 boolean current = digitalRead(BUTTON); 23 if (last != current) { 24 // 如果電壓改變了,說明肯定按下按鈕了,否則電壓值是不會改變的。 25 // 但是這個電壓改變是不是抖動階段的電壓改變是不知道的,所以要等5ms(避開抖動 26 // 階段)再讀取一次,第二次讀取的就是穩定后的值可以直接返回了。 27 delay(5); 28 current = digitalRead(BUTTON); 29 } 30 // 如果電壓沒有改變,不能判斷是否按下按鈕,直接返回,等待下一輪對引腳狀態的查詢 31 return current; 32 } 33 35 void loop() 36 { 37 currentButton = debounce(lastButton); 38 // 如果不用消抖動函數讀取引腳值, 這一句應該是currentButton = digitalRead(BUTTON),后面的邏輯都不變 39 40 if (lastButton == LOW && currentButton == HIGH) { 41 // 如果lastButton == LOW && currentButton = HIGH,則認為按鈕按下了,因此要改變led燈的狀態 42 ledOn = !ledOn; 43 } 44 lastButton = currentButton; 45 46 digitalWrite(LED, ledOn); 47 }
