mcpField
M
m5-onboard

m5-onboard

github.com/anthropics開発45.1k3.1k 回インストール1 日前に更新
リポジトリ

m5-onboard について

m5-onboardは、M5Stack ESP32デバイスをセットアップするスキルです。USB検出とモデル識別からUIFlow 2.0の書き込み、MicroPythonアプリの導入まで行い、アプリ更新やハードウェアテストにも対応します。

主な機能

  1. 01USBデバイスの検出とモデル識別
  2. 02UIFlow 2.0の取得と書き込み
  3. 03MicroPythonアプリのインストール
  4. 04I2C、LCD、スピーカー、ボタンのテスト

活用シーン

  1. 01新しいM5Stackデバイスのセットアップ
  2. 02書き込み済みデバイスのアプリ導入・更新
  3. 03I2C、画面、音声、ボタンの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/anthropics/claude-plugins-official --skill m5-onboard

インストール後、Claude Code で/m5-onboardを入力して読み込まれたか確認します。

詳細

M5Stack のセットアップ

このスキルは、M5Stack ESP32 デバイスのコールドスタート時の一連の作業を自動化します。USB 接続での検出、モデルの特定、UIFlow 2.0 の書き込み、そしてデバイスがユーザーソフトウェアを起動するように、MicroPython アプリバンドルを /flash/ に転送します。提供するアプリ(Claude Buddy、Snake、Hello)は、BLE または USB 経由で通信します。このワークフローは macOS、Linux、Windows で動作します。このスキルは M5Stack Basic v2.6(CH9102 ブリッジ、ESP32-D0WDQ6-V3、16 MB フラッシュ)を対象に開発し、Core ファミリーの他のモデルにも対応するよう一般化しました。現在のデフォルトのターゲットは Cardputer-Adv(ESP32-S3、ネイティブ USB)です。

スクリプトの場所

このスキルはリファレンスとして cwc-makers プラグインの一部として提供されていますが、実行可能なスクリプトと buddy/ アプリバンドルは、https://github.com/moremas/build-with-claude のローカルクローン内にあります(/maker-setup コマンドでこのクローンを作成します)。以下に示す scripts/*.py の呼び出しは、すべてこのクローン内の onboard/ ディレクトリから実行してください。そうすることで、--apps buddy が隣接する buddy/device/ ペイロードを参照できます。

使用するタイミング

ユーザーが M5Stack デバイスを接続し、セットアップを希望しているときに使用します。判断手順は次のとおりです。

  • 未セットアップまたは不明なデバイス → onboard.py --apps buddy を最初から最後まで実行します(検出 → 特定 → 書き込み → アプリのインストール)。これがデフォルトの手順です。
  • すでにファームウェアを書き込み済みで、アプリのインストールまたは更新だけを希望するデバイス → install_apps.py --src buddy を実行します(または、.py ファイルを含むディレクトリを指定する任意の --src <path>)。
  • ファームウェアを書き込み済みのデバイスで、何かがうまく動作しない場合 → smoke_test.py を実行します(I2C、LCD、スピーカー、ボタンのチェック)。
  • バス上のデバイスや、そのデバイスで可能な操作を確認したい場合 → smoke_test.py を実行します。

複数のデバイスが接続されている場合は、対象のポートを尋ねてください。推測してはいけません。以前に使ったことのあるデバイスをユーザーがセットアップしている場合(例:「前回と同じもの」や「もう1台の Buddy」)、特に指示がなければ --apps buddy をデフォルトにします。

想定するバリアント

このスキルを使用する環境では Cardputer-Adv ボードが圧倒的に多いため、onboard.py のデフォルトは --variant cardputer-adv です。実際の運用では、次のようになります。

  • ユーザーがモデルについて何も言わなければ、デフォルトを使用します。ほぼ間違いなく Cardputer-Adv を持っています。
  • ユーザーが「Cardputer」(「Adv」なし)と言った場合は、確認してください。2つのモデルはフォームファクターが同じですが、異なるファームウェアイメージを使います。誤ったイメージを書き込むと、デバイスは起動ループに陥ります。
  • ユーザーが別のボード(「Core2」、「CoreS3」、「Basic」、「Fire」)を指定した場合は、対応する --variant を明示的に渡します。デフォルトは適用されません。
  • どちらもチップは ESP32-S3 であり、UIFlow の書き込み前には detect.py で Cardputer と Cardputer-Adv を見分けられません(ネイティブ USB-JTAG の VID が同じで、書き込み前の I2C プローブもないためです)。したがって、これはハードウェアの指紋による判別ではなく、ユーザーの意図を確認する質問です。

