ESP32でILI9341(パラレル)LCDを動かす(漢字表示編)

# 今回やること
今回の記事は前回[ESP32でILI9341(パラレル)LCDを動かす](https://qiita.com/heisan_desu/items/eca17ea9a73df7bed58c)の続編になります。
前回はとりあえず、文字、グラフィックを表示出来るようにしました。
今回は日本語を表示したい！！ということで、日本語表示の実装を行いました。
メインで使うライブラリは TFT_eSPI となります。

# 参考にしたサイト
漢字フォントデータをSDカードから読み取ることから、配線関係は台湾のサイト（多謝！）

https://blog.xuite.net/iamleon/blog/589250819

ソースコードは↓のサイト。こちらに掲載されているコードをTFT_eSPIで使える様にしました。

https://qiita.com/taront/items/7900c88b9e9782c33b08

配線は台湾のサイトをそのまま流用しました
SDカード関係の配線はESP32（arduino）の標準らしい。

基板表記　　接続先　信号名
SD_SS　→　　D5　　　CS
SD_DI　→　　D23　　MOSI
SD_DO　→　  D19　　MISO
SD_SCK　→　D18　　CLK

![1250370584_x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118608/4736bf8e-60c2-3c97-2ca7-b65bf931765a.jpeg)

# ソースコードの変更
参照元のソースコードは M5Stack用（これ欲しい！）で書かれていますので、ここを書き換える必要があります。
つまり M5.ナンチャラ を tft.ナンチャラ に書き換えればとりあえず動くのではないかと
例:　`M5.Lcd.fillScreen(TFT_BLACK);` を `tft.fillScreen(TFT_WHITE);` な感じです。
コーディング前に行う準備関係は @taront さんの[ページ](https://qiita.com/taront/items/7900c88b9e9782c33b08)を参考。
で、以下の様に書き換えました。
```cpp 
kanji_test.ino
#include "TFT_eSPI.h"
#include "SPI.h"
#include <sdfonts.h>

#define SD_PN 5

TFT_eSPI tft = TFT_eSPI();

// フォントデータの表示
// buf(in) : フォント格納アドレス
// ビットパターン表示
// d: 8ビットパターンデータ
void fontDisp(uint16_t x, uint16_t y, uint8_t* buf) {
  // 白地に黒の字で表示するようにしています。
  // カラーコードを引数で与える様にすれば行、或いは文字毎に色が変えられそうです
  uint32_t txt_color = TFT_BLACK;
  uint32_t bg_color = TFT_WHITE;

  uint8_t bn = SDfonts.getRowLength();               // 1行当たりのバイト数取得
//  Serial.print(SDfonts.getWidth(), DEC);            // フォントの幅の取得
//  Serial.print("x");
//  Serial.print(SDfonts.getHeight(), DEC);           // フォントの高さの取得
//  Serial.print(" ");
//  Serial.println((uint16_t)SDfonts.getCode(), HEX); // 直前し処理したフォントのUTF16コード表示

  for (uint8_t i = 0; i < SDfonts.getLength(); i += bn ) {
    for (uint8_t j = 0; j < bn; j++) {
      for (uint8_t k = 0; k < 8; k++) {
        if (buf[i + j] & 0x80 >> k) {
          tft.drawPixel(x + 8 * j + k , y + i / bn, txt_color);
        } else {
          tft.drawPixel(x + 8 * j + k , y + i / bn, bg_color);
        }
      }
    }
  }
}


// 指定した文字列を指定したサイズで表示する
// pUTF8(in) UTF8文字列
// sz(in)    フォントサイズ(8,10,12,14,16,20,24)
void fontDump(uint16_t x, uint16_t y, char* pUTF8, uint8_t sz) {
  uint8_t buf[MAXFONTLEN]; // フォントデータ格納アドレス(最大24x24/8 = 72バイト)
  SDfonts.open();                                   // フォントのオープン
  SDfonts.setFontSize(sz);                          // フォントサイズの設定
  uint16_t mojisu = 0;
  while ( pUTF8 = SDfonts.getFontData(buf, pUTF8) ) { // フォントの取得
    fontDisp(x + mojisu * sz, y, buf);                 // フォントパターンの表示
    ++mojisu;
  }

  SDfonts.close();                                  // フォントのクローズ
}


void setup() {
  Serial.begin(115200);

  tft.begin();
  tft.setRotation(1);   // 横長で表示する。

//  tft.setBrightness(100);
  tft.fillScreen(TFT_WHITE);

  SDfonts.init(SD_PN);
  Serial.println(F("sdfonts liblary"));

  fontDump(0, 10, "国境の長いトンネルを抜けると", 20);
  fontDump(0, 40, "雪国であった。夜の底が白くなった。", 20);
  fontDump(0, 70, "信号所に汽車が止まった。", 20);
  fontDump(0,100, "向側の座席から娘が立ってきて、",20);
  fontDump(0,130, "島村の前のガラス窓を落した。",20);
  fontDump(0,160, "雪の冷気が流れ込んだ。娘は窓",20);
  fontDump(0,190, "いっぱいに乗り出して、遠くへ",20);

}

void loop() {
  // put your main code here, to run repeatedly:
}
```
実行画面
![20230405_172119.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118608/b6f2f533-3a79-2e7e-8582-1cfa4cfac003.jpeg)

とういう感じで表示できちゃいました😁

# 今後の課題
文字表示は1ピクセル毎に3重ループの中でドットを打っている感じなのでESP32でもやや遅い感じがします。
今後TFT_eSPIへの理解を深めていき、高速化を図ってみようかと思います。

# 感想
長年Cだけでプログラムを組んできましたので「インスタンス化」ということをしたことはありませんでしたが、今回、この便利さを思い知りました！
GithubやここのQiita等、今はネットの恩恵を受けられるのは良いですね＾＾
昔はプログラムが動かないとデータシート首っ引きで調べたり、メーカーに問い合わせたりして大変でしたが、今は本当に便利になったものです:smiley: