ゆるく楽しむプログラミング
> トップページ > メニュー > 東雲フォントROMを作ってみた

東雲フォントROMを作ってみた

TFT液晶に天気予報を表示するために、東雲フォントをEEPROMに書き込んで、東雲フォントROMを作ってみました。
EEPROMは 24FC1025 を使用します。 使用方法は 『I2C接続:1MBit EEPROM 24FC1025』 を参照。

フォントデータのサイズがスケッチに組み込むには大きすぎるので、M5Stackを使ってSDカード経由でEEPROMに書き込みます。

VisualStudioで東雲フォント(BDFフォーマット)をEEPROMに書き込めるバイナリデータに変換する

東雲フォントはいくつかの形式で配布されているようですが、ドレがオリジナルなのか良くわからないので検索して一番最初に出てくる
GitHub - mgo-tec/SDcard_sample_filsesに含まれている BDF形式のフォントデータを使用しました。
DBF形式のファイルはテキスト形式で、メモ帳で開けます。

ファイルの構造はChatGPTに聞きました「FONTファイルのBDF形式とは、どのような形式ですか?


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


ChatGPTは便利ですね。
フォントファイルのフォーマットがわかった所で、このテキスト形式のファイルをEEPROMに書き込めるバイナリデータに変換します。
フォントの文字コードは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進数をバイナリ値として読みだして、フォントパターン(FONTDATA.BIN)とINDEX(FONTINDEX.BIN)を生成します。

INDEX
0x0000

0x01FF
半角文字のINDEX 256バイト  半角文字の文字コードに対応する位置に、文字バターンの番号が入る。 
半角文字は221文字
0x0100

0x01FF 
全角文字のINDEXテーブルの番号 256バイト UTF-16の上位バイトに対応する位置に、下位バイトに対応する文字のパターンへのINDEXの番号
1~255の番号が入る。※0は該当なし
01xxhや、FExxhなど、存在しない文字コードもあるので、実際に使用する上位バイトは93種類
0x0200

0x03FF
全角文字のINDEXテーブル1
(UTF16コード1バイト目が0x00)
FONTイメージのアドレス
 
512Byte  フォントイメージの番号が入る
半角文字2文字を全角1文字とカウントするため、全角文字は111番目から始まる。 
INDEテーブル2 ・・・ INDEXテーブル92(表記省略)
0xBC00

0xBDFF
INDEXテーブル93
(UTF16コード1バイト目が0xFF)
FONTイメージのアドレス
 
512Byte  フォントイメージのアドレスが入る  

FONTイメージ
0x0000

0x0DD0 
半角文字フォントイメージ 3536Byte 221文字×16Byte  
空き 16Byte
半角2文字を全角文字1文字としてカウントするための調整
0x0DE0

0x369C0 
フォントイメージ  220128Byte 6879文字x32Byte

実行形式ファイル FONT2ROM-EXE.zip ※FONTINDEX.BIN / FONTDATA.BINを含む

ソースコード FONT2ROM.zip

EEPROMへの書き込み

作成したFONTINDEX.BIN / FONTDATA.BINをSDカードにコピーしてM5Stack BASICを使用してEEPROに書き込みます。

EEPROM 24FC1025のピン配置
   
A0 I2C アドレスセレクト
A0 A1 A2 I2Cアドレス
GND GND GND  0x50
Vcc  GND  GND  0x51
GND  Vcc  GND  0x52
Vcc  Vcc  GND  0x53
GND  GND  Vcc  0x50 / 0x54
Vcc  GND  Vcc   0x51 / 0x55
GND  Vcc  Vcc   0x52 / 0x56
Vcc  Vcc  Vcc   0x53 / 0x57
A1
A2
GND GND 
Vcc 2.5~5.5V 
WP 書き込み禁止 
SCL I2C-SCL
SDA I2C-SDA 

   
SCL M5Stack BASICの22番ピン(SCL)へ 
SDA  M5Stack BASICの21番ピン(SDA)へ 
Vcc  M5Stack BASICの5Vピンへ 
GND  M5Stack BASICのGNDピンへ 
 

EEPROMは64KByteのブロックごとに名称をつけて管理します。
I2Cアドレス 呼称 用途 
0x50 ROM 1 INDEX
0x54    
0x51 ROM 2  フォントパターンデータ
0x55 ROM 3
0x52 ROM 4
0x56 ROM 5 

フォントパターンは65536バイトに区切ってROM2~ROM5も書き込みます。

ArduinoIDEスケッチ FontROM-Write.zip


※SDカードが認識できなくて、初期化でエラーになることがあります。
 SDカードを何度か抜き差しすると認識するのですが、SDカードの相性があるのかも。

東雲フォント表示サンプル

サンプル文章は(面倒なので)スケッチ内に固定で持ちます。
画面スクロールは(仮想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( )を使用しています。

東雲フォント表示デモ fontROM-M5Stack.zip



解説動画