ワークフロー

メインのオーケストレーターは scripts/onboard.py です。サブスクリプトを順番に実行し、再起動待ち、MAC の取得、進捗の報告など、各スクリプト間の受け渡しを処理します。ユーザーが一部のみの実行を希望している場合を除き、サブスクリプトを自分で組み合わせるのではなく、これを直接呼び出してください。

デフォルトのセットアップコマンド(新しい Cardputer-Adv に Buddy バンドルをインストール):

python3 scripts/onboard.py --apps buddy

Claude Code の Bash ツールから実行する方法。 onboard.py をフォアグラウンドの Bash コマンドとして呼び出してはいけません。Bash ツールは出力を取得し、コマンドが終了するまでアシスタントに返しません。このコマンドは2~3分かかります。無出力の状態はハングと見分けがつかず、ボタン操作のプロンプトがユーザーに表示される前に、アシスタントが通常は諦めてしまいます。代わりに、必ず run_in_background: true を指定し、tee でログファイルに出力してから、Monitor ツール(または Read 経由で定期的に tail)を使って、ステージのバナー、ハートビート、プロンプトをリアルタイムでユーザーに表示してください。2>&1 では解決しません。進捗はすでにすべて stderr に出力されており、ターミナルでは問題なく表示されます。必要なのはリダイレクトではなく、ストリーミングの仕組みです。うまくいくパターンは次のとおりです。

# Launch (background, tee log):
python3 scripts/onboard.py --apps buddy 2>&1 | tee /tmp/m5-onboard.log

# Monitor (surfaces key events without drowning in byte-progress spam):
tail -f /tmp/m5-onboard.log | grep -E --line-buffered \
  "^====|heartbeat|Heads up|Enter download mode|download mode!|rebooted into UIFlow|Manual reset|DONE|ERROR|Error|Traceback|FAIL|failed|No USB|not detected|Attempt [0-9]|Device already in download|Download mode port|Post-flash port|Waiting for device"
物理的な手順をユーザーに伝える(必須)

ネイティブUSBボードでは、手動でボタンを押さないとフラッシュ段階に進めません。ソフトウェアによる操作方法はありません。監視中のログに Enter download mode が表示されたとき、またはスクリプトが FLASH 段階で待機しているように見えるときは、続行する前に必ず停止し、ユーザー自身の言葉で、Cardputer の背面で次の操作を行うよう伝えてください。

  1. G0 ボタンを押したままにします
  2. G0 を押したまま、RST ボタンを短く押して離します
  3. さらに約 1 秒間 G0 を押したままにしてから、離します
  4. 画面が完全に暗くなれば、ダウンロードモードが有効になっています

画面が暗くならずにデバイスが UIFlow で再起動した場合は、G0 を離すのが早すぎたと伝え、もう少し長く押し続けて再試行するよう案内してください。画面が暗くなったことをユーザーが確認するまでは、先に進んだり、スクリプトを再試行したり、ソフトウェアで回避しようとしたりしないでください。それまではフラッシュが開始されません。後で Manual reset のプロンプトが表示された場合も同様に、物理的な手順を伝えてユーザーの操作を待ってください。

Claude Code 経由ではなく、ユーザー自身のターミナルで onboard.py を直接実行している場合は、すべての出力がリアルタイムで表示されるため、変更は不要です。

--port を省略した場合、detect.py は 3 つすべての OS で最も可能性の高い候補を選びます。候補は、ネイティブUSB接続の ESP32-S3(macOS では /dev/cu.usbmodem*、Linux では /dev/ttyACM*、Windows では COMx)、または旧型ボードの CH9102/CP210x UART ブリッジです。Bluetooth シリアルポートは除外されます。候補が複数ある場合は、選択を求められます。

登録済みアプリ名 buddy は、このリポジトリの buddy/device/ ディレクトリ(カスタムランチャー+Hello+Claude Buddy BLE クライアント+Snake)に解決されます。それ以外の --apps の値は、ファイルシステムのパスとして扱われます。

再フラッシュせず、すでにセットアップ済みのデバイスにアプリを転送(または更新)するには、次のようにします。

