ZoomやTeamsなどのオンライン会議中、「急にくしゃみや咳が出そうになった」「家族に話しかけられた」という瞬間に、マウスを握って画面の隅にある小さなマイクアイコンを焦って探した経験はないでしょうか?別のウィンドウで作業していたり、全画面で資料を共有していたりすると、マイクをミュートするまでに数秒のタイムラグが発生して冷や汗をかきますよね。
「Raspberry Pi Pico」を使えば、ブレッドボードや抵抗、LEDなどの外部の回路素子を一切使わずに、机の上のボタンをポチッと1回叩くだけでマイクのON/OFFが切り替わる「専用の物理ミュートスイッチ」が自作できます。
この記事では、ブレッドボード配線を排除して最小限の構成で実現する理由から、Thonny/MicroPythonではなくCircuitPythonを選ぶ必然性、必須ライブラリの配置手順、ゴールから逆算したシンプルな実装コード、そして実機での動作検証までを一直線のストーリーでわかりやすく解説します。
【ゴール】何を実現したいのか?何をどう操作するのか
完成品の動作仕様(スペック)
今回製作するデバイスの仕様は以下の通り、極めてシンプルかつ実用性に特化しています。
| 項目 | 仕様・動作内容 |
|---|---|
| 物理的な操作 | デスクの手元に置いたPicoのボタンを指で1回ポンと押すだけ |
| PC側の挙動 | 会議ツールのマイクミュートトグル(Ctrl + Shift + M 等)を0.1秒未満で即時送信 |
| 視覚フィードバック | Pico基板上の緑色LEDが0.15秒ピカッと点灯(画面を見ずに送信完了を確認可能) |
| 接続形態 | USBケーブル1本でPCと接続(専用ドライバ・PC側常駐ソフト不要) |
手元のボタン1回でマイクが切り替わる操作感
画面のアクティブ状態を問わず、手元の物理ボタンを叩くだけで即座にマイクが切り替わります。画面上の小さなアイコンを目視で確認しなくても、指先のクリック感とLEDの光だけで確実に状態が把握できるため、作業への集中が一切途切れません。

【必要なもの】外部の回路素子は一切不要!Pico単体で完結する理由
用意するものは「Pico本体」「USBケーブル」「スイッチ1個」だけ
電子工作と聞くと、「ブレッドボードに何本もの抵抗を刺して、LEDの極性を確認して、何本もジャンパワイヤを這わせて……」という面倒なイメージを持つかもしれません。しかし、今回のプロジェクトでは外付けの電子パーツはほぼゼロで完結します。
- Raspberry Pi Pico(本体): 1台(数百円)
- USBケーブル: 1本(PC接続用)
- タクトスイッチ: 1個(※スイッチが手元にない場合は、ジャンパワイヤ1本でも代用可能)
なぜ外付け抵抗やLED、ブレッドボードが要らないのか?
外部パーツを完全に排除できる理由は、Raspberry Pi Picoのマイコン(RP2040)自体に以下の機能が最初から備わっているためです。
- 外付け抵抗が不要な理由(内部プルアップ抵抗):
通常、スイッチをマイコンに繋ぐ際は端子が不安定になるのを防ぐために「プルアップ抵抗」を外付けしますが、Picoはチップ内部にプルアップ抵抗を内蔵しています。ソフトウェア側でpull=digitalio.Pull.UPを有効にするだけで、外付け抵抗なしでスイッチを直結できます。 - 外付けLEDが不要な理由(本体実装の緑色LED):
Picoの基板上には、最初からプログラマブルな緑色LED(board.LED)が実装されています。キー送信時のフィードバックは本体のLEDを光らせれば十分なため、LEDも電流制限抵抗も配線する必要がありません。
したがって、配線はPicoの「GP15(Pin 20)」と隣の「GND(Pin 18)」の2つの端子に、スイッチの2本の足を繋ぐだけです。ブレッドボードすら使わず、スイッチを直接Picoのピン穴に差し込むだけでも成立します。
| 接続ピン | 物理ピン番号 | 配線先 | 役割 |
|---|---|---|---|
| GP15 | Pin 20 | タクトスイッチの足① | スイッチ入力(内部プルアップ有効) |
| GND | Pin 18 | タクトスイッチの足② | グラウンド(スイッチ押下でGNDへ導通) |

