Excel で自作したカスタムフォントを M5stack に表示してみる

記事公開日:2018年5月13日


スポンサーリンク

カスタム(自作)フォントをバイナリ形式ファイルに変換する

では、今度はカスタム(自作)フォントを東雲フォントに埋め込まずに、バイナリ化したファイルに変換してみたいと思います。

バイナリ化すると、先ほどの様に手軽にテキストエディタで編集というわけにはいきませんが、フォントのアドレスに直接アクセスできて、プログラムが簡単になり、表示速度も速くなります。

まず、MyFont_ver3.0.xlsx ファイルを開きます。
そして、今度は下図の様に
CSV_fileOUTput シート
を開きます。

[pic20]

m5stack_customfnt20.jpg


このページを表示しながら、先ほどと同じように、CSVファイルとしてエクスポートします。
ここでは、ファイル名を
MyFont_ver3.0.csv

としておきます。

保存したCSV ファイルテキストエディタで見てみると、こんな感じになります。

[pic22]

m5stack_customfnt22.jpg


東雲フォント時のBDFデータと異なるデータ並び順に注意してください。
バイナリにした場合、こちらの並び順の方が圧倒的に手軽にデータを処理できます。

また、なぜバイナリ形式の方は処理が速いのかと言うと、テキストファイルを Stirling などのバイナリエディタで開いてみると、分かります

[pic23]

m5stack_customfnt23.jpg


Arduino – ESP32 の SDライブラリでテキストデータを読み込むと、バイナリ値で読み込まれます。
すると、上図でみて分かる通り、最初の 1F というテキストデータは、
0x31
0x46
という数値で読み込まれます。
これは ASCII コード値そのものです。
これを、0x1F という数値に再変換するにはいろいろな計算式や条件式を加えないといけないので、当然速度が遅くなるというわけです。

ということで、このCSV ファイルをバイナリファイルに一括変換してみます。

まず、M5Stack のmicro SD カードにファイル
MyFont_ver3.0.csv
を/font/フォルダ内にコピーしておき、パソコンとM5Stack をUSB接続して、Arduino IDE を起動してください。

次に、先にGitHub からダウンロードしておいた、
Excel_Make_Font_CSV
の中の、

\Excel_Make_Font_CSV\Arduino_ESP32_CSV_Binary_Convert\M5Stack\M5Stack_MyFont_CSV_Binary_Convert_ver3.0

にある、

M5Stack_MyFont_CSV_Binary_Convert_ver3.0.ino

というファイルをArduino IDE で開いて下さい。
必要ならばファイル名を変更するなりしてスケッチを編集してください。

シリアルモニターを 115200 bps で起動しておいてください。

その後、コンパイル書き込み実行させてください。

すると、シリアルモニターにこのように表示されればOKです。

[pic24]

m5stack_customfnt24.jpg



これで新たに、
MyFont_ver3.0.fnt
というバイナリ形式ファイルが生成されます。

M5Stack の micro SD カードをパソコンに差し替え、コンバートしたフォントファイルをStirling などのバイナリエディタで見てみると、こうなります。

[pic25]

m5stack_customfnt25.jpg


ちゃんとバイナリ数値で書き込まれていますね。
当然、右側のテキストビューワーは文字化けします。

では、次ではこのバイナリフォントファイルで M5Stack のディスプレイに表示させてみます。

M5Stack にバイナリ形式カスタムフォントを表示させる

では、前項で作ったバイナリ形式カスタム(自作)フォントファイルを使って M5Stack のディスプレイに表示させてみたいと思います。
Arduino IDE を起動し、以下のスケッチを入力してみてください。

#include "ESP32_LCD_ILI9341_SPI.h" //beta ver 1.25-
#include <SD.h>

const int8_t sck = 18; // SPI clock pin
const int8_t miso = -1; // MISO(master input slave output) don't using
const int8_t mosi = 23; // MOSI(master output slave input) pin
const int8_t cs = 14; // Chip Select pin
const int8_t dc = 27; // Data/Command pin
const int8_t rst = 33; // Reset pin
const int8_t LCD_LEDpin = 32;

const uint8_t CS_SD = 4; //SD card CS ( Chip Select )

ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);

const uint8_t MAX_TXT_NUM = 4; //文字列表示最大行数

