東雲フォントをSDカードに入れてみた
M5Stackで天気予報を表示するために、SDカードに東雲フォントを入れて表示できるようにしてみました。一般的なSDカードの容量であれば、盛大に無駄遣いしても余裕で入りますので、文字コードとフォントデータの場所を示すINDEXは作らず
文字コード自体をINDEXとして扱うことでSDカードの読み出し回数を減らしています。
※ その方がメモリーの節約になり、読み出し速度が向上する・・・と言う目論見です。
※ 実際の速度計測はしていないので、本当に速くなっているのかは不明。
SDカードの寿命
文字フォントを入れるので、1文字表示する毎にSDカードの読み出しが発生します。読み出し回数が膨大な回数になるのでSDカードの寿命が心配ですが ChatGPTで調べたところ、読み出し動作はSDカードの寿命にほとんど影響を与えないようです。
SDカードの寿命(読み書き回数)は主に書き込み回数によって制限されており、読み出し(リード)による寿命への影響はごくわずかです。以下に詳しく説明します。
✅ 読み出しの影響について
- SDカードはフラッシュメモリを使用しており、読み出し自体ではセルが劣化しないため、基本的に読み出し回数による寿命制限はありません。
- 理論的には、読み出しは無制限に近いとされており、数十万〜数百万回読んでも問題ない設計になっています。
- ただし、極端な高頻度アクセス(監視カメラの連続再生など)では、カードコントローラやその他部品に負荷がかかり、全体としての耐久性に影響する可能性はあります(非常に稀)。
❗書き込みによる寿命制限
- 通常のSDカード(TLC型フラッシュ)では、1セルあたりおよそ500〜3,000回程度の書き込みが限界。
- **SLCタイプ(高耐久型)**では、およそ50,000〜100,000回の書き込みが可能。
実用的な目安(書き込み)
SDカードの種類 書き込み回数の目安 用途 TLC(一般的) 約500〜3,000回 カメラ、スマホ等 MLC(中耐久) 約10,000回程度 産業用、監視カメラ SLC(高耐久) 約50,000〜100,000回 ミッションクリティカル用途
まとめ
- 読み出しは基本的に寿命にほとんど影響を与えない。
- 寿命は主に書き込み回数によって決まる。
- 高頻度アクセス用途では、高耐久(MLC/SLC)カードの使用を推奨。
VisualStudioで東雲フォント(BDFフォーマット)をビットマップパターンのバイナリデータに変換する
東雲フォントはいくつかの形式で配布されているようですが、ドレがオリジナルなのか良くわからないので検索して一番最初に出てくるGitHub - mgo-tec/SDcard_sample_filsesに含まれている BDF形式のフォントデータを使用しました。
DBF形式のファイルはテキスト形式で、メモ帳で開けます。
ファイルの構造はChatGPTに聞きました「FONTファイルのBDF形式とは、どのような形式ですか?」
BDF(Bitmap Distribution Format)は、ビットマップフォントを定義するためのテキスト形式のファイルフォーマットです。主にX Window Systemで使用されるフォントの形式として広く知られています。
この形式は、1980年代にAdobeが定義したもので、簡単に人間が読み書きできる仕様となっています。
特徴
- テキスト形式
BDFはテキスト形式のため、テキストエディタで中身を直接確認したり編集することができます。- ビットマップフォント
各文字がピクセル(ビットマップ)として定義されており、フォントのアウトラインではなく、文字ごとのピクセル情報を保持します。- X Window Systemでの利用
主にX11で利用されるフォント形式として開発されました。サーバ側でのフォントレンダリングや設定に使用されることが多いです。
メリット
- 簡単で分かりやすい:テキスト形式のため、直接編集が可能。
- 高い互換性:X Window Systemで広く利用可能。
- 軽量:アウトラインフォント(例: TrueTypeやOpenType)よりもサイズが小さい。
デメリット
- 拡張性が低い:ビットマップフォントはスケーラビリティがなく、解像度が固定されているため、大きく表示するとピクセルが目立つ。
- アウトラインフォントに比べて柔軟性が低い:異なる解像度やサイズへの適応が難しい。
主な用途
- レトロなシステムや低解像度のディスプレイでの利用。
- エンベデッドシステムや小型端末での軽量フォントとしての利用。
- フォント開発者がデバッグや設計段階でビットマップデータを確認する際に利用。

