ここでは GPIO 16 に付けたボタンを押すたびに LED が点いたり消えたり するスクリプトを動かしてみます。
割り込み(IRQ)って何?
-
ボタンの状態を ずっとループで監視(ポーリング) するのではなく、
「変化が起きた瞬間だけ」マイコンが自動で呼び出してくれる 仕組み。 -
イメージは ドアベル。押された瞬間だけ「ピンポーン♪」と鳴るので、ずっと耳を澄ます必要がない。
1.回路
GPIO16 はデジタル入力として使用し、内部プルアップを有効にします。GPIO15 は出力として設定します。なお、接続には 1kΩ(1キロオーム)の抵抗を使用します。
2.ソースコード
from machine import Pin, Timer
LED_PIN = 15
SW_PIN = 16
DEBOUNCE_MS = 300 # ボタンが完全に落ち着くまで待つ時間
led = Pin(LED_PIN, Pin.OUT, value=0)
sw = Pin(SW_PIN, Pin.IN, Pin.PULL_UP)
debounce_timer = Timer() # ONE_SHOT 用タイマ
def reenable_irq(t):
# 一度だけ呼ばれる。IRQ を再登録して入力を再監視
sw.irq(trigger=Pin.IRQ_FALLING, handler=led_toggle)
def led_toggle(pin):
led.toggle() # LED の ON/OFF 反転
sw.irq(handler=None) # 直ちに割り込み受付を停止
debounce_timer.init(
mode=Timer.ONE_SHOT,
period=DEBOUNCE_MS,
callback=reenable_irq
)
# 最初の IRQ 登録
sw.irq(trigger=Pin.IRQ_FALLING, handler=led_toggle)
📝 処理の流れ
-
🛠️ GPIO の初期設定
-
LED_PIN(15)
を 出力にして LED を消灯 (value=0
) -
SW_PIN(16)
を 入力+プルアップに設定
-
-
⏲️ ワンショットタイマ生成
-
Timer()
を 1 個確保し、デバウンス専用で使用
-
-
🎯 最初の割り込み登録
-
sw.irq(trigger=Pin.IRQ_FALLING, handler=led_toggle)
-
ボタンを押して電圧が下がった瞬間に
led_toggle()
が走る
-
-
💡
led_toggle()
が呼ばれたら-
LED を反転(点灯 ↔ 消灯)
-
🚫 割り込みを一時的に 無効化
-
⏲️ デバウンスタイマを
DEBOUNCE_MS
(ここでは 300 ms)で スタート-
タイマ満了後に
reenable_irq()
へ
-
-
-
🔄
reenable_irq()
がタイマ満了で実行-
割り込みを再登録 → 再びボタン押下待ちへ戻る
-
こうして「押下→LED 反転→300 ms 無視→再待機」というサイクルを回し、チャタリングを防ぎながら確実に 1 押下 1 トグルを実現します。
コメント
コメントを投稿