前回は LED を光らせる「出力」の使い方を学びました。今回は反対に、外の世界から Pico へ信号を伝える「入力」を扱います。もっとも身近な入力部品が タクトスイッチ(押しボタン) です。
- タクトスイッチの 4 ピン構造と内部の繋がり方
- プルアップ抵抗(10kΩ)の役割と「押すと LOW」になる理由
- 入力と出力を組み合わせて「押している間だけ LED 点灯」を作る
PycoBlocks(MicroPythonモード) を開き、左カテゴリ「Pico 電子工作 / デジタル入力」から「デジタル入力 ピン GP14 を読み 変数 btn に入れる」ブロックを使うのが今回の主役です。

タクトスイッチの仕組み
今回の主役 タクトスイッチ(押しボタン) は、押している間だけ電気が流れるスイッチです。仕組みは姉妹シリーズ「電子工作のきほん」#06 でくわしく図解しているので、まずはその図でおさらいしましょう。見た目は 4 本足ですが、同じ側から出る 2 本は内部で常に繋がっており、配線上は実質 2 つの端子として扱います。

なぜ押すと繋がるのか。中身を横から見ると、ボタンの下に金属のドーム板があり、押した瞬間だけドームが沈んで両側の接点を橋わたしする 構造になっています。離せばドームが元に戻り、また切れます。

⚠️ 挿す向きに注意(90 度回転で常時 ON)
なぜプルアップ抵抗が必要?
Pico の入力ピンは「何も繋がっていない」状態だと電圧が不安定(フロート状態)になり、0V と 3.3V の間をふらふらして誤動作します。そこで 普段は HIGH(3.3V)に固定 しておき、ボタンを押したときだけ GND と短絡させて LOW にする回路を組みます。
「普段 HIGH に引き上げておく」役割の抵抗をプルアップ抵抗 と呼びます。値は 10kΩ(茶・黒・橙・金)が標準です。逆に「普段 LOW に引き下げておく」プルダウン抵抗 を使う方法もあります。下の回路図で両者を並べて比較してみましょう。

どちらの方式でも、GP14 は 抵抗を通していつも電源か GND のどちらか一方に必ず繋がっている 点が重要です。これにより「何にも繋がっていない不安定な状態」を避けられます。ボタンを押した瞬間だけ、もう一方の電位に切り替わって値が反転します。
| 状態 | GP14 の電圧 | btn.value() |
|---|---|---|
| 押していない | 3.3V(HIGH) | 1 |
| 押している | 0V(LOW) | 0 |
⚠️ プルアップでは「押されたら 0」
btn.value() == 0 で押下を判定します。「1 で判定」と書いてしまい動かない、というのが入門時の定番のつまずきです。ステップ1:ボタンの状態を読んでみよう
GP14 → ボタンの片側 → ボタンのもう片側 → GND の経路に加えて、3V3 → 10kΩ プルアップ抵抗 → GP14 も並列に配線します。下の実体配線図は PycoBlocks の配線図ビューアで自動表示されるもので、ブロックの 「プルアップ」 プルダウン(外付け(PU) / 外付け(PD) / 内部(PU))に応じて抵抗の有無や接続が切り替わります。

PycoBlocks では「デジタル入力 ピン GP14 を読み 変数 btn に入れる」ブロックを「ずっと繰り返す」の中に入れて、ボタンの値を継続的に読み取ります。

from machine import Pin
import utime
while True:
btn = Pin(14, Pin.IN).value()
utime.sleep(0.1)
動作確認のコツ:Thonny の 変数ビュー を開いておくと、ボタンを押すたびにbtn の値が 1 ⇄ 0 に切り替わる様子が見えます。0.1 秒間隔で読んでいるので、人間の指の動きに対しては十分な反応速度です。
プルダウン抵抗で組むとどう変わる?プルアップとは逆に、普段は LOW(0V)に固定 しておき、ボタンを押したときだけ 3V3 と短絡させて HIGH にする回路です。3V3 → ボタン → GP14 と接続し、さらにGP14 → 10kΩ プルダウン抵抗 → GND を並列に配線します。PycoBlocks ではブロックのプルダウンメニューを 「外付け(PD)」 に切り替えると、配線図ビューアが自動で次の図に変わります。

| 方式 | 普段の電圧 | 押していない | 押している |
|---|---|---|---|
| プルアップ(PU) | HIGH (3.3V) | btn.value() == 1 | btn.value() == 0 |
| プルダウン(PD) | LOW (0V) | btn.value() == 0 | btn.value() == 1 |
プルダウンに切り替えると、「押されたら 1」 という直感的な値の対応に変わります。代わりに、ボタンの片方を 3V3、もう片方を GP14 に挿し替えるなど、ブレッドボード上の配線が変わるので注意しましょう。プログラム側も if btn.value() == 1 のように判定を反転させる必要があります。
どちらを使うべき?電子工作の世界では プルアップ方式が主流 です。理由は (1) 多くのマイコンが内部プルアップを内蔵していて外付け抵抗を省略しやすい、(2) 配線ミスで GP と 3V3 が短絡しても電流が小さい(押下時のみ GND 経由)ため安全、の二点です。本シリーズも以降はプルアップで統一しますが、「押したら 1」の直感を優先したい場合はプルダウンを選んでも構いません。
ステップ2:押されたら LED を光らせよう
入力と出力を組み合わせます。GP14 のボタンが押されている(値が 0)の間だけ、GP15 の LED を点灯させましょう。PycoBlocks では 「もし ◯◯ だったら」 ブロックの条件部に「ピン GP14 の入力値」ブロックを差し込みます。

