GPIO當作輸入,我們使用這樣的例子:
from machine import Pin
P0 = Pin(0, Pin.IN)
P1 = Pin(1, Pin.OUT)
while True:
P1.value(P0.value())
這裡 P0 是 BOOT 那個按鈕開關(或者自己接個開關電路), P1外接一個 LED 燈。
當按鈕按下時,燈滅,放開按鈕時,燈亮。
舉這個例子是有點偷懶,主要的當時還沒有提到開關有 彈跳 (bounce) 的問題
若我們希望把按鈕當作是一個自鎖開關,也就是按一下開關,燈亮,再按一下開關,燈滅
程式改寫如下:
from machine import Pin
SW = Pin(0, Pin.IN)
LED = Pin(1, Pin.OUT)
LED_state = 0 # LED off at beginning
LED.value(LED_state)
while True:
if( SW.value() == 0): # button pushed
LED_state = not LED_state
LED.value(LED_state)
while (SW.value() == 0): # wait till button released
pass
程式果然按照設定的程序執行
我們在 GPIO 4上接了一個開關,並且像 BOOT 開關一樣接個上拉電阻,開關按壓時,獲得 0 電位。
我們程式改寫成:
SW = Pin(4, Pin.IN)
我們發現程式並沒有按照預期的執行,按鈕控制很不順暢!
然後用邏輯分析儀捕捉一下信號:
我們發現,在幾 ms 期間,按鈕應該是按下的,信號應該爲 0 ,顯然的,在按下的初期有彈跳的現象;事實上,在按鈕釋放的初期也可能會發生按鈕彈跳的現象。
我們透過一些延時方法,可以改善彈跳的問題,程式改寫如下,並加入一些 debug 訊息:
import time
from machine import Pin
SW = Pin(4, Pin.IN)
LED = Pin(1, Pin.OUT)
LED_state = 0 # LED off at beginning
LED.value(LED_state)
P=0
while True:
if( SW.value() == 0): # button pushed
P += 1
print(P)
LED_state = not LED_state
LED.value(LED_state)
if (SW.value() == 0):
time.sleep_ms(10)
while (SW.value() == 0): # wait till button released
pass
else:
time.sleep_ms(10)
結果彈跳的問題改善了。爲何延時是 10ms ? 其實這只是一個估算值,我們從邏輯分析儀上看出,彈跳的時間小於 1ms。您也可以試試其它數值,看看效果。
我們再參考了 BPI-leaf-S3 電路圖,發現:
在 BOOT (GPIO0)與 RESET 按鈕上面加了 C9,C10 電容,這個電容有硬體 debounce (去除彈跳) 的作用,因此我們在 BOOT 按鈕上實驗,比較不會獲得到彈跳的現象。接着,我們把一個電容加到 GPIO4 上的按鈕,彈跳的現象竟然也消失了!
要注意,加上電容或是延時,都不是最佳的解法,網路上可以查到更深入的做法,但那超出我們要探討的範圍了。