第3回:ボタン入力で LED を制御してみよう

つぶやき

今回のゴール

今回の目的は、ボタン入力によって LED を点灯/消灯 できる仕組みを作ることです。
具体的には以下を理解・実装できるようになることを目指します:

  • Pin.IN(入力モード)の使い方
  • プルアップ/プルダウン抵抗の役割と設定
  • ボタン入力を読み取って LED に出力する基本制御

これをクリアできれば、「押すと光る」「離すと消える」ような基本的なインタラクションが実現できます。


必要な部品

以下の部品を用意してください:

部品数量備考
Raspberry Pi Pico W1本体
タクトスイッチ(押しボタン)1ブレッドボード対応のもの
ジャンパーワイヤー数本オス-オスで可
ブレッドボード1実験用回路盤

なお、Pico 本体にはオンボード LED(“LED” 指定で扱う)があるため、外部 LED はこの段階では必須ではありません。


配線方法と回路構成

まずは回路構成を押さえておきましょう。以下のような接続で説明します:

🔽 配線イメージ(ブレッドボード接続例)

GP16 ---- ボタン ---- 3.3V
    |
    └── 内部プルダウンで GND に接続される(PULL_DOWN を有効にする場合)

“LED” は Pico のオンボード LED
  [Pico W ピン配置(例)]

   GP16 ---- ボタン ---- 3.3V
     |       
     └── 内部プルダウンでGNDに接続される
   'LED'(オンボードLED)

つまり:

  • ボタンの片側を Pico の GPIO(例:GP16)に接続
  • ボタンのもう一方を 3.3V に接続
  • Pin.PULL_DOWN を有効にすると、ボタンを押していないときはピンが GND 側に引かれて LOW(0)を読み、押すと HIGH(1)を読みます

(逆に、プルアップ方式を使う配線にして、Pin.PULL_UP を使うことも可能です。後述します)

ブレッドボード上での配線時には、タクトスイッチの向き(足の配置)を注意してください。一般的なタクトスイッチは中央をまたぐ形で足が繋がっているので、ブレッドボードの溝をまたいで設置し、片側が 3.3V、もう片側が GPIO に接続する形にします。
また、内部プル機能を使わずに外部抵抗でプルアップ/プルダウンを設けても構いません。


サンプルコード

以下のコードを実際に Pico に書き込んで動かしてみましょう:

from machine import Pin
import utime

# ボタン入力(GP16)
button = Pin(16, Pin.IN, Pin.PULL_DOWN)

# LED出力(オンボードLED)
led = Pin('LED', Pin.OUT)

while True:
    if button.value():  # ボタンが押されているか判定
        led.value(1)    # LED点灯
    else:
        led.value(0)    # LED消灯
    utime.sleep(0.1)    # チャタリング対策のため短い待ちを入れる

コードの解説:

  • Pin(16, Pin.IN, Pin.PULL_DOWN):GPIO16 を入力モードで初期化し、内部プルダウンを有効
  • button.value():ボタンが押されていれば 1、押されていなければ 0 を返す
  • 条件分岐で LED の出力を制御
  • utime.sleep(0.1):0.1 秒待機を入れて、高速変化やノイズの影響を抑える

このコードを実行すると、ボタンを押している間だけ LED が点灯し、離すと消灯する動作になります。


実行と動作確認

  1. Pico を PC に接続し、Thonny 等で main.py(または任意の名前)として保存
  2. コードを実行
  3. ボタンを押す → LED 点灯
  4. ボタンを離す → LED 消灯

もし動作しない場合は後述の トラブル対策 を参照してください。


重要ポイント

入力モード(Pin.IN)

出力時に Pin.OUT を使いましたが、入力を扱うときは Pin.IN を指定します。これにより、その GPIO は外部からの信号(HIGH/LOW)を読む側として働きます。

プルアップ/プルダウン抵抗

ボタン入力は、押していないときにはどの信号が来るか不安定(浮動状態)になりやすいため、「基準を与える抵抗」が必要です。これを内部的に実現するのが 内部プルアップ/プルダウン抵抗 です。

  • Pin.PULL_DOWN:ボタンが押されていないときは内部で GND に引き、LOW(0)になる
  • 押すと 3.3V が来て HIGH(1)になる
  • Pin.PULL_UP:逆の構成。押されていないときは HIGH、押すと LOW になる

MicroPython では、Pin(IN, Pin.PULL_UP)Pin(IN, Pin.PULL_DOWN) をコンストラクタに指定することで、内部プルを設定できます。

チャタリング対策(デバウンス)

実際の機械式スイッチ(タクトスイッチなど)は、押した・離した瞬間に接点が微細にバウンドして、短時間で複数の ON/OFF 信号が出ることがあります。これを チャタリング(バウンス) といいます。

多くの簡易的な方法では、スイッチ判定後に短時間待機することで複数回の反応を抑える(デバウンス)という手法が使われます。上記のコードの utime.sleep(0.1) はその目的もあります。ただし、応用用途ではソフトウェア的なデバウンス処理(フィルタリング、過去の状態比較、割り込み処理+遅延制御など)を使うこともあります。


応用アイデア

このボタン→LED 制御をベースに、以下のような拡張を試してみると学びが深まります:

  • トグル動作:ボタンを押すたびに LED の ON/OFF を切り替える
  • 複数ボタン制御:複数の入力ピンを用意して、それぞれ異なる LED やモーターを操作
  • 長押し/短押し判定:一定時間押されていたら別の動作をさせる
  • 割り込み(Interrupt)利用:ボタン入力をポーリング処理でなく割り込みで検出して制御
  • 外付け LED を使う:オンボード LED だけでなく、外部 LED や複数 LED を点灯制御する
  • PWM 制御との組み合わせ:ボタン押下で LED の明るさを変える(例:長押しでフェードイン)

これらを順に加えていくと、制御プログラムの応用力がどんどんついていきます。


トラブル対策ヒント

「ボタンを押しても LED が光らない」「LED が常に点灯/消灯している」などの問題に遭遇したら、以下をチェックしてみてください:

  • Pico W / MicroPython のバージョン:LED 制御や内部プル機能に制限があるバージョンだと動かないことがある
  • 使用ピンの指定ミス:Pin(16) と書いたら、実際に配線したのが GP16 かを確認
  • 内部プル設定の不一致:プルアップ方式に配線しているのに Pin.PULL_DOWN を使っている、など
  • 配線ミス:ボタンの接続が逆になっていたり、ボタン足の向きが間違っていたり
  • 接点不良:ジャンパ線やスイッチの接触不良
  • チャタリングで誤反応:スイッチを押した瞬間に動作が速すぎて目に見えない
  • 他のコードやスクрипトの競合:main.py のほかに実行中の別スクリプトが影響している

これらを順に確認すれば、多くの不動作原因を潰せます。

コメント