const char* my_fontfile = "/font/MyFont_ver3.0.fnt";
File _MyF;

void setup() {
  Serial.begin(115200);
  delay(1000);
  LCD.ILI9341_Init(false, 40000000); //※M5StackでSDカードと併用する場合は必ずfalseにすること
  LCD.Display_Clear();
  LCD.Brightness(255); //LCD LED Full brightness

  SD.begin(CS_SD, SPI, 24000000, "/sd");
  _MyF = SD.open(my_fontfile, FILE_READ);
  if (!_MyF) {
    Serial.print(my_fontfile);
    Serial.println(" File not found");
    return;
  }else{
    Serial.print(my_fontfile);
    Serial.println(" File read OK!");
  }

  uint8_t test_buf[ MAX_TXT_NUM ][ 20 ][ 16 ] = {};
  uint16_t test_length[ MAX_TXT_NUM ] = {}; //S
  uint8_t num = 0; //文字列番号
  uint8_t X0 = 0, Y0 = 0;
  uint8_t Zen_or_Han = 2; //半角 = 1, 全角 = 2
  uint8_t Fnt_Cnt = 0; //半角相当フォントカウント
  uint8_t red = 31, green = 63, blue = 31;
  uint8_t H_size = 2, V_size = 3; //H_size(水平方向サイズ)、V_size(垂直方向文字サイズ)

  for( num = 0; num < MAX_TXT_NUM; num++ ){
    for( int i = 0; i < 10; i++ ){
      MyFont_SD_Read(_MyF, Zen_or_Han, i + 10 * num, &test_buf[ num ][ Fnt_Cnt ]);
      Fnt_Cnt = Fnt_Cnt + Zen_or_Han;
    }
    test_length[ num ] = Fnt_Cnt;
    Fnt_Cnt = 0;
    LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_length[ num ], X0, num * 48, red, green, blue, test_buf[ num ]);
  }

  //※以下、ESP32_LCD_ILI9341_SPIライブラリ beta ver 1.25~、背景色指定可能
  num = 4;
  H_size = 3, V_size = 3;
  red = 31, green = 0, blue = 0; //文字色指定
  uint8_t bg_red = 31, bg_green = 63, bg_blue = 0; //背景色指定

  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, 2, X0, num * 48, red, green, blue, &test_buf[ 2 ][ 0 ], bg_red, bg_green, bg_blue);
  red = 0, green = 0, blue = 31;
  bg_red = 0, bg_green = 63, bg_blue = 31;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, 2, 48, num * 48, red, green, blue, &test_buf[ 2 ][ 4 ], bg_red, bg_green, bg_blue);
  red = 31, green = 0, blue = 0;
  bg_red = 0, bg_green = 63, bg_blue = 0;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, 2, 96, num * 48, red, green, blue, &test_buf[ 3 ][ 2 ], bg_red, bg_green, bg_blue);
}

void loop() {

}

//*****************************************************
void MyFont_SD_Read(File F, uint8_t ZorH, uint8_t num, uint8_t buf[][16]){
  F.seek(num * (16 * ZorH));
  F.read(buf[0], 16);
  F.read(buf[1], 16);
}

※このスケッチの ESP32_LCD_ILI9341_SPI ライブラリは、beta ver 1.25 以上でないと動作しませんのでご注意ください

64-70行目の関数は、今まで使用していた関数にバックグラウンドカラー(背景)が指定できるようになりました。
もちろん、今までの様式の関数もそのまま使えます。

これ、実は、C++ のクラス宣言で、デフォルト引数を使っているんです。
今までも何となく使っていましたが、今回の様に、今までの関数を変更せずに、後で引数を追加したいときにすごく便利だということが判明して、我ながら大発見でした。
プロの方々ならば当たり前の知識でしょうが、素人の私にはとても新鮮でした。

78-82行でバイナリ形式フォントファイルを読み込んでいます。
テキスト形式と違って、バイナリ形式だと計算がかなり簡単でシンプルになりますね。

では、これをコンパイル書き込み実行してみてください。
下図の様に表示されればOKです。

[pic40]

m5stack_customfnt40.jpg


次の項では、カスタムフォントで表示させた NTP 自動時刻補正時計を作ってみます。


スポンサーリンク


コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください