HDMIコネクタを使用した画像出力

PIC, AVRやPICOに搭載されているRP2040などのマイクロコントローラーを使用して、NTSCやVGA信号を生成する製作例はいろいろと報告されていますが、HDMIコネクタで使用できるDVI信号を作成する例はほかにみたことがありません。

ハードウェア的にはRP2040に実質的にHDMIコネクタのみを追加し、ソフトウェアのみでDVI信号を生成する製作例 PicoDVI を見てびっくりしました。PicoDVIの機能は驚くことにソフトウェア的に実現されており、ハードウェア的には単にマイクロコントローラーの端子から、HDMIコネクタに信号線を接続しただけで実現されています。PICOに使用されているRP2040の潜在能力や、PicoDVIを開発したLuke Wren氏の能力や熱意(執念、狂気?)には、ただただ感嘆するばかりです。

PicoDVIを使用する際には、定格では133MHzのRP2040のクロックを252 MHzで動かしている点には注意が必要です。(おいたが過ぎるように感じますが、チップが問題なさげに動いているところもびっくりです。どんだけマージンがあんねん…)

映像出力を行うプログラムを実行すると、オーバークロックの影響で、通常は10mA以下の消費電流が50mA程度に激増しており、チップが少し暖かくなります。周辺温度にもよりますが、チップ内の温度センサーで計測すると、40-50度程度になるようです。この温度を見る限りは、チップ内の回路がすぐさま熱損傷を受けるということはなさそうですね。


PicoDVIの特徴

最大の特徴は、何と言ってもMCUだけで全く外部回路(ロジックだけでなくメモリも)なしでDVI信号を生成しているところでしょう。映像生成は、映像信号の生成能力も重要ですが、メモリ容量も大きな制約条件になります。DVIとしては低解像度だとしても、その両方をクリアしたRP2040もPicoDVIの制作者もすごいですね。そもそも作れるかもと思ったこと自体がすごい。

MPUやMCUでのアナログのNTSCやVGAの映像信号生成は、いろいろと試して遊んでいましたが、DVIやHDMIになってからは、トライアルする気もありませんでした。だって、たとえばNTCSは信号帯域が5MHzぐらいだから手を出す気にもなるけど、HDMIは5Gbpsとか50Gbpsとかいってんだもん。スペック見ただけで試しもせず諦めました。

でも、やる人、成功させる人がいるんだよね。

PicoDVIの画面構成

PicoDVIでは、目的や用途に応じて、いくつかの候補から画面構成を選択できます。

ゲームなどの画面の書き換えを常時行うアプリケーションでは、色の表現力とメモリの使用量を考慮すると、320x240もしくは400x240の8ビットダブルバッファが基本的な選択肢になりそうですね。

解像度(ピクセル)色表現(ビット数)バッファ数バイト数
320x240161154K
400x240161192K
320x2408177K
400x2408196K
320x24082154K
400x24082192K
640x4801139K
800x4801148K
640x4801277K
800x4801296K

解像度

HDMIでは1920x1080ピクセルが標準ですが、大域的にもデータ量的にも無理なので、PicoDVIではすごく割り切った設定になっています。320x240ピクセルでは、各ピクセルを縦横2倍に拡大し、画面上では、640x480ピクセルの表示になっています。400x240も同様に800x480に引き伸ばされて表示されます。

画像の縦横比を1:1に近づけたい場合には、400x240や800x480の使用が望ましいのです。ただし、メモリの使用量が多くなるので、アプリケーション処理用のメモリとのトレードオフになります。

色表現

ビット数は、1ピクセルの表現に使用されるビット数を示します。16ビットの場合には、1ピクセルを16ビット65,536色で表現できます。色の表現は直接書き込み、R5G6B5の形式で指定します。

8ビットの場合には、1ピクセルを8ビット256色で表現できます。8ビットの場合には16ビットの場合と異なり、色をR5G6B5の形式で書き込む256個のパレットを用意し、どのパレットの色を使うかというインデックスを利用してピクセルの色指定をします。