from machine import Pin
while True:
if Pin(14, Pin.IN).value() == 0:
Pin(15, Pin.OUT).value(1) # 押下中: 点灯
この例では 「離したときの消灯処理」 を書いていないので、一度押すと LED が点きっぱなしになります。実際に動かしてみて、「離したときに消える」が必要な理由を体感してみましょう。→ 課題3-3-2 で else: 側を追加して完成形にします。
ステップ3(コラム):内部プルアップで外付け抵抗を省略する
RP2040 マイコンは 内部にプルアップ抵抗(≒ 50〜80kΩ) を持っており、Pin.PULL_UP を指定することで外付けの 10kΩ 抵抗を省略できます。回路がシンプルになるので、本シリーズの #04 以降ではこちらを多用します。
from machine import Pin
# 内部プルアップを有効化(外付け 10kΩ 抵抗は不要)
btn = Pin(14, Pin.IN, Pin.PULL_UP)
while True:
if btn.value() == 0:
print('押された!')
📝 外付け抵抗と内部プルアップの使い分け
Pin.PULL_UP で省略する、という方針が分かりやすいです。電気的にはどちらも同じ「普段 HIGH・押されたら LOW」の挙動になります。内部プルアップは約 50〜80kΩ と大きめなので、強いノイズ環境では外付けの 10kΩ のほうが安定する、という違いだけ覚えておきましょう。演習課題
課題3-3-1:プルアップ抵抗を入れない場合の問題点
もし回路から 10kΩ プルアップ抵抗を取り外し、内部プルアップも使わなかったとすると、ボタンを押していないときに btn.value() はどんな値を返すでしょうか。また、その挙動がなぜ「マズい」のかを 2〜3 行で説明してみよう。
▶ 模範解答と解説を見る
# 答え:
# - プルアップが無いと、ピンは『どこにも繋がっていない』状態になる。
# - 周囲のノイズや指の静電気で電圧がふらつき、btn.value() は 0 と 1 を
# 不規則に行き来する(フロート状態)。
# - 「押されていないのに押されたと判定される」誤動作が起こり、
# プログラムが意図通りに動かない。
# - これを防ぐために、普段 HIGH に固定するプルアップ抵抗が必要。
解説: デジタル入力ピンは「電源(HIGH)か GND(LOW)に確実に繋がっている」状態でないと、値が安定しません。プルアップ(HIGH 側に固定)・プルダウン(LOW 側に固定)のどちらかを必ず入れる、が電子工作の鉄則です。Pico の場合は内部プルアップが使えるので、外付け抵抗を忘れてもPin.PULL_UP 引数を付け足せばリカバリーできます。
課題3-3-2:押している間だけ LED を点灯させよう
GP14 にタクトスイッチ(プルアップ抵抗付き)、GP15 に LED(330Ω 抵抗付き)を配線し、ボタンを押している間だけ LED が光り、離すと消える プログラムを書こう。

▶ 模範解答と解説を見る
ブロックの組み合わせ例:

from machine import Pin
while True:
if Pin(14, Pin.IN).value() == 0:
Pin(15, Pin.OUT).value(1) # 押下中: 点灯
else:
Pin(15, Pin.OUT).value(0) # 離す: 消灯
解説: ポイントは else: 側で必ず消灯 を書くこと。「もし押されたら点灯」だけだと、一度押した後 value(0) の命令が実行されないため LED が点きっぱなしになります。if-else 構造で 「両方の状態を毎回書き直す」 のがデジタル入出力プログラムの基本パターンです。「ずっと繰り返す」の中で 1 秒あたり数千回判定が走っているので、人間にはボタンに完全連動して見えます。
課題3-3-3:押している間だけ LED を点滅させよう
課題3-3-2 と同じ配線で、今度は ボタンを押している間だけ0.2 秒間隔で LED が点滅、離したら消灯するプログラムを書こう。(押している間は速い点滅、離せばずっと消灯)
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

from machine import Pin
import utime
while True:
if Pin(14, Pin.IN).value() == 0:
Pin(15, Pin.OUT).value(1)
utime.sleep(0.2)
Pin(15, Pin.OUT).value(0)
utime.sleep(0.2)
else:
Pin(15, Pin.OUT).value(0)
解説: 「もし押されていたら」の中に #02 で学んだ点滅パターン(点灯→待つ→消灯→待つ)をそっくり入れるだけで完成します。else: 側では消灯を 1 行書くだけで OK。押している間は utime.sleep(0.2) で 0.2 秒ずつ止まりますが、離した直後は即座に else 側に入り消灯するため「離した瞬間に止まる」自然な反応に見えます。発展:utime.sleep の値を小さくすると速い点滅、大きくするとゆっくり点滅になります。押している時間に応じて点滅速度を変える(カウンタを使う)応用も面白いです。
まとめ
- タクトスイッチは内部で 2 ピンずつ常時繋がっている。向きを 90 度間違えると押しっぱなし状態になる。
- 入力ピンは「フロート状態」だと値が不安定。プルアップ抵抗(10kΩ) で普段 HIGH に固定する。
- プルアップ回路では 「押されたら LOW(0)」。条件文は
if btn.value() == 0:と書く。 - RP2040 は 内部プルアップ(
Pin.PULL_UP)が使えるので、外付け抵抗を省略可能。 - 「ずっと繰り返す」+
if-elseで両方の状態を毎回書き直すのがデジタル入出力の基本パターン。
次の記事では PWM(Pulse Width Modulation) を扱います。今までは LED の「点灯/消灯」の二択だけでしたが、PWM を使うとデューティ比という割合の指定で「うっすら光らせる」「だんだん明るくする」 といった中間表現が可能になります。