1. 概要
Raspberry Pi Picoを使って、ドットマトリクスLED(WAVESHARE-20591)にMP4動画ファイルを表示するシステムを作成しました。
2. 成果物
ソースコード、バイナリファイル、および使い方は以下のGitHubリポジトリにまとめています。
shiomachisoft / PicoMtrx
開発環境・使用言語
- ファームウェア(Pico側): C言語 / Pico SDK
- PCアプリ(Windows側): C# / Visual Studio
3. 動作環境・ハードウェア仕様
| 項目 | 詳細 |
|---|---|
| マイコン基板 | Raspberry Pi Pico |
| ドットマトリクスLED | WAVESHARE-20591(64×32ドット / RGB各2階調 / Picoを直接装着可能) |
| PC OS | Windows 11 または Windows 10 |
| PC環境の要件 | .NET Framework 4.6.2以上(Windows 11は標準で満たしています。※.NET 5以降は非対応です) |
| リフレッシュレート | 30Hz(ファームウェア仕様) |
4. システム構成とデータの流れ
PC側で事前にMP4ファイルからマトリクスデータを作成した後、Picoへ送信して表示させる構成です。
- ①変換: PCアプリでMP4ファイルを読み込み、マトリクス用のデータに変換。
- ②送信: PCからPicoへ、マトリクスデータをUSB通信で送信。
- ③表示: Picoがデータを受信し、ドットマトリクスLEDの表示を更新。
5. MP4からマトリクスデータへの画像処理
WAVESHARE-20591のハードウェア仕様(64×32ドット、RGB各2階調、横長アスペクト比2:1)に最適化するため、PC側で以下の画像処理を行っています。
- 回転: MP4の画像が縦長の場合、パネルの向きに合わせて左に90度回転して横長にする。
- トリミング: パネルの縦横比に合わせ、画像の中央から「幅2:高さ1」の比率で切り取る。
- リサイズ: 64×32ピクセルに縮小する。
- 鮮鋭化フィルタ適用: 低解像度(64×32ドット)だと細部がぼやけて見えがちなため、エッジを強調して視認性を上げる。
- 二値化: パネルがRGB各2階調しか表現できないため、RGB各成分に対して「大津の二値化」を適用する。
6. リフレッシュレート30Hzを保つための工夫
USBのアイソクロナス転送は実装のハードルが高いため、手軽な仮想COMポート(USB-CDC)を使用しつつ、30Hzを維持するために以下の工夫を行いました。
① USB-CDC受信バッファの拡張
Picoのデフォルト設定ではバッファが足りなくなるため、TinyUSBの受信バッファサイズ(CFG_TUD_CDC_RX_BUFSIZE)をカスタマイズして約30KBに増やしています。
Pico SDKでカスタマイズした設定ヘッダ(例: my_tusb_config.h)を適用する場合、CMakeLists.txtに以下のように定義を記述します。
target_compile_definitions(PicoMtrx PUBLIC
CFG_TUSB_CONFIG_FILE="my_tusb_config.h"
)
② ダブルバッファリングによる並行処理
データの「受信」と「表示更新」のタイムラグによる画面のつきを防ぐため、30フレーム分のマトリクスデータを保持できるキューバッファを2つ(バッファA、バッファB)用意し、交互に処理を行っています。
- [バッファAに受信] PCからPicoへ、仮想COM経由で30フレーム分のデータを送信し、Picoは「バッファA」で受信する。
-
[バッファAを表示 / バッファBに受信]
- Picoは「バッファA」のデータを使ってマトリクスLEDの表示を30Hzで更新。
- これと並行して、PCから次の30フレーム分のデータを送信し、Picoは「バッファB」で受信する。
-
[バッファBを表示 / バッファAに受信]
- 「バッファB」のデータで表示を更新。
- これと並行して、PCから次の30フレーム分のデータを「バッファA」で受信する。
- 以降、この処理を交互に繰り返すことで、通信の遅延に影響されずスムーズな30Hz再生を実現しています。
7. 免責事項
本記事の内容や本ソフトウェアの使用により生じた、いかなる損害やトラブルについても、作者は一切の責任を負いません。ご利用は自己責任でお願いいたします。