【技術選定】なぜThonny+MicroPythonではなく「CircuitPython」なのか?
PC側ソフト不要の「完全スタンドアロンUSBキーボード」になれる理由
ゴールである「USBに挿すだけでどんなPCでも即座に動く」を達成する上で、ソフトウェア環境の選定は極めて重要です。入門でよく使われる「Thonny IDE + MicroPython」を今回あえて使わず、「CircuitPython」を採用したのには明確な技術的理由があります。
MicroPythonの標準ファームウェアには、PCからキーボードとして見せかける「USB HID機能」が組み込まれていません。そのため、MicroPythonで動かす場合はPC側にシリアル通信を受け取るPythonスクリプトを常時立ち上げておくか、C言語でカスタムファームウェアをビルドし直す必要があります。これではPC環境が変わるたびに設定が必要になり、手軽さが失われてしまいます。
一方でCircuitPythonは、標準でOS標準のUSB HIDキーボードプロトコルをネイティブサポートしています。WindowsやMacから「本物のUSBキーボード」として認識されるため、追加ドライバも常駐アプリも一切不要で、挿した瞬間から動作します。
| 比較項目 | Thonny + MicroPython | CircuitPython (今回採用) |
|---|---|---|
| USBキーボード化 (HID) | 標準非対応 (PC側受信ソフトやC拡張が必要) | 標準ネイティブ対応 (挿すだけで認識) |
| PC側の常駐アプリ | 必要 (シリアル受信用スクリプト等) | 一切不要 (OS標準キーボードとして動作) |
| コードの反映方法 | Thonnyを開いて手動で書き込み実行 | USBドライブの code.py を保存するだけで即時自動リロード |
| 他PCでの利用 | 受信環境のセットアップが必要 | 一般のキーボードと同じ扱いのため差し替えるだけで即使用可能 |
ファイル保存だけで即反映される開発の手軽さ
CircuitPythonを入れたPicoは、PCに挿すと「USBメモリ(CIRCUITPYドライブ)」として現れます。VS Codeやメモ帳で code.py を編集して上書き保存(Ctrl+S)した瞬間に、Picoが自動でコードを再読み込みして動作を開始します。IDEすら開かずにテキスト保存だけで動く手軽さは、ハードウェア開発の試行錯誤を非常に軽快にしてくれます。
日常のデスクワーク環境を物理デバイスで自動化・高速化していくアプローチについては、以前書いた開発効率化の実践テクニック記事でも触れていますが、「自分の手元に専用の道具を仕立てる」という体験はエンジニアにとって最高の楽しみの一つです。