python3 scripts/install_apps.py --port <PORT> --src buddy

<PORT> には、前回のフル実行時に detect.py が表示した値を指定します。例:/dev/cu.usbmodem1101、/dev/ttyACM0、COM3。

ステージ
  1. 検出(detect.py)— シリアルポートを列挙し、USB-UART ブリッジ(CH9102 ベンダー ID 0x1A86、Silabs CP210x 0x10C4、FTDI 0x0403)または ESP32-S3 のネイティブ USB-JTAG インターフェース(0x303A)に絞り込みます。esptool でプローブし、チップを確認します。ポート名は OS によって異なります(macOS では /dev/cu.usbmodem*、Linux では /dev/ttyACM*/ttyUSB*、Windows では COMx)が、pyserial がその違いを抽象化します。
  2. 識別(detect.py)— ポート検出と並行して、detect.py は UIFlow 起動後にファクトリーテストパーティションの署名を読み取るか、I2C をスキャンし、references/hardware_signatures.md と照合して、適切なファームウェアのバリエーション(Basic-16MB、Core2、CoreS3、Cardputer-Adv など)を提案します。ユーザー向けのバリエーション選択は onboard.py --variant で行います。detect.py --identify フラグはありません。
  3. ファームウェアの取得(fetch_firmware.py)— M5Burner のマニフェスト API に問い合わせ、適切な UIFlow 2.0 バイナリをシステムの一時ディレクトリにダウンロードします。実行間でキャッシュされます。キャッシュはいつでも安全に削除でき、再ダウンロードされるだけです。
  4. 書き込み(flash.py)— UART ブリッジでは 460800 baud で esptool write_flash 0x0 <image> を実行し、ネイティブ USB の S3 デバイスでは 115200 baud で --no-stub を指定します。CH9102 ブリッジでは 921600 は断続的に失敗するため、速度を上げないでください。ネイティブ USB の書き込みでは、消去中に Lost connection, retrying が断続的に発生する場合がありますが、esptool が復旧します。書き込み自体が成功していても、書き込み後の watchdog-reset 終了処理が失敗することがあります。flash.py は esptool の標準出力を解析し、Hash of data verified が出力されていれば、その特定の失敗パターンを致命的ではないものとして扱います。必要に応じて onboard.py は flash.native_reset()、それでも解決しない場合は手動の RESET 操作案内に切り替えます。
  5. アプリのインストール(任意、install_apps.py)— ペーストモードの REPL で、ソースディレクトリ内のすべての .py を /flash/ にアップロードし、repl_reset で再起動します(ネイティブ USB では DTR/RTS は何も起こさないため、使わないでください)。ソースの配置:ルートの *.py → /flash/、apps/*.py → /flash/apps/(UIFlow の標準ランチャーはここをスキャンします)。バンドルにルートの main.py が含まれる場合、install_apps.py は NVS の boot_option=2 も設定します。これにより UIFlow 自身のランチャーは実行されず、こちらの main.py が起動処理を引き継ぎます。これは ESP32-S3 で BLE を使用するアプリに不可欠です(以下の注意事項を参照)。
  6. スモークテスト(任意、smoke_test.py)— I2C スキャン、LCD テストパターン、スピーカーのビープ音、ボタン読み取りを行います。

重大な注意点(スクリプトに組み込み済み—独自判断で変更しないでください)

スクリプトがすでに正しく処理しているため、ユーザーから「esptool を手動で実行するだけ」などと頼まれても、上書きしてはいけない項目です。

  • ネイティブ USB の ESP32-S3 ボード(Cardputer、Cardputer-Adv、CoreS3)では、ダウンロードモードに入るために BtnG0 と BtnRST を手動で操作する必要があります。 ソフトウェアで行う方法はありません。このチップには DTR/RTS ブリッジがないため、esptool や pyserial を使っても ROM ブートローダーには移行できません。ハードウェアボタンを使い、リセットパルスの間 GPIO0 を Low に保つ必要があります。特に Cardputer-Adv では、2 つのボタン(BtnG0 と BtnRST)はデバイスの背面にあります。小さく、表面とほぼ面一で、爪で押すのが最も簡単な場合がよくあります。onboard.py:_wait_for_download_port は FLASH の実行中に、この操作を実行時に促します。BtnG0 を押したままにし、BtnRST を短く押して、先に BtnRST を離し、BtnG0 はさらに約 1 秒押し続けてから離してください。画面が完全に消えているはずです。 デバイスが UIFlow に再起動した場合、BtnG0 を離すのが早すぎたということです。ガイドが再試行し、より長く押し続けるよう伝えます。esptool --before default_reset や pyserial の DTR/RTS を使ってこれを自動化しようとしないでください。どちらもネイティブ USB では何も起こりません(ピンは EN に配線されていません)。これらを追加すると、本当に必要な操作の案内が隠れてしまうだけです。
  • FLASH の実行中はデバイスの USB ケーブルを抜かないでください。 特にネイティブ USB の場合は注意してください。書き込み途中で切断すると、内蔵フラッシュが不整合な状態になります。その後も通常はマスク ROM にアクセスできます(背面の BtnG0 だけを押すか、BtnG0 と BtnRST の両方を操作します)。そのため、復旧するには m5-onboard go を再実行するだけです。このコマンドは冪等で、ダウンロードモードへの再移行、再書き込み、アプリの再転送を行います。慌ててケースを開けないでください。マスク ROM はシリコンに組み込まれているため、USB PHY が正常であればフラッシュが破損しても使用できます。
  • UART ブリッジではボーレートは 460800、ネイティブ USB では --no-stub を使って 115200 にしてください。 どちらも 921600 ではありません。CH9102 ブリッジは 921600 での erase_flash 中に同期を失います(理論上の話ではなく、実際に失敗します)。ネイティブ USB でスタブのボーレートを上げる方法を使うと、書き込み中に「Lost connection」が発生します。直感に反しますが、115200 のスタブなしの方が、一度も失敗しないため最初から最後までの所要時間は短くなります。
  • NVS への書き込みでは set_blob ではなく set_str を使う必要があります(install_apps.py の boot_option セッターに関係します)。UIFlow は起動時に nvs.get_str() を呼び出し、ESP-IDF は blob と string のエントリーを別々に扱います。blob として保存されたキーを get_str で読み取ると ESP_ERR_NVS_NOT_FOUND が返され、デバイスが起動ループに陥ります。以前の試行で blob として書き込んでいた場合は、set_str を呼び出す前に nvs.erase_key(name) を呼び出してください。
  • REPL で複数行のブロックを実行するには、ペーストモードが必要です。 try:/except: を1行ずつ送信すると、REPL はインデントを延々と保持し続けます。Ctrl-E でペーストモードに入り、ブロックを送信してから Ctrl-D で実行してください。mpy_repl.py がこれを処理します。
  • ハードリセットは DTR=False、RTS=True、100ms 後に RTS=False ですが、UART ブリッジ搭載デバイスでのみ有効です。 ネイティブ USB の ESP32-S3 ボードでは DTR/RTS ラインが EN/GPIO0 に配線されていないため、このパルスを送っても何も起こりません。これらのデバイスのインストール後の再起動には、mpy_repl.repl_reset()(REPL 経由で machine.reset() を送信)を使用してください。install_apps.py はすでにこれを実行します。install_apps.py を使わずに独自の処理を組み立てる場合、usbmodem ポートで DTR/RTS を使って再起動させようとしないでください。ファイルはディスク上にあっても、古いコードが動作し続けます。この問題で一度失敗したことがあります。
  • アイドル時のヒープデバッグループは正常です。 UIFlow 2.0 はペアリング画面で待機中に、asyncio の診断情報を出力します。フリーズしたと判断しないでください。
  • Cardputer-Adv(ESP32-S3)の BLE 周辺機器には、NVS の boot_option=2 とカスタム main.py が必要です。 UIFlow のデフォルトの boot_option=1 はバックグラウンドで Flow ペアリング用の BLE アドバタイズを開始し、NimBLE コントローラーを正常に動作できない状態にします。その後、ユーザーコードから gap_advertise(adv_data=...) を呼び出すと、ペイロードの形式にかかわらず OSError(-519)「Memory Capacity Exceeded」が発生します。また、デバイスは空の AD フィールドでアドバタイズするようになり、iOS とデスクトップ版の Claude Buddy アプリから除外されます。バンドルの main.py は /flash/ にあり、起動フローを引き継いで(/flash/apps/ を対象としたシンプルなメニューを表示し)、BLE 自体には触れず、ユーザーが選んだアプリがコントローラーを正常な状態で使用できるようにします。バンドルにルートの main.py が含まれている場合、install_apps.py は boot_option=2 を自動的に設定します。この動作を元に戻さないでください。

プロビジョニング後(デバイス上でユーザーに表示される内容)

m5-onboard go が DONE のバナーで終了すると、デバイスは単独で使用できる状態になります。

  • 電源。 Cardputer-Adv の右端にあるスイッチをスライドして電源を入れます。同じスイッチで電源を切ります。USB ケーブルを抜いている間は内蔵 LiPo で動作し、USB-C で充電できます。
  • 起動。 起動ログが短くスクロールした後、ランチャーメニューが自動的に表示されます。メニューには /flash/apps/ 内のすべての .py と、トップレベルの /flash/*.py エントリーが表示されます。
  • 操作。 矢印キー(またはキーボードのトラックポイント風カーソルキー)でメニューをスクロールします。Enter キーで選択中のアプリを起動し、アプリ内で ESC キーを押すとランチャーに戻ります。
  • イベント WiFi への自動接続。 バンドルの main.py は起動のたびに、ハードコードされたイベント WiFi(SSID cardputer)に接続し、ランチャーメニューが表示される前に LCD に結果を表示します。認証情報は buddy/device/wifi_event.py にあります。接続はベストエフォートで行われ、接続に失敗してもランチャーは常に続行されます。このバンドルをイベント以外で使用する場合は、wifi_event.py を編集するか、main.py から _connect_wifi_with_splash() の呼び出しを削除してください。
  • BLE 経由の Claude Buddy。 初回のみ、Claude Desktop で Help → Troubleshooting → Enable Developer Tools を選択します(この設定は一度だけ行い、以降の起動でも保持されます)。次に Developer menu → Hardware Buddy → Connect を選択します。BLE は WiFi の状態に関係なく動作します。Claude.app との接続はローカルです。
  • UIFlow に戻す。 buddy バンドルが /flash/ に配置するのは main.py のみで、置き換え用の boot.py はありません。そのため、標準の UIFlow boot.py は変更されず、復元用の boot_uiflow.py バックアップもありません。デバイスの REPL から main.py を削除して元に戻します。os.remove('/flash/main.py') を実行し、続けて machine.reset() を実行してください。次回の起動時には UIFlow の標準ランチャーが起動します。ファームウェアも含めて完全に初期化するには、--apps を指定せずにスキルを再実行してください。

ファイル

  • scripts/onboard.py — メインオーケストレーター
  • scripts/detect.py — ポート検出とチップ ID の取得
  • scripts/fetch_firmware.py — M5Burner API とダウンロード
  • scripts/flash.py — esptool のラッパー
  • scripts/install_apps.py — ペーストモード REPL 経由で .py ファイルのディレクトリを /flash/ に転送します。上書き前に boot.py を boot_uiflow.py としてバックアップします。バンドルにルートの main.py が含まれる場合は、boot_option NVS キーも書き込みます。
  • scripts/smoke_test.py — I2C、LCD、スピーカー、ボタンのテスト
  • scripts/mpy_repl.py — シリアル/REPL 用の共有ヘルパー(ペーストモード、ハードリセット、起動ログのキャプチャ)
  • references/hardware_signatures.md — チップと I2C のフィンガープリントからモデル、ファームウェアを特定
  • references/uiflow2_nvs.md — 型と障害モードを含む NVS キーのリファレンス

依存関係

  • pyserial — onboard/scripts/vendor/serial/ に同梱(バージョン 3.5 に固定、BSD-3-Clause)。
  • esptool — pip の依存関係で、requirements.txt に宣言されています。インポート可能かどうかは importlib.util.find_spec("esptool") で確認します。バイナリの代替検索では、macOS の ~/Library/Python/*/bin/、Linux の ~/.local/bin/、Windows の %APPDATA%\Python\Python3XX\Scripts\ を検索します。

