我們利用按壓開關按下時回傳給 Arduino 板子的訊號,做為觸發輸出端改變的判斷,以下的電路示意與第一段程式碼,示範情境為:按下按壓開關則點亮主板內建 LED,放開按壓開關則關閉主板內建 LED
電路示意圖
範例程式
思考練習
如何做到:按一下開關亮,再按一下開關滅?
程式碼一
程式思路是,當按鈕按下時,反轉目前 LED 腳位 (13) 的狀態
你發現問題了嗎?事實上 LED 的明滅似乎不是我們所想的對嗎?這種不正常現象來自按鈕開關的機械彈跳 (Bounce) 特性,當按下按鈕時,D2 並不是一次從上拉的 HIGH 直接跳到 LOW,而是在 HIGH 與 LOW 之間來回切換好幾次才成為穩定的 LOW 狀態,這種彈跳的暫態現象通常可能持續 10 毫秒到 50 毫秒左右。
由於 loop() 速度極快,每次按下的瞬間,事實上 digitalRead() 已經讀了數十次以上的開關 HIGH(奇數次) LOW(偶數次) 切換的數值了,所以如果上述的開關機械彈跳特性在達到穩定前,digitalRead() 讀進來的是偶數次 (LOW) 的開關狀態,那麼下一個狀態仍然是回到奇數次 (HIGH),然而,我們的程式邏輯只判斷 swState == LOW 時改變 LED 狀態,因為不符合條件,故 LED 並不會切換狀態。
我們先在原來的程式碼中加寫一段監控計數的程式碼來觀察這個現象。
程式碼二
看到了嗎?當你只是按一下的瞬間,程式進入到判斷 swState 為 LOW 的狀態已經跑了十幾次了。
解決這個問題的辦法最直接的是時間延遲法,我們多準備一個延遲的時間,來避免按壓按鈕的機械彈跳特性,意即當偵測到按鈕被按下,D2 位準變 LOW 後,多延遲一段時間再判斷一次,若狀態還是 LOW,那表示彈跳情況已消失,按鈕已穩定在被按下的狀態,此時才去反轉 LED 明滅狀態。
程式碼三
可是老師,如果我按鈕一直按著,LED 會一直明滅耶。這也是由於 loop() 速度極快,每次按下的瞬間,事實上 digitalRead() 已經讀了數十次以上的開關 HIGH(奇數次) LOW(偶數次) 切換的數值了,所以你一直按著,loop() 還是一直在跑,每次 digitalRead() 讀進來的如果是偶數次 (LOW) 的開關狀態,那麼下一個狀態仍然是回到奇數次 (HIGH),如果 digitalRead() 的是奇數次 (HIGH),我們的程式邏輯判斷 swState == LOW 時,就會改變 LED 狀態。
我們這裡再多加一行程式碼,用一個空迴圈的寫法,讓 swState 是 LOW 狀態的時候,進入一個什麼動作都不會作的迴圈,然後一直等到 swState 狀態改變為 HIGH(也就是你再次放開的時候),才讓程式跳脫空迴圈,從頭再來過。
程式碼四
參考連結
Comments