Raspberry Pi Pico 2 を、ブラウザから使えるオシロスコープ・スペクトラムアナライザ・ロジックアナライザにする PiLyzer と、同じものを Arduino の R4 シリーズ(Nano R4 / UNO R4 Minima / UNO R4 WiFi)で動かす ArLyzer を作りました。
- アプリのインストールなし:Chrome / Edge で PiLyzer Web を開いて USB でつなぐだけ。Mac には専用アプリもあります。
-
Wi-Fi 対応:Pico 2 W と UNO R4 WiFi は、ボード自身が画面を配ります。スマホや iPad で
http://pilyzer.local(arlyzer.local)を開けば、そのまま測定器になります。 - オープンソース:ファーム・Web アプリ・Mac アプリ・回路まで GitHub で公開しています(MIT ライセンス)。
紹介動画(約 6 分、日本語・英語字幕):
コードのほとんどは AI(Claude Code)と一緒に書きました。この記事では、何ができるか、どう使うか、作る途中でハマったところを紹介します。
できること
| 画面 | 内容 |
|---|---|
| オシロスコープ | 電圧の波形、X/Y 表示。Vpp・平均・RMS・周波数・デューティ・立ち上がり時間を自動で測定 |
| スペクトラム | 有効な全チャンネルの FFT。ピークの印、THD・THD+N・SNR・SINAD・ENOB |
| ロジック | 8 本の波形、周波数とデューティ、UART / SPI / I²C のデコード |
| メーター / ロガー | 全入力の電圧を数字で。50 ms〜5 分ごとの記録(区間の最小・平均・最大) |
どの画面も、表示しているデータを CSV に書き出せます。何もつながなくても、組み込みのデモ信号で全部の画面を試せます。
電圧を横目で見る(メニューバー / Watch)
ほかの作業をしながら、1 本の入力の電圧だけを見ていたいときのための機能です。
-
Mac アプリ:「View」→「Show in Menu Bar」でチャンネルを選ぶと、メニューバーに PiLyzer のマークと電圧が出ます(例:
3.31 V)。小数点以下 2 桁の等幅表示なので、値が動いても幅が変わりません。クリックすると全チャンネルの電圧の一覧が出て、表示するチャンネルの切り替えや Run / Stop もできます。 -
Web アプリ:右側の「Instrument」欄の Watch でチャンネルを選ぶと、タブのタイトルが
3.31 V — PiLyzerになります。Pop out を押すと、電圧だけの小さなウインドウを、ほかのアプリの上に浮かせておけます。
値は、Meter 画面ではメーターの読み、Scope / Spectrum 画面では記録の平均電圧(直流のレベル)です。いま動いている測定の値をそのまま使うので、測定の速さや設定は変わりません。
Pop out は、Chrome / Edge の Document Picture-in-Picture という機能を使っています。この機能は https のページでしか使えません。そのため、http://pilyzer.local や http://arlyzer.local のように、ボードが配るページでは Pop out は出ません(タブのタイトルには出ます)。Pop out を使うときは、https://satachito.github.io/Oscillo/ を開いて USB でつないでください。
対応ボードと性能
| Pico 2(PiLyzer) | Nano R4 / UNO R4 Minima(ArLyzer) | UNO R4 WiFi(ArLyzer) | |
|---|---|---|---|
| アナログ入力 | 3ch、12 bit | 8ch、14 bit | 7ch、14 bit |
| アナログの速さ(1ch あたり) | 495 / 247 / 165 kSa/s(1 / 2 / 3ch) | 88 kSa/s(1ch)〜 47 kSa/s(8ch) | 88 kSa/s(1ch)〜 50 kSa/s(7ch) |
| 記録長 | アナログ 16,384 点、ロジック 65,536 点 | アナログ 1,024 点、ロジック 16,384 点 | アナログ 1,024 点、ロジック 14,336 点 |
| ロジック | 8ch、最大 150 MSa/s | D2〜D9 の 8ch、最大 167 kSa/s | 同左 |
| つなぎ方 | USB(Pico 2 W は Wi-Fi も) | USB シリアル | USB シリアル + Wi-Fi |
Pico 2 のほうが速く、Arduino のほうが入力の本数が多い、という関係です。Arduino の入力は 0〜5 V、Pico 2 は 0〜3.3 V で、Pico 2 でそれより広い電圧を測るには、アナログフロントエンドを付けます。picoLABO の PL2407AFE(2ch、±30 V / ±6 V / ±1.5 V)に対応していて、3ch で ±25 V / ±5 V を切り替える自作の基板も設計中です。
入力に、ボードの電源電圧(Pico 2 は 3.3 V、Arduino R4 は 5 V)を超える電圧や、マイナスの電圧を直接つながないでください。それより広い範囲を測るには、フロントエンドの回路が必要です。
使い方
Pico 2 / Pico 2 W(PiLyzer)
- ファームウェアを書き込みます。
-
リリースページから、ボードに合う UF2 を選びます。
-
Pico 2(そのまま、またはミニ AFE 付き):
PiLyzer-Pico2.uf2 -
Pico 2 W:
PiLyzer-Pico2W.uf2 -
picoLABO PL2407AFE 付きの Pico 2:
PiLyzer-PL2407AFE-Pico2.uf2(元の Scoppy のファームは置き換わります)
-
Pico 2(そのまま、またはミニ AFE 付き):
- BOOTSEL ボタンを押しながら Pico を USB につなぐと、
RP2350というドライブが出てきます。そこに UF2 をドラッグ&ドロップすれば書き込み完了です。 - 自分でビルドする場合は、
Pico2/firmware/pilyzerを Pico SDK でビルドします(手順は README)。
-
リリースページから、ボードに合う UF2 を選びます。
- Chrome か Edge で PiLyzer Web を開き、Connect USB を押して Pico を選びます。Mac なら専用アプリでも使えます。
- Run を押すと測定が始まります。GPIO22 から 1 kHz の矩形波が出ているので、GPIO26(CH1)とつなぐと、すぐに波形を確かめられます。
Pico 2 W を Wi-Fi で使う:USB でつないだ状態で、右側の Wi-Fi 欄にネットワーク名(2.4 GHz)とパスワードを入れて保存します。ボードがつながったら、同じネットワークのスマホや iPad で http://pilyzer.local を開いてください。ネットワークの設定は Pico のフラッシュに保存され、ファームを更新しても残ります。パスワードは読み出せません。
Arduino R4(ArLyzer)
- ファームウェアを書き込みます。
-
ビルドなしで書き込む:リリースページに、3 枚それぞれのファーム(
ArLyzer-NanoR4.bin、ArLyzer-Minima.bin、ArLyzer-R4WiFi.bin)があります。arduino-cli で書き込みます。Minima ならarduino-cli core install arduino:renesas_uno arduino-cli upload --fqbn arduino:renesas_uno:nanor4 -p <ポート> --input-file ArLyzer-NanoR4.bin:minimaとArLyzer-Minima.bin、UNO R4 WiFi なら:unor4wifiとArLyzer-R4WiFi.binに置き換えます。ポートはarduino-cli board listで確認できます。 -
Arduino IDE から書き込む:「Arduino UNO R4 Boards」のボードパッケージを入れ、
ArLyzer/arlyzerのスケッチを開いて書き込みます。
-
ビルドなしで書き込む:リリースページに、3 枚それぞれのファーム(
- PiLyzer Web で Serial を押して、ボードのシリアルポートを選びます(Web Serial を使うので、こちらも Chrome / Edge)。Mac アプリなら、接続先の一覧からボードを選びます。
- アナログ入力は A0〜A7(Minima は A0〜A5 と D4・D5、WiFi は A0〜A5 と D10)、ロジック入力は D2〜D9 です。
UNO R4 WiFi を Wi-Fi で使う:ボードに載っている ESP32-S3 のファームを、ArLyzer 用のものに入れ替えます。リリースページの ArLyzer-R4WiFi-bridge.zip を展開して、ArLyzer/bridge/flash.sh で書き込みます(ジャンパー不要、要 esptool)。元の Arduino 純正ファームは、最初に丸ごとバックアップされます。あとは Pico 2 W と同じく、アプリの Wi-Fi 欄でネットワークを設定して、http://arlyzer.local を開きます。
Arduino R4 のロジック入力は 5 V ロジック向けです。チップが 5 V で動いているので、3.3 V の信号は HIGH と読めないことがあります。3.3 V の回路を見るときは、レベル変換を挟んでください。
仕組み
アプリは、ボードに「何ができるか」を聞く
PiLyzer のアプリには、ボードの性能が一切書き込まれていません。つなぐと、まずボードに「チャンネルは何本か、どこまで速いか、記録は何点までか、入力の範囲は」と問い合わせて、その答えに合わせて画面を作ります。
そのおかげで、Pico 2 と Arduino R4 という、まったく違うボードを同じアプリで扱えます。ArLyzer は「PiLyzer と同じ通信の決まりごと(プロトコル)を話す Arduino のファーム」で、アプリ側の変更はほとんどありませんでした。違うのはつなぎ方だけで、Pico 2 は USB のベンダークラス(WebUSB)、Arduino は標準の開発環境の都合で USB シリアル(Web Serial)を使っています。中身のデータは同じです。
プロトコルの仕様は Pico2/docs/protocol.md にまとめてあります。
UNO R4 WiFi は「USB の先が ESP32」
UNO R4 WiFi の USB は、Arduino 本体のチップ(RA4M1)ではなく、Wi-Fi 用の ESP32-S3 につながっていて、ESP32 が UART で本体に中継しています。ArLyzer では ESP32 の Arduino 純正ブリッジファームをもとに、Wi-Fi の命令を受ける部分だけを入れ替えました。
ブラウザ ⇄ Wi-Fi ⇄ ESP32-S3(画面を配る・/rpc を中継)⇄ 2 本目の UART ⇄ RA4M1(測定)
Mac ⇄ USB ⇄ ESP32-S3(USB シリアルの中継) ⇄ UART ⇄ RA4M1
ESP32 は Web アプリを自分のフラッシュから配り、測定の要求は 2 本目の UART で本体に中継します。USB からのスケッチ書き込みなど、純正ファームの機能はそのまま残しています。
ハマったところ
作る途中でぶつかった問題を、いくつか紹介します。
「5 V」は 5 V じゃなかった
Arduino R4 の ADC は、USB から来る 5 V を物差しにしています。テスターで測ると 5.21 V で、そのぶん電圧の読みが 4% 低く出ていました。しかもこの値は USB ポートやケーブルで変わります。
チップ内部の約 1.43 V の基準電圧を読み、そこから実際の電源電圧を逆算するようにして解決しました。ただし、基準電圧を普通の入力と交互に読むと 8% 低く出るので、単独で、いちばん長いサンプリング時間で読む必要があります。
エラーが出ないのに、時間軸が 15% ずれていた
サンプリングの刻みを詰めていったところ、取りこぼしのエラーは一度も出ないのに、1 kHz の矩形波が 1.15 kHz と表示されました。
取りこぼしの検査が「1 回ずつの間隔が長すぎないか」しか見ていなかったのが原因です。1 回ずつは少ししか遅れないので検査に引っかからず、遅れが積もって最後にはサンプルが丸ごと抜けていました。今は、予定時刻からの遅れの合計で判定しています。
エラーが出ないことは、正しいことの証明にはなりません。 周波数のわかっている信号を入れて、本当にその値に読めるかを確かめるのが確実です。
analogRead(4) は D4 ではなく A4
UNO R4 Minima は、デジタルの D4・D5 も ADC につながっているので、アナログ 8ch にできます。ところが Arduino の analogRead(4) は A4 を読みます。A0 より小さい番号は「アナログの何番目か」と解釈されるからです。ピンをポートとビットで指定して読むようにしました。
スペクトラムに「測れない周波数」の数字が出ていた
7ch を最短の刻みで記録すると 504 点しか取れず、FFT は 2 のべき乗の長さしか使えないので 256 点だけを使っていました。目盛り 1 つが約 200 Hz と粗く、111 Hz の信号はそもそも測れないのに、マイナス 117 Hz という数字を出していました。
記録を 2 のべき乗にそろえ、測れない周波数には数字を出さず、代わりに波形から測った周波数と「スペクトラムで測れる下限」を表示するようにしました。下限は窓関数ごとに実測した値(Hann なら目盛り 2.5 個分)です。
arlyzer.local を開くたびに 5 秒待たされた
Mac は名前を引くときに IPv6 のアドレスも問い合わせます。ESP32 が IPv6 に答えないので、Mac が 5 秒待ってからあきらめていました。IPv6 を有効にして、サーバーも IPv6 と IPv4 の両方で待ち受けるようにしたら、5.03 秒が 0.057 秒になりました。
Pico 2 W でも同じ問題があり、同じように直しました。Pico 2 W では、ルーターから配られるグローバルな IPv6 アドレスは付けないようにしています。PiLyzer の画面と /rpc には認証がないので、家のネットワークの外から届かないようにするためです。
Wi-Fi のパスワードをファームに焼き込まない
最初は、Wi-Fi のネットワーク名とパスワードをビルド時にファームに埋め込んでいました。これではファームを配布できません。誰でもダウンロードして取り出せてしまうからです。
今は、アプリから USB でネットワークを設定します。UNO R4 WiFi では、アプリがつながる RA4M1 と Wi-Fi を扱う ESP32 が別のチップなので、ESP32 が 1 秒に 1 回 RA4M1 に「新しい設定はある?」と聞きに行き、受け取ったら自分の保存領域(NVS)にしまってつなぎます。ESP32 が受け取ったら、RA4M1 はパスワードを消します。この受け渡しの命令は、USB からも Wi-Fi からも送れないようにしました。
ESP32 の問い合わせで、USB の要求が 300 回に 1 回欠けた話
ESP32 が毎秒問い合わせるようにしたところ、USB からの要求がおよそ 300 回に 1 回、1 バイト欠けるようになりました。試験用のファームで切り分けた結果です。
| 試験用ファーム | USB の要求の失敗 |
|---|---|
| 2 本目の UART を使わない | 0 / 219 |
| 2 本目は受信だけ(返事をしない) | 7 / 216 |
| USB 側の受信割り込みを 1 段上げる | 0 / 219 |
| 両方の受信割り込みを 1 段上げる | 7 / 217 |
もう一方の UART の受信割り込みが、USB 側の受信割り込みを待たせていました(230,400 bps では 1 バイトが 43 µs)。USB 側だけ優先度を上げて、350 回続けて失敗なしになりました。
AI(Claude Code)との分担
このプロジェクトは、Anthropic の Claude Code と一緒に作りました。分担はこうです。
| AI(Claude Code) | 自分 |
|---|---|
| ファームウェア・テスト・シミュレータ・測定スクリプトを書く | 配線、ボードの抜き差し、リセット |
| ボードへの書き込みと測定を実行して、結果を読む | テスターで測る |
| 原因を切り分けて、直し方の選択肢を出す | 目で見たことを伝える(LED が点かない、など) |
| コミットとリリース | 方針を決める |
やってみて印象に残ったことが 3 つあります。
- AI は自分の書いた検査の穴にも気づく:上の「時間軸が 15% ずれた」の取りこぼし検査は、AI 自身が書いたものでした。見つけたのも AI で、周波数のわかっている信号で確かめる検査に書き直したときです。
- 画面の違和感に気づくのは人間:スペクトラムの不具合は 4 つとも、画面を見ていた自分が気づき、原因を掘ったのは AI でした。テストは、使う人の違和感までは拾えません。
- 公開を止めたのは AI:Wi-Fi のパスワード入りのファームをリリースに載せようとしたとき、止めたのは AI でした。
作る過程は、YouTube の制作記(英語、日本語字幕)にまとめています。
- PiLyzer #1:Pico 2 のオシロで、チップが実際に見ているものを見る
- PiLyzer #2:オペアンプ 1 個で、Pico で音を聴く
- ArLyzer:Pico 2 の測定器を Arduino R4 の 3 枚に移植した、AI との 3 日間
リンク
- ソースコード:https://github.com/Satachito/Oscillo
- PiLyzer Web:https://satachito.github.io/Oscillo/
- 紹介動画(YouTube):https://youtu.be/e5NLnyxRusI
- 制作記(YouTube、英語・日本語字幕):PiLyzer #1 · PiLyzer #2 · ArLyzer
- リリース(Mac アプリ・ファーム):https://github.com/Satachito/Oscillo/releases/latest
- プロトコル仕様:https://github.com/Satachito/Oscillo/blob/main/Pico2/docs/protocol.md
Mac アプリは ad-hoc 署名で、Apple の公証は受けていません。初回起動時は「システム設定 → プライバシーとセキュリティ → このまま開く」で許可してください。
