今回やること
今回の記事は前回ESP32でILI9341(パラレル)LCDを動かすの続編になります。
前回はとりあえず、文字、グラフィックを表示出来るようにしました。
今回は日本語を表示したい!!ということで、日本語表示の実装を行いました。
メインで使うライブラリは TFT_eSPI となります。
参考にしたサイト
漢字フォントデータをSDカードから読み取ることから、配線関係は台湾のサイト(多謝!)
ソースコードは↓のサイト。こちらに掲載されているコードをTFT_eSPIで使える様にしました。
配線は台湾のサイトをそのまま流用しました
SDカード関係の配線はESP32(arduino)の標準らしい。
基板表記 接続先 信号名
SD_SS → D5 CS
SD_DI → D23 MOSI
SD_DO → D19 MISO
SD_SCK → D18 CLK
ソースコードの変更
参照元のソースコードは M5Stack用(これ欲しい!)で書かれていますので、ここを書き換える必要があります。
つまり M5.ナンチャラ を tft.ナンチャラ に書き換えればとりあえず動くのではないかと
例: M5.Lcd.fillScreen(TFT_BLACK);
を tft.fillScreen(TFT_WHITE);
な感じです。
コーディング前に行う準備関係は @taront さんのページを参考。
で、以下の様に書き換えました。
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:
}
とういう感じで表示できちゃいました😁
今後の課題
文字表示は1ピクセル毎に3重ループの中でドットを打っている感じなのでESP32でもやや遅い感じがします。
今後TFT_eSPIへの理解を深めていき、高速化を図ってみようかと思います。
感想
長年Cだけでプログラムを組んできましたので「インスタンス化」ということをしたことはありませんでしたが、今回、この便利さを思い知りました!
GithubやここのQiita等、今はネットの恩恵を受けられるのは良いですね^^
昔はプログラムが動かないとデータシート首っ引きで調べたり、メーカーに問い合わせたりして大変でしたが、今は本当に便利になったものです