前回、PicoとAdafruit DVI Breakout Boardでテキスト表示に成功しましたが、標準設定では文字の「ギザギザ(ジャギー)」が目立ち、視認性に課題が残りました。
そこで今回は、Pico 2を使わず、あえて初代Picoのままでどこまで美しく、読みやすいテキスト表示ができるか挑戦しました。AI(Gemini)と相談しながら導き出した、リソース節約と美しさの両立案をまとめます。
今回の改善アプローチ
1. 解像度とメモリの最適化(VGA 640×480)
あえてカラーを捨てて**白黒(1bitモード)**に特化することで、RP2040の限られたRAMを節約。これにより、高解像度なVGA(640×480)設定でも、画面全体をクリアに維持したまま高速な描画を可能にしました。
2. フォントサイズと「太字(Bold)」の魔法
最小の fontsize=1 を使用すると、1ピクセルの線が細すぎて液晶モニター上ではかすれて見えたり、逆にジャギーが際立ったりします。
標準フォントの限界
PicoのDVI出力サンプルでよく使われる標準フォントは、軽量ですが「1ドットの集合体」感が強く、VGA解像度ではどうしても文字が細く、ギザギザ(ジャギー)が目立ってしまいます。
2. 解決策:FreeSansBold12pt7b の採用
今回は、Adafruit GFXライブラリ等で利用できる**プロポーショナルフォント(可変幅フォント)**の太字版を導入しました。
- なぜこのフォントか?:
Bold(太字)なので、1bit(白黒)表示でも文字が背景に負けず、くっきりと浮かび上がります。- 文字の角や曲線が最適化されており、標準フォントよりも圧倒的に「読みやすく、高級感がある」表示になります。
3. 実装の工夫(メモリ管理)
プロポーショナルフォントは美しい反面、標準フォントよりもデータ量が大きくなります。
- 白黒(1bit)化の効果: 画面のバッファを1bitに絞ることで浮いたRAMを、これらリッチなフォントデータの格納や描画処理に充てることができました。
「こだわりポイント」のヒント
- 「fontsize=1」の意味: 大きなフォントを縮小するのではなく、
12ptなどの適切なサイズのフォントをそのままsize=1で描画するのが、最もエッジが綺麗に出る設定です。「拡大してぼやけるのを防ぐ」という意図を伝えると説得力が増します。 - ソースコードの紹介:
#include <Fonts/FreeSansBold12pt7b.h>を追加し、tft.setFont(&FreeSansBold12pt7b);のようにセットする一連の流れを載せると、初心者にとって非常に有益なガイドになります。
#include <PicoDVI.h>
#include <Fonts/FreeSans9pt7b.h> // 滑らかなフォントを読み込み
#include <Fonts/FreeSansBold12pt7b.h> // 太いフォント
const dvi_serialiser_cfg my_dvi_cfg = {
.pio = pio0,
.sm_tmds = {0, 1, 2},
.pins_tmds = {12, 16, 18}, // 青(D0), 緑(D1), 赤(D2)
.pins_clk = 14,
.invert_diffpairs = false // ← これを true/false 切り替えて試す
};
int progress = 0; // 0〜100
// 引数から false を削除し、電圧(VREG_VOLTAGE_1_20)を指定
//DVIGFX16 display(DVI_RES_320x240p60, my_dvi_cfg, VREG_VOLTAGE_1_20);
// 修正前
// DVIGFX1 display(DVI_RES_640x480p60, my_dvi_cfg, VREG_VOLTAGE_1_20);
// 修正後:第2引数に「ダブルバッファリング」の設定が必要です
DVIGFX1 display(DVI_RES_640x480p60, false, my_dvi_cfg, VREG_VOLTAGE_1_30);
void setup() {
if (!display.begin()) {
pinMode(LED_BUILTIN, OUTPUT);
while (1) {
digitalWrite(LED_BUILTIN, HIGH); delay(100);
digitalWrite(LED_BUILTIN, LOW); delay(100);
}
}
display.fillScreen(0);
display.setTextColor(1);
// 1. まずフォントをセットする(重要:getTextBoundsの前にセット)
display.setFont(&FreeSansBold12pt7b);
display.setTextSize(1); // FreeFontsは元から大きいのでサイズ2くらいが綺麗です
String text = "Loading........";
// 2. テキストの範囲を計算
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
// 3. 中央の座標を計算
// FreeFontsの場合、y座標には「高さ(h)」を足す、もしくはy1のオフセットを考慮する必要があります
int centerX = (640 - w) / 2;
int centerY = (480 + h) / 2; // +h にすることでベースラインを中央に下げます
// 4. テキストの描画
display.setCursor(centerX, centerY);
display.print(text);
// 画面の四隅に枠を描画(これが映れば信号は正常です)
display.drawRect(0, 0, 640, 480, 1);
}
まとめ
「Picoでもここまでできる!」 デバイスの性能を限界まで引き出すのではなく、**「適切なリソース配分(カラーを捨ててフォントに振る)」**という戦略によって、実用性の高いディスプレイ出力を実現できました。




コメント