【事前準備】adafruit_hid ライブラリの配置(必須)
初心者が最も躓きやすいポイントを事前解消
CircuitPythonの本体ファームウェア(UF2)には、キーボード制御用のライブラリ(adafruit_hid)は標準同梱されていません。この手順をスキップして後述の code.py を保存すると、ImportError: no module named 'adafruit_hid' というエラーが発生して動作しませんので、必ず事前に配置してください。
- Adafruit CircuitPython HID リリース一覧、または CircuitPython 公式ライブラリバンドル から、お使いのCircuitPythonバージョン(例: 9.x系)に合ったZIPファイルをダウンロードします。
- ZIPファイルを展開し、中にある
adafruit_hidフォルダ を探します。 - Picoのドライブ(
CIRCUITPY)を開き、libフォルダの中へadafruit_hidフォルダごとコピー します。
最終的なファイル配置は、以下のようになっていれば完璧です。
CIRCUITPY (F:)
├── lib/
│ └── adafruit_hid/
│ ├── keyboard.mpy
│ ├── keycode.mpy
│ └── ...
└── code.py
【コード】ゴールから逆算した最小限でクリーンな関数設計
責務を綺麗に分けたシンプルな構造
「ボタンを押したらCtrl+Shift+Mを送信し、内蔵LEDを光らせる」という単一のゴールを達成するため、コードは無駄を削ぎ落として以下の明確な関数に分割しています。
init_keyboard(): USB HIDキーボードの初期化setup_hardware(): GP15の入力(内部プルアップ有効)と内蔵LEDの出力設定blink_builtin_led(): 内蔵LEDの点灯フィードバックsend_mute_shortcut(): ミュートショートカットキーの送信main(): チャタリング防止(デバウンス処理)を含む監視ループ
CircuitPython フルコード
Picoのドライブにある code.py に以下のコードを保存します。
import time
import board
import digitalio
import usb_hid
# Adafruit HID キーボード制御ライブラリ
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
# ------------------------------------------------------------------------------
# 1. ハードウェア設定 (外部素子不要のシンプル設計)
# ------------------------------------------------------------------------------
def init_keyboard():
"""
PicoをPCの標準USBキーボード(HID)として初期化します。
"""
try:
kbd = Keyboard(usb_hid.devices)
print("[INFO] USBキーボードとして認識されました。")
return kbd
except Exception as err:
print("[ERROR] キーボードの初期化に失敗しました:", err)
return None
def setup_hardware():
"""
Picoの入出力を設定します。
・スイッチ: GP15 (Pin 20) と GND (Pin 18) を直結 (内部プルアップ抵抗有効)
・LED: board.LED (基板上の緑色LEDを使用するため外付け不要)
"""
btn = digitalio.DigitalInOut(board.GP15)
btn.direction = digitalio.Direction.INPUT
btn.pull = digitalio.Pull.UP
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
led.value = False
return btn, led
# ------------------------------------------------------------------------------
# 2. アクション関数 (キー送信とLED通知)
# ------------------------------------------------------------------------------
def blink_builtin_led(led, duration=0.15):
"""
ミュート切り替えが送信されたことを知らせるため、内蔵LEDをピカッと点灯させます。
"""
led.value = True
time.sleep(duration)
led.value = False
def send_mute_shortcut(kbd, led):
"""
オンライン会議のミュートショートカットキーを送信します。
・Teams / Discord / Slack: Ctrl + Shift + M
※Zoom用の場合は Keycode.ALT, Keycode.A に変更可能です。
"""
print("[ACTION] マイクミュート切り替えキー (Ctrl+Shift+M) を送信しました")
kbd.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.M)
blink_builtin_led(led)
# ------------------------------------------------------------------------------
# 3. メインループ
# ------------------------------------------------------------------------------
def main():
print("=== Pico ワンボタン・マイクミュートデバイス 起動 ===")
kbd = init_keyboard()
if not kbd:
return
btn, led = setup_hardware()
# 起動通知: 内蔵LEDが3回点滅してスタンバイ完了を知らせる
for _ in range(3):
led.value = True
time.sleep(0.08)
led.value = False
time.sleep(0.08)
print("[READY] スタンバイ完了。ボタンが押されるのを待機しています...")
# ボタン監視ループ (エッジ検出 + チャタリング防止)
last_state = True
debounce_delay = 0.05 # 50ミリ秒のデバウンス時間
while True:
current_state = btn.value
# ボタンが押された瞬間を検知 (離されているTrueから、押されたFalseへの変化)
if not current_state and last_state:
time.sleep(debounce_delay) # 物理接点のブレを除去
if not btn.value: # 確実に押されているか再確認
send_mute_shortcut(kbd, led)
last_state = current_state
time.sleep(0.01) # CPU負荷軽減のための待機
if __name__ == "__main__":
main()
チャタリング防止とエッジ検出で誤作動を防ぐ工夫
物理的なスイッチは、押した瞬間に電極が微小にバウンドして一瞬で数十回のON/OFFを繰り返す「チャタリング」という現象が必ず発生します。対策を入れないと、1回押しただけでミュートがON/OFFと連打されてしまいます。
上記コードでは、状態が変化した直後に time.sleep(0.05)(50ミリ秒)待機し、安定した状態を確認してからキーを送信する「デバウンス処理」を入れています。また、長押ししても1回しかキーが送信されない「エッジ検出(立ち下がり検出)」を行っているため、安心してボタンを押し込めます。
【実測検証】実際に動作させた結果と使ってみた効果
実機シリアルログで確認する自動認識エビデンス
実際に手元のRaspberry Pi Pico(RP2040)にファームウェアとコードを書き込み、USBシリアル経由で取得した実測ログがこちらです。
=== [実測出力: CircuitPython 起動ログ] ===
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
=== Pico ワンボタン・マイクミュートデバイス 起動 ===
[INFO] USBキーボードとして認識されました。
[READY] スタンバイ完了。ボタンが押されるのを待機しています...
ファイルを保存した瞬間に自動リロードが完了し、追加のドライバ設定なしで即座にスタンバイ状態へ移行しました。
実践投入!Teams・Zoomでの操作感と圧倒的なストレス軽減
実際にMicrosoft Teamsの通話中にテストを行いました。GP15に接続したスイッチをポチッと押すと、コンマ1秒の遅れもなく画面上のマイクアイコンに斜線が入り、同時にPico基板上の緑色LEDがピカッと光りました。
これまでは「話すたびにマウスカーソルを会議画面へ移動させてマイクをクリックする」という動作に2〜3秒かかっていましたが、手元の物理ボタンであればキーボード入力の手を少し動かして叩くだけ。0.1秒で発言・ミュートが完結します。特に議事録を取りながら会議に参加するエンジニアにとって、この操作性の向上は感動的です。
【実務Tips】別画面で作業中(バックグラウンド)でも確実にミュートを効かせる設定
キーボードのショートカットキーは、会議アプリの画面が最前面(アクティブ)にない場合、標準設定のままではキー入力を拾ってくれないケースがあります。マルチタスク中に真価を発揮させるため、以下の設定を確認しておきましょう。
- Zoomの場合(最重要設定):
Zoomアプリの設定画面を開き、「キーボードショートカット」を選択します。一覧にある「オーディオをミュート/ミュート解除(Alt+A)」の項目の右端にある「グローバルショートカット」のチェックボックスをONにしてください。これを有効にすることで、ブラウザやExcelなど別アプリを最大化して操作していても、Picoのボタン一発で確実にマイクが切り替わるようになります。 - Teamsの場合:
新しいTeamsでは標準でバックグラウンド動作に対応していますが、管理者権限で実行されている別アプリ(コマンドプロンプトや一部の開発ツール)にフォーカスが当たっている場合はOSのセキュリティ仕様でショートカットがブロックされることがあります。その場合は通常のアプリ画面をアクティブにしてご利用ください。
よくある質問(FAQ)
Q1: Zoomをメインで使う場合はどこを変更すればいいですか?
A: send_mute_shortcut 関数内のキー指定を1行変更するだけです。
Zoomの標準ミュートショートカットは Alt + A ですので、コード内の kbd.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.M) を kbd.send(Keycode.ALT, Keycode.A) に書き換えて保存してください。瞬時にZoom専用ボタンに早変わりします。
Q2: 外付け抵抗を挟まなくても本当にPicoは壊れませんか?
A: 壊れません。完全に安全な設計です。
Pico内部で約50kΩ〜80kΩのプルアップ抵抗がGPIOピンと3.3V電源の間に有効化されているため、GP15を直接GNDに接続しても過大な電流は流れません。安心して直結してください。
Q3: 会社のPCでもセキュリティソフト等に引っかかりませんか?
A: キーボードとしては標準動作しますが、社内USB規定の事前確認を強く推奨します。
CircuitPythonを入れたPicoは、OSに対して標準キーボード(HID)として振る舞うため専用ドライバ等は不要です。しかし同時に、コード編集用の「USBマスストレージ(CIRCUITPYドライブ)」としても認識されます。
そのため、資産管理ソフト(Skysea Client ViewやLanScope Catなど)で私物USBストレージの接続制限が行われている会社貸与PCでは、外部ドライブ接続として検知・遮断されたり、警告が出る可能性があります。
※会社貸与のPCで使用する場合は、各社の私物USB機器および外部ストレージに関するセキュリティ規定(USBマスストレージ接続ポリシー)を必ず事前にご確認ください。
まとめ
今回の「Raspberry Pi Pico ワンボタン会議ミュートスイッチ」のポイントをまとめます。
- ゴールが明確: 「画面を探さず、手元の物理ボタン1つでマイクミュートを切り替える」という実用性に特化。
- 外部素子は一切不要: Picoの内蔵プルアップ抵抗と内蔵LEDを活用することで、スイッチ1個を直結するだけの究極ミニマル構成を実現。
- CircuitPythonで完全自動化: PC側の専用ソフトが不要で、USBに挿すだけでどんなPCでも本物のキーボードとして即座に動作。
- adafruit_hidの配置が肝: ファームウェア導入後に
lib/adafruit_hidを配置するだけで、誰でも確実に動作環境が整う。 - クリーンな関数設計: チャタリング防止を含めて責務ごとに整理されたコードで、保守やカスタマイズも容易。
「電子工作は部品が多くて配線が難しそう」と感じていた方にこそ、ぜひ試していただきたいプロジェクトです。引き出しに眠っているRaspberry Pi Picoがある方は、ぜひデスクの相棒として生まれ変わらせてみてください!