個々のタグで意味の分からない所は順次質問します「BDFフォント・フォーマットのBBXの意味を解説して」

ChatGPTは便利ですね。
フォントファイルのフォーマットがわかった所で、このテキスト形式のファイルをバイナリデータに変換します。
フォントの文字コードはJISX0208ですが、ArduinoIDEで入力する文字コードはUTF-8です。
JISX0208とUTF-8では文字の並びが違い、文字コードに相関性がないのでコード変換には変換表を使用するのが一般的ですが、変換表を用意するのが大変なのでWindowsのAPIを使用します。
※Javaのコード変換ライブラリを使用しても同じことができると思います。JavaとC/C++のどっちが楽か…という話で…慣れてる方でやればよいのではないかと思います。
UTF-8は2~3バイトのコードで扱いが面倒なので、2バイトコードのUTF-16を使用します。
UTF-8とUTF-16は文字の並びが同じなので、変換式で文字コードを変換する事ができます。
変換プログラムの作成にはVisualStudioを使用します。VisualStudio Communityエディションは無償で使用できます。※使用にはMicrosoftアカウントが必要です。
STARTCHAR~ENDCHAR間のBITMAP以降の16進数をバイナリ値として読みだして、ビットマップ・ファイル(SINONOME_FONT.BIN)と(SINONOME_FONT_R.BIN)を生成します。


文字フォント(ビットマップパターン)へのアクセス方法
出来上がったバイナリファイルのイメージは▼SINONOME_FONT.BIN ・ SINONOME_FONT_R.BIN イメージ
0x0000 ~ 0x0FFF |
半角文字フォントイメージ | 4096Byte | 256文字×16Byte |
0x1000 ~ 0x200FFF |
全角文字フォントイメージ | 2097152Byte | 65536文字x32Byte ※実際に存在するのは6879文字、残りは空白文字 |
表示方法の都合で、ビットの並びを逆にした方が都合が良い場合があるので、SINONOME_FONT.BINとSINONOME_FONT_R.BINでは、ビットの並びが逆になっています。
例:
SINONOME_FONT.BIN : 11001001
SINONOME_FONT_R.BIN: 10010011
これは、M5Stackのライブラリを使用して2値ビットマップを表示する場合と2値ビットマップを256色or65536色表示に変換する場合で都合が良い向きが異なるためです。
文字のビットマップパターンへのアクセスは、
例えば’猫'(UTF-8コード 0xE78CAB)の場合
1, UTF-16文字コードに変換 ⇒ 0x732B ※10進数では 29483
2. ビットマップパターンの位置を計算 ⇒ 256 × 16 + 29483 × 32 = 947552
3.ファイルの読み出し位置を 947552に移動 ⇒ file.seek(947552)
4.1文字分 32Byte読み出し
となります。
東雲フォント表示サンプル
SINONOME_FONT_R.BINをSDカードのルートフォルダにコピーしてM5Stackに入れてください。サンプル文章は(面倒なので)スケッチ内に固定で持ちます。
画面スクロールは(仮想VRAMを作るとか)面倒なので1画面に収まる範囲で表示します。
・半角全角文字の混合表示
・全角漢字表示
・半角英字表示
の3パターンを表示します。
UTF-8には半角カナの文字コードが含まれますが、全角文字パターンに半角カナ文字は含まれていないので
半角カナはJISカナに変換して半角文字パターンを表示します。
UTF-16半角カナからJISコードへの変換ルールをChatGPTに質問すると
U+FF61(。)から U+FF9F(゚)までが UTF-16 の半角カナの範囲。 JIS X 0201では、対応するコードは 0xA1(。)から 0xDF(゚)です。 よって、UTF-16コード − 0xFF61 + 0xA1 でシンプルに変換できます。 |
表示にはM5StackのLCDライブラリにあるBITMAPパターンを表示するメソッドM5.Lcd.drawXBitmap( )を使用しています。