onboard.py は起動時に事前チェックを実行します。esptool(または、まれな vendor 削除時における pyserial)が見つからない場合、必要なものを一覧表示し、今すぐインストールするかユーザーに確認します。Y(または Enter)を入力すると、現在のインタープリターで python -m pip install --user <missing> を実行し、その後に検証します。venv 内では --user フラグを外すため、venv の site-packages にインストールされます。非対話型の呼び出し(stdin がパイプ接続されている場合)では、プロンプトの代わりに手動インストールの案内が表示されます。 このスキルが何かを実行するには、まず Python 自体が必要です。インタープリターをスキル内からブートストラップすることはできません。git は必須ではありません。git --version に失敗した場合、/maker-setup コマンドは curl と tar を使って GitHub の tarball をダウンロードする方法に切り替えます。どちらも macOS、Linux、Windows 10 以降にはプリインストールされています。scripts/*.py を実行する前に、Claude が Python の有無を検出し、見つからない場合はインストールする責任を負います。検出には python3 --version/python --version を実行するだけです。失敗した場合、Claude は何よりも先にホストのネイティブパッケージマネージャーを使って Python を取得します。

OS ごとの Python のブートストラップ(Python がない場合は Claude の責任です):

  • Windows — winget install -e --id Python.Python.3.13 --silent --accept-source-agreements --accept-package-agreements。所要時間は約30秒で、UI は表示されず、PATH も正しく設定されます。その後、現在のシェルから python が見つからない場合は、ユーザーにターミナルを閉じて開き直すよう伝えてください(Windows が PATH を更新するのは新しいシェルだけです)。
  • macOS — 現行の macOS では通常、Apple が同梱している /usr/bin/python3 として Python 3 がプリインストールされています。何らかの理由で見つからない場合は、Homebrew 経由の brew install [email protected] が最適です。Homebrew 自体がない場合は、/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" でのインストールを提案してください(ただし、ユーザーが確認した場合のみ。Homebrew の導入は winget よりも大きな決断を伴います)。
  • Linux — ディストリビューションのパッケージマネージャーを使います。Debian/Ubuntu:sudo apt-get update && sudo apt-get install -y python3 python3-pip。Fedora:sudo dnf install -y python3 python3-pip。Arch:sudo pacman -S --noconfirm python python-pip。sudo が必要な場合があるため、必要に応じてパスワード入力をユーザーに求めてください。

pyserial — スキルに同梱:

固定バージョンの pyserial 3.5 が scripts/vendor/ に同梱されています(BSD-3-Clause、Apache 互換)。serial をインポートするすべてのスクリプトは、最初のサードパーティ製インポートより前に vendor_path.ensure_on_syspath() を呼び出します。これにより scripts/vendor/ が sys.path の先頭に追加されるため、ユーザーのシステム全体にあるインストール状況に関係なく、同梱版が解決されます。その結果、pip の手順をまったく行わなくても、新しいクローンでポート列挙と REPL の入出力が動作します。サイズは約500 KBで、純粋な Python 製です。macOS/Linux/Windows で同じディレクトリ構成を使用します。

esptool — pip 依存関係。初回実行時に自動インストール:

esptool は GPLv2 以降のライセンスであり、意図的に同梱していません。リポジトリをクリーンな Apache-2.0 に保つため、GPL のコードはツリー内ではなく、ユーザーが pip で管理する環境に置きます。このスキルの事前チェックではインポート可能な esptool があるか確認し、見つからない場合はインストールを促します(python -m pip install --user esptool。仮想環境内では --user が除外されるため、site-packages にインストールされます)。サブプロセスの呼び出しには [sys.executable, "-m", "esptool", ...] を使います。サブプロセスはユーザーサイトを引き継ぐため、pip でインストールしたモジュールを問題なくインポートできます。明示的なセットアップ用に requirements.txt でこれを宣言しています。プロンプト経由のインストールは、まだ pip を実行していない初回参加者向けのデフォルトです。

非対話型の呼び出し(パイプで stdin を渡す場合や CI など)ではプロンプトをスキップし、代わりに python -m pip install --user esptool を実行するよう案内します。

誰かが scripts/vendor/ を削除した場合のフォールバック:

同じ事前チェック経路で、同梱版がない場合は pyserial も pip 経由で再インストールします。これは、同梱ファイルが除外されたソースのみの zip をダウンロードした場合や、容量を節約するためにリポジトリを手動で削除した場合に対応します。

USB ドライバー — Windows 固有。古いボードでのみ必要:

CH9102 USB-UART ドライバーは、Windows では引き続き手動インストールが必要です。WCH は winget マニフェストを公開していません。必要なのは UART ブリッジ搭載ボード(Basic、Fire、Core2、StickC)のみです。ネイティブ USB 対応の ESP32-S3 ボード(Cardputer、Cardputer-Adv、CoreS3)は、Windows 標準搭載のドライバーを使って複合 USB-CDC デバイスとして列挙されるため、追加のインストールは不要です。

プラットフォームに関する注意事項

このスキルは macOS、Linux、Windows で動作します。分かりにくい点は次のとおりです。

  • ポート名。 pyserial が検索を抽象化しますが、ユーザーに表示される形式は OS によって異なります。detect.py が報告する形式を指定してください。

    • macOS:/dev/cu.usbmodem1101(ネイティブ USB)または /dev/cu.usbserial-XXXX(CH9102)
    • Linux:/dev/ttyACM0(ネイティブ USB)または /dev/ttyUSB0(UART ブリッジ)
    • Windows:COM3、COM4 など(不明な場合は「デバイス マネージャー」→「ポート」を確認してください)
  • Linux の権限 — ハードウェアのせいにする前にお読みください。 ほとんどのディストリビューションでは、sudo を使わずに /dev/ttyUSB*//dev/ttyACM* にアクセスするにはグループへの所属が必要です(Debian/Ubuntu/Arch では dialout、Fedora では uucp)。症状:detect.py はポートを検出するのに、フラッシュの手順で Permission denied または Could not open port が発生します。一度設定すれば長期的に解決します。

    sudo usermod -aG dialout $USER
    # log out / log back in — group change only takes effect for new sessions
    

    sudo python3 scripts/onboard.py ... を一時的に使う方法もありますが、グループに追加するほうが確実です。そうすれば以降、ユーザーモードで pyserial が問題なくポートを開けるようになります。

  • Windows の PATH に関する注意点。 Python の pip install --user esptool では、実行ファイルは %APPDATA%\Python\Python3XX\Scripts\ にインストールされます。このディレクトリが PATH に含まれていない場合、pip は警告を表示しますが、インストールを認識するほかの仕組みはありません。detect.py は予備策としてこの場所を直接確認するため、PATH を修正しなくてもスキルは動作します。ただし、スキル以外から esptool を実行する場合や、ほかのツールで「esptool not found」エラーが発生する場合は、次のいずれかを実行してください。

    • Python インストーラーを再実行し、「Add Python to PATH」にチェックを入れます(インストール時の既定値)。
    • 「システムのプロパティ」→「環境変数」から %APPDATA%\Python\Python3XX\Scripts を PATH に追加します。
    • PATH に関係なく常に動作する python -m esptool ... を使用します。
  • Windows Store 版 Python。 新しい Windows 11 マシンには、Microsoft Store 経由で Python がプリインストールされている場合があります。動作はしますが、PATH の挙動に癖があります(%LOCALAPPDATA%\Packages\PythonSoftwareFoundation.Python.*\ にインストールされます)。detect.py はこの場所も確認します。選択できる場合は、winget install Python.Python.3.13 でインストールするバージョンのほうが予測しやすいです。

  • バンドルのパス解決。 install_apps.py の --src buddy という省略形は、次の順にパスを解決します。

    1. 設定されている場合は $M5_BUDDY_DIR — 明示的な上書きで、常に優先されます。このクローンに含まれていないフォークやカスタマイズ済みバンドルを指定したい場合に便利です。
    2. このリポジトリ内の buddy/device/ ディレクトリ。install_apps.py から os.path.realpath(__file__) を使って上位ディレクトリをたどり、見つけます。シンボリックリンクされた ~/.claude/skills/m5-onboard/ へのスキルのインストールを含め、クローンの場所を問わず動作します。
    3. ~/Downloads/m5stack/buddy/device。
    4. ~/Desktop/m5stack/buddy/device。

    ほとんどのインストールでは(2)が使われます。このクローンの外にあるバンドルを指定する場合に限り、M5_BUDDY_DIR を設定します。Unix では export M5_BUDDY_DIR=/path/to/buddy/device、PowerShell では $env:M5_BUDDY_DIR="C:\path\to\buddy\device" を実行してください。

  • ファームウェアのキャッシュ。 ダウンロードしたファームウェアは ~/.cache/m5-onboard/(または $XDG_CACHE_HOME/m5-onboard/)に保存されます。ディレクトリが存在しない場合は、モード 0700 で作成されます。キャッシュファイルは書き込み時に MD5 で検証され、キャッシュから読み込む際にも再検証されます。キャッシュを削除しても問題ありません。次回実行時に再ダウンロードされます。

コメント