2025年8月12日火曜日

GPIO割り込み処理

 ここでは 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() が呼ばれたら

    1. LED を反転(点灯 ↔ 消灯)

    2. 🚫 割り込みを一時的に 無効化

    3. ⏲️ デバウンスタイマを DEBOUNCE_MS(ここでは 300 ms)で スタート

      • タイマ満了後に reenable_irq() へ

  • 🔄 reenable_irq() がタイマ満了で実行

    • 割り込みを再登録 → 再びボタン押下待ちへ戻る


こうして「押下→LED 反転→300 ms 無視→再待機」というサイクルを回し、チャタリングを防ぎながら確実に 1 押下 1 トグルを実現します。

0 件のコメント:

コメントを投稿

Google Spread Sheetの利用

  以前に ESP32 で作っていたものを、Raspberry Pi Pico W + MicroPythonで再現してみました。 1.Googleスプレッドシートの設定 1.Google Drive → 右クリック → Google スプレッドシート 2.作成して共有をクリック