1ビットの場合には、ピクセルごとに1か0かで白か黒の指定になります。

バッファ数

色表現が16ビットの場合にはシングルバッファのみ、それ以外はシングルバッファか、ダブルバッファを選択できます。この制約は基本的にメモリ容量によるものです。ない袖は振れませんからねえ。

画面の描画更新のちらつきが気になる場合には、ダブルバッファを利用することができます。

バイト数

RP2040には、260Kバイトのメモリが搭載されています。この中から、画面表示用のメモリ領域を確保しなければなりません。

色表現で16ビットを選択する場合や、8ビットでダブルバッファを選択する場合には、メモリの使用状況がかなり切迫したものとなります。

リソース


PicoDVIのプログラミング

PicoDVIのプログラミングは、だれもが簡単にトライアルできるという観点からは、ArduinoとCircuitPythonを使用して行うことができます。ArduinoもCircuitPythonも結局のところAdafruitさんの貢献で多くの人が楽しめるということで、PicoDVIだけではありませんが頭が下がります。

Arduino

ArduinoでのPicoDVIプログラミングでは、Arduinoの世界で使い慣れたAdafruit_GFXを使ってプログラミングできるので、Adafruit_GFXの使用経験がある人はすぐに使うことができるでしょう。Adafruit_GFXの使用経験がない人は、PicoDVIで経験すると、TFTディスプレイなど他の出力デバイスのプログラミング技術も手に入れることになるので、楽しんでください。

PicoDVIのArduinoプログラミングに関する情報を以下に示します。

CircuitPython

CircuitPythonでのPicoDVIのグラフィックスライブラリはAdafruitさんが実装したので、Adafruit_GFXか、オリジナルのMicroPythonのFrameBufferのグラフィックスに準じたものになるだろうと考えてプログラミングに先立つ調査を開始したのですが。。。

CircuitPythonのドキュメントをさっと俯瞰しても、WEBの記事を眺めてみても、それ風の情報はどこにもないぞ???ということで、あたふたしてしまいました。

どのライブラリを使うのかもよくわからず、displayioライブラリを使うということはわかっても、そのプログラミングモデルがよくわからず、しばしさまよってしまいました。

分かってしまえばということなのですが、灯台下暗しというか、displayioのプログラミングモデルは、ドキュメントのタイトルとして書かれていた以下のタイトルと序文につきますね。

displayio – High level, display object compositing system
The displayio module contains classes to define what objects to display. It is optimized for low memory use and, therefore, computes final pixel values for dirty regions as needed.

絵筆でキャンバスに絵を描くというよりは、絵を描く図形要素をオブジェクトとして生成し、それを画面に置いていくという方式になっています。この説明ではわかりにくいけど、プログラミングするとわかると思います。

displayioの序文を読むと、情報工学を学んだ人は、遅延評価とか、キャッシュや仮想記憶の書き戻しとかのメカニズムを思い起こしちゃいますよね。グラフィックスライブラリだけど、実装にはそのようなアイディアを使ってるやつですね。

displayioは一癖あるけど、Pythonの対話性やオブジェクト指向の特徴をうまくかつようできる面白いグラフィックスライブラリだと思うのでぜひ使ってみてください。

PicoDVIのCircuitPythonプログラミングに関する情報を以下に示します。


関連製品

RP2040-UNO-HDMI

UNO形状のRP2040開発ボードにHDMIコネクタを搭載し、PicoDVIでPCモニタに画像出力を行うことができる開発ボードです。

PICO-HDMI-PLUS

Raspberri Pi PICO/PICO WにHDMIコネクタとタクトスイッチx4、圧電スピーカーを追加する拡張ボードです。PICOが超小型のテレビゲーム機やPCモニタ出力付きのArduino実験ボードに変身します。