M5stack の LCD に日本語漢字フォントを表示したりスクロールしたり

M5Stack,に日本語漢字フォント表示させ、スクロールさせたりしてみた M5Stack

(追記)micro SD を使う場合

この記事を書いた後に以下の記事で、micro SD 対応の Yahoo ニュース文字列スクロール記事を掲載しました。

M5Stack ( ESP32 搭載 )で、Wi-Fi 接続して、Yahoo! ニュースを4記事同時スクロールしてみた

それに伴い、こちらの記事に掲載したスケッチを micro SD カードで使う場合の方法を追記します。
(2018/4/28時点)

micro SDHC カードを用意する

micro SD カードは SDHC カードが使い易くて良いと思います。
SDXC は使用できないかも知れないのでご注意ください。
(まだ試していませんが…)
私が動作確認したカードは以下の通りです。
Class10 の方が読み書き速度が速いので良いと思われますが、M5Stack は SPI モードしか対応していないので、他の Class でもあまり変化ないものと予想しています。

micro SD カードにフォントファイルをコピーする

まず、micro SD カードを FAT32 でフォーマットしておいてください。
市販されている micro SD カードは殆どが予めフォーマット済みと思われますが、フォーマットされていない場合は以下の記事を参照してフォーマットしておいてください。

micro SD 、micro SDHC カードの初期化(フォーマット)方法

次に、micro SD カードのルートに /font/ フォルダを新たに作成して、先に紹介したようにダウンロードした3つのフォントファイル類をコピーしておいてください。

Utf8Sjis.tbl
shnmk16.bdf
shnm8x16.bdf (※shnm8x16r.bdf の名前変更したもの)

M5Stack への micro SD カードの挿入方法

下図の様に、M5Stack への micro SD カード挿入方向に注意しください。

バージョンアップしたライブラリの再インストール

この記事以降、以下のライブラリを新たにバージョンアップしました。
旧バージョンをお持ちの場合はライブラリのフォルダごと削除してから新たにインストールし直してください。

ESP32_LCD_ILI9341_SPI ライブラリ
beta ver 1.2

ESP32_SD_UTF8toSJIS ライブラリ
beta ver 1.22

ESP32_SD_ShinonomeFNT ライブラリ
beta ver 1.22

micro SD カード用スケッチの入力

先に紹介した3つの SPIFFS 用スケッチをmicro SD カード用に変更したものは以下の通りです。

「文字表示だけのスケッチ」
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include "ESP32_LCD_ILI9341_SPI.h"
#include "ESP32_SD_ShinonomeFNT.h"
#include "ESP32_SD_UTF8toSJIS.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 )
 
const char* UTF8SJIS_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* Shino_Zen_Font_file = "/font/shnmk16.bdf"; //全角フォントファイル名を定義
const char* Shino_Half_Font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義
 
ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);
ESP32_SD_ShinonomeFNT SFR(CS_SD, 40000000);
 
String test_str[7];
uint8_t test_buf[7][80][16] = {};
uint16_t test_sj_length[7];
 
//red (0-31), green (0-63), blue (0-31)
uint8_t red = 31, green = 63, blue = 31;
uint8_t V_size = 1, H_size = 1;
uint8_t num;
 
//***********セットアップ****************************
void setup() {
  Serial.begin(115200);
 
  SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く
 
  LCD.ILI9341_Init(false, 40000000);
  LCD.Display_Clear(0, 0, 319, 239);
  LCD.Brightness(255); //LCD LED Full brightness
 
  test_str[0] = "M5stackで日本語フォント表示できた";
  test_str[1] = "16×16ドット東雲フォントを使用している";
  test_str[2] = "ILI9341 LCD ディスプレイで最大40文字まで表示できる";
  test_str[3] = "半角もいけます。アイウエオカキクケコサシスセソァィゥェォャュョ 1234567890 ABCDEFG abcdef";
  test_str[4] = "40文字以上は表示されないようにした。";
  test_str[5] = "JIS第2水準漢字:纜聽艢鬣魴鯔鱸龠熙";
  test_str[6] = "●■◆▲▼〇◎□◇↓←→↑⇒〒!?";
 
  for(num = 0; num < 7; num++){
    test_sj_length[num] = SFR.StrDirect_ShinoFNT_readALL(test_str[num], test_buf[num]);
    Serial.printf("test_sj_length[%d] = %d\r\n", num, test_sj_length[num]);
  }
 
  num = 0;
  red = 31; green = 63;  blue = 31;
  int x0 = 0, y0 = 0;
  uint8_t H_size = 3, V_size = 2;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 1;
  red = 31; green = 0;  blue = 0;
  x0 = 0, y0 = 32;
  H_size = 1, V_size = 2;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 2;
  red = 0; green = 0;  blue = 31;
  x0 = 0, y0 = 64;
  H_size = 5, V_size = 1;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 3;
  red = 0; green = 63;  blue = 0;
  x0 = 0, y0 = 80;
  H_size = 1, V_size = 1;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 4;
  red = 0; green = 63;  blue = 31;
  x0 = 0, y0 = 96;
  H_size = 2, V_size = 6;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 5;
  red = 31; green = 63;  blue = 0;
  x0 = 0, y0 = 208;
  H_size = 1, V_size = 1;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
  num = 6;
  red = 31; green = 5;  blue = 15;
  x0 = 0, y0 = 224;
  H_size = 1, V_size = 1;
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[num], x0, y0, red, green, blue, test_buf[num]);
}
//***********メインループ****************************
void loop() {
 
}

「文字スクロールスケッチ」
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include "ESP32_LCD_ILI9341_SPI.h"
#include "ESP32_SD_ShinonomeFNT.h"
#include "ESP32_SD_UTF8toSJIS.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 )
 
const char* UTF8SJIS_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* Shino_Zen_Font_file = "/font/shnmk16.bdf"; //全角フォントファイル名を定義
const char* Shino_Half_Font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義
 
ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);
ESP32_SD_ShinonomeFNT SFR(CS_SD, 40000000);
 
String test_str[2];
uint8_t test_buf[2][80][16] = {};
uint16_t test_sj_length[2];
 
uint8_t Scl_Buf[ 2 ][ 16 ][ 640 ] = {};
 
//red (0-31), green (0-63), blue (0-31)
uint8_t red = 31, green = 63, blue = 31;
uint8_t V_size = 1, H_size = 1;
uint8_t num;
 
//***********セットアップ****************************
void setup() {
  Serial.begin(115200);
 
  SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く
 
  LCD.ILI9341_Init(false, 40000000);
  LCD.Display_Clear(0, 0, 319, 239);
  LCD.Brightness(255); //LCD LED Full brightness
 
  num = 0;
  test_str[num] = "M5stackで 16×16 pixel 日本語漢字(東雲フォント)の表示できた~~! ";
  num = 1;
  test_str[num] = "半角もいけます。アイウエオカキクケコサシスセソァィゥェォャュョ 1234567890 ABCDEFG abcdef";
 
  for(num = 0; num < 2; num++){
    test_sj_length[num] = SFR.StrDirect_ShinoFNT_readALL(test_str[num], test_buf[num]);
    Serial.printf("test_sj_length[%d] = %d\r\n", num, test_sj_length[num]);
  }
 
  num = 0;
  uint8_t max_txt = 40;
  uint32_t scl_speed = 0;
  H_size = 2, V_size = 5;
  red = 0; green = 63;  blue = 31;
  LCD.Scrolle_Font_SetUp(num, max_txt, test_sj_length[num], H_size, V_size, scl_speed, red, green, blue);
 
  num = 1;
  scl_speed = 10;
  H_size = 6, V_size = 2;
  red = 31; green = 5;  blue = 15;
  LCD.Scrolle_Font_SetUp(num, max_txt, test_sj_length[num], H_size, V_size, scl_speed, red, green, blue);
}
//***********メインループ****************************
void loop() {
  num = 0;
  int16_t x0 = 0, y0 = 0;
  LCD.Scrolle_HVsizeUp_8x16_Font_DisplayOut(num, x0, y0, test_buf[num], Scl_Buf[num]);
 
  num = 1;
  x0 = 0; y0 = 100;
  LCD.Scrolle_HVsizeUp_8x16_Font_DisplayOut(num, x0, y0, test_buf[num], Scl_Buf[num]);
}

「ボタン操作文字スクロールスケッチ」
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include "ESP32_LCD_ILI9341_SPI.h"
#include "ESP32_Button_Switch.h"
#include "ESP32_SD_ShinonomeFNT.h"
#include "ESP32_SD_UTF8toSJIS.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 )

 
const char* UTF8SJIS_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* Shino_Zen_Font_file = "/font/shnmk16.bdf"; //全角フォントファイル名を定義
const char* Shino_Half_Font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義
 
ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin);
ESP32_SD_ShinonomeFNT SFR(CS_SD, 40000000);

ESP32_Button_Switch BTN;
 
const uint8_t MAX_TXT_NUM = 2;
 
String test_str[ MAX_TXT_NUM ];
uint8_t test_buf[ MAX_TXT_NUM ][ 100 ][ 16 ] = {};
uint16_t test_sj_length[ MAX_TXT_NUM ];
 
uint8_t Scl_Buf[ MAX_TXT_NUM ][ 16 ][ 640 ] = {};
 
//red (0-31), green (0-63), blue (0-31)
uint8_t red = 31, green = 63, blue = 31;
uint8_t V_size = 1, H_size = 1;
uint8_t prev_V_size = 1, prev_H_size = 1;
uint16_t X0 = 0, Y0 = 0;
int32_t scl_speed = 20;
uint8_t num = 0;
 
//---------------------------------------
const uint8_t buttonA_GPIO = 39;
const uint8_t buttonB_GPIO = 38;
const uint8_t buttonC_GPIO = 37;
uint8_t btn_stateA = _Release;
uint8_t btn_stateB = _Release;
uint8_t btn_stateC = _Release;
 
boolean V_size_down = false;
 
//***********セットアップ****************************
void setup() {
  Serial.begin(115200);
  pinMode(buttonA_GPIO, INPUT); //GPIO #39 は内部プルアップ無し
  pinMode(buttonB_GPIO, INPUT); //GPIO #38 は内部プルアップ無し
  pinMode(buttonC_GPIO, INPUT); //GPIO #37 は内部プルアップ無し
 
  SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く
 
  LCD.ILI9341_Init(false, 40000000);
  LCD.Display_Clear();
  LCD.Brightness(255); //LCD LED Full brightness
 
  test_str[0] = "M5stackで日本語漢字フォント表示。東雲フォントです。サイズも変えられてスクロールもできる! ";
  test_str[1] = "←←←スクロール速度はこれが限界で、文字数格納メモリもこの程度! ";
 
  for(num = 0; num < 2; num++){
    test_sj_length[num] = SFR.StrDirect_ShinoFNT_readALL(test_str[num], test_buf[num]);
    Serial.printf("test_sj_length[%d] = %d\r\n", num, test_sj_length[num]);
  }
 
  uint8_t max_txt = 40;
  num = 0;
  red = 31; green = 0;  blue = 0;
  LCD.Scrolle_Font_SetUp(num, max_txt, test_sj_length[num], red, green, blue);
 
  num = 1;
  red = 0; green = 63;  blue = 0;
  LCD.Scrolle_Font_SetUp(num, max_txt, test_sj_length[num], red, green, blue);
 
  red = 31; green = 63;  blue = 31;
  while(1){
    btn_stateA = BTN.Button(0, buttonA_GPIO, true, 10, 300);
    switch( btn_stateA ){
      case _MomentPress:
        Serial.println("Button A Moment Press");
        Vertical_Size_Down();
        Serial.printf("V_size =%d\r\n", V_size);
        break;
      case _ContPress:
        Serial.println("-------------Button A Cont Press");
        Vertical_Size_Up();
        Serial.printf("V_size =%d\r\n", V_size);
        break;
      default:
        break;
    }
 
    btn_stateB = BTN.Button(1, buttonB_GPIO, true, 10, 300);
    switch( btn_stateB ){
      case _MomentPress:
        Serial.println("Button B Moment Press");
        Horizontal_Size_Down();
        Serial.printf("H_size =%d\r\n", H_size);
        break;
      case _ContPress:
        Serial.println("-------------Button B Cont Press");
        Horizontal_Size_Up();
        Serial.printf("H_size =%d\r\n", H_size);
        break;
      default:
        break;
    }
 
    btn_stateC = BTN.Button(2, buttonC_GPIO, true, 10, 300);
    switch( btn_stateC ){
      case _MomentPress:
        Serial.println("Button C Moment Press");
        Serial.println("Scroll Start!");
        TaskHandle_t th; //マルチタスクハンドル定義
        xTaskCreatePinnedToCore(Task1, "Task1", 8192, NULL, 5, &th, 0); //マルチタスク起動
        return;
        break;
      default:
        break;
    }
    delay(1);
  }
}
//***********メインループ****************************
void loop() {    
  btn_stateA = BTN.Button(0, buttonA_GPIO, true, 10, 300);
  switch( btn_stateA ){
    case _MomentPress:
      Serial.println("Button A Moment Press");
      prev_V_size = V_size;
      V_size--;
      if(V_size < 1) V_size = 1;
      Serial.printf("V_size =%d\r\n", V_size);
      V_size_down = true;
      break;
    case _ContPress:
      Serial.println("-------------Button A Cont Press");
      V_size++;
      if(V_size > 14) V_size = 14;
      Serial.printf("V_size =%d\r\n", V_size);
      break;
    default:
      break;
  }
 
  btn_stateB = BTN.Button(1, buttonB_GPIO, true, 10, 300);
  switch( btn_stateB ){
    case _MomentPress:
      Serial.println("Button B Moment Press");
      prev_H_size = H_size;
      H_size--;
      if(H_size < 1) H_size = 1;
      Serial.printf("H_size =%d\r\n", H_size);
      break;
    case _ContPress:
      Serial.println("-------------Button B Cont Press");
      H_size++;
      if(H_size > 15) H_size = 15;
      Serial.printf("H_size =%d\r\n", H_size);
      break;
    default:
      break;
  }
 
  btn_stateC = BTN.Button(2, buttonC_GPIO, true, 10, 300);
  switch( btn_stateC ){
    case _MomentPress:
      Serial.println("Button C Moment Press");
      scl_speed++;
      if(scl_speed > 100) scl_speed = 100;
      Serial.printf("scl_speed =%d\r\n", scl_speed);
      break;
    case _ContPress:
      Serial.println("-------------Button C Cont Press");
 
      scl_speed--;
      if(scl_speed < 0) scl_speed = 0;
      Serial.printf("scl_speed =%d\r\n", scl_speed);
      break;
    default:
      break;
  }
}
//************ マルチタスクループ ****************************
void Task1(void *pvParameters) {
  while(1){
    num = 0;
    X0 = 0, Y0 = 0;
    LCD.Scrolle_HVsizeUp_8x16_Font_DisplayOut(num, scl_speed, H_size, V_size, X0, Y0, test_buf[num], Scl_Buf[num]);
    num = 1;
    LCD.Scrolle_HVsizeUp_8x16_Font_DisplayOut(num, 0, 1, 1, 0, 224, test_buf[num], Scl_Buf[num]);
 
    if( V_size_down == true ) {
      LCD.Display_Clear( 0, V_size * 16 + Y0 - 1, 319, prev_V_size * 16 + Y0 - 1 );
      V_size_down = false;
    }
    delay(1); //most important
  }
}
//****************************************
void Horizontal_Size_Up(){
  H_size++;
  if(H_size > 15) H_size = 15;
  Serial.printf("H_size =%d\r\n", H_size);
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[0], X0, Y0, red, green, blue, test_buf[0]);
}
//****************************************
void Horizontal_Size_Down(){
  prev_H_size = H_size;
  H_size--;
  if(H_size < 1) H_size = 1;
  Serial.printf("H_size =%d\r\n", H_size);
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[0], X0, Y0, red, green, blue, test_buf[0]);
}
//****************************************
void Vertical_Size_Up(){
  V_size++;
  if(V_size > 15) V_size = 15;
  Serial.printf("V_size =%d\r\n", V_size);
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[0], X0, Y0, red, green, blue, test_buf[0]);
}
//****************************************
void Vertical_Size_Down(){
  prev_V_size = V_size;
  V_size--;
  if(V_size < 1) V_size = 1;
  Serial.printf("V_size =%d\r\n", V_size);
  LCD.Display_Clear( 0, V_size * 16 + Y0 - 1, 319, prev_V_size * 16 + Y0 - 1 );
  LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, test_sj_length[0], X0, Y0, red, green, blue, test_buf[0]);
}

以上、micro SD カード用の方法でした。

トラブルシューティング

上手く動作しない、うまくコンパイルできない、うまくSPIFFSアップロードできないなどのトラブルは以下の記事を参照してみてください。

ESP32 ( ESP-WROOM-32 ) 自分的 トラブルシューティング まとめ

編集後記

どうでしょうか?

あくまで素人自作ライブラリですから、描画速度はそれほど速くありませんし、メモリも多く消費してしまっています。
それは今後の課題です。

今回はスクロールする関数を一から見直してみましたが、やはり素人の頭と経験ではここまでが限界です。
やっぱりプロの方々はもっと効率の良い画像処理を知っているんだろうなぁと思います。
Twitter のタイムラインを見ていると、恐ろしく高速描画するものがありましたしね。
そういうのを見ると、生きている間にはとても追いつけないと落胆してしまいます。

でも、SSD1351 や SSD1331 の小型ディスプレイで限界かと思っていた情報量が、M5Stack でライブラリを作っていると、あっさり限界を超えるプログラムを組むことができました。
自分自身のプログラミング能力もちょっと進歩したように感じた次第です。

ということで、今回はここまでですが、次回はこれをスマホでコントロールさせてみたいと思っています。

ではまた・・・。

こちらの記事ではもっと簡単に文字表示や文字スクロールできるように改良していますので、合わせてご参照ください。
(2018/10/16)
https://www.mgo-tec.com/blog-entry-html-color-code-m5stack-esp32-library.html

 

コメント

  1. あいむ より:

    いつも感心しますが、なかなかやること早いですね。

    3つの日本語表示のスケッチが私のところでも動作したので報告しておきます。まだソースコードやコメントをちゃんと読んでいませんが、たぶん、同じ動作していると思います。(^^)3つ目のスケッチは、コントールの仕方がしっくりしませんが。と言っても私にはこの仕様で参考になります。

    先日アマゾンからILI9341のLCDを1185円で注文しておいたので、到着したら自作のESP32のボードにそのLCDを接続して、このスケッチが動作するか確認しようと思っています。

    • mgo-tec mgo-tec より:

      あいむさん

      いつもコメント頂き、そしてスケッチを試していただき、ありがとうございます。
      動いてホッとしました。
      それにしても、こうやって動作報告して下さるのはホントに有難いことです。
      改めて感謝いたします。
      m(_ _)m
      コーディングはまだまだ未熟なので、今後試行錯誤して、改良していこうと思っています。

      ILI9341 LCD は私も1年以上前に購入して放置しておいたものがあるので、試してみようと思っています。

  2. マッキー より:

    こんにちわ
    わたしも動作確認できました。
    素晴らしいです。
    M5stackでしか動かしていませんがILI9341 LCDで実験やってみます。
    ご活躍期待しております

    • mgo-tec mgo-tec より:

      マッキーさん

      いつもコメントありがとうございます。

      一応公開はしましたが、まだメモリを圧迫していて、他のスケッチの応用が上手くいかない場合があります。
      特に、WEBの HTTPS ページから記事を取得する場合、うまくいきません。
      画面が大きくて、なかなか難しいです。
      その辺は今後改良していく予定です。
      それまでは、文字表示だけということでご容赦ください。
      m(_ _)m

      • mgo-tec mgo-tec より:

        早速ライブラリ修正しました。
        Beta ver 1.1 になっています。
        関数の引数 uint8_t txt_length を uint16_t txt_length に修正です。
        一人で黙々と作っていると気付かないもんです。
        失礼しました。

        更新時期は気まぐれの未定で、Twitter では適宜つぶやいています。
        @mgo_tec

  3. あいむ より:

    追加の報告です。

    実は、上記私の報告で確認したのは3〜4年使っていたパソコン(MacBookPro)での話だったのですが、2、3週間前に購入してセットアップ中のパソコン(Mac mini)では、なぜか文字化けしていたので、今朝確認したら対策できたので報告しておきます。

    新しいパソコンでは、Arduino IDE1.8.5のツールのボードをESP32 Dev Moduleにすると、Partition Schemeと言う設定項目があり(今まで使っていたパソコンのArduino IDE1.8.5にはありません)、選択項目として、初期値、Minimal(2MB FLASH)
    、No OTA(Large APP)の3つあり、このスケッチを初期値でフォントのアップロードやスケッチの書き込みをすると、必ず文字化けをします。No OTA(Large APP)を設定して、フォントのアップロードとスケッチの書き込みの両方をすると、ちゃんと表示できました。

    • mgo-tec mgo-tec より:

      あいむさん

      ご報告ありがとうございます。

      Arduino core for the ESP32 の Commits on Apr 7, 2018 バージョンから Partition Scheme 項目が追加されているのは存じており、Twitter でもツイートしておりました。
      ただ、私の Windows 10 の場合は、文字化けしていても、Partition Scheme を初期値にしていてフォントをSPIFFSで再アップロードすれば、文字化け解消されました。
      私の場合、Partition Scheme を No OTA にすると、逆に別の個所の文字化けが発生してしまいました。
      謎ですね。

      個人的に想像していたのは、メモリーオーバーしたスケッチを何度もコンパイル書き込みしていて、その結果 SPIFFS のフォント領域まで破壊されてしまったと思っていました。
      MAC と Windows で違いが出るのかどうか分かりませんが、もうちょっといろいろと動かして調べてみたいと思います。

  4. JimiT より:

    Hi, nice project… I would like to find some time to test it !!

    Is this (see link below) the fast drawing code you mentioned that you saw on Twitter ?

    All credit to @ksasao for the code:

    https://github.com/PartsandCircuits/M5Stack-Counter

  5. JimiT より:

    Hi Mgo,

    Its a good blog – my pleasure to visit !

    Ah that demo….. nice one that. Thanks for the link.

  6. juchang より:

    mgo-tec 様

    HiLetgo 2.8″ ILI9341 LCD で動作確認できました。
    大きい画面に日本語を表示させるのが目標でしたので感動です。
    スケッチはそのままで接続を変えることでうまくいきました。
    sck = 18
    miso = 19 ← -1
    mosi = 23
    cs = 17 ← 14
    dc = 16 ← 27
    rst = 5 ← 33
    LCD_LEDpin = 32
    CS_SD = 4
    M5stack のボタンで文字サイズを変えたり…は、未完成(ほんの一瞬動いて止まる)ですが、今後ボタン機能を研究したいと思います。

    • mgo-tec mgo-tec より:

      juchangさん

      それはスゴイ!!
      M5Stack を使わず、別途 ILI9341 を使われたんですね。
      スバラシイ!!

      M5Stack の画面は ILI9341 にしては小さいですもんね。
      ディスプレイが大きいというのはやっぱり良いもんですね。
      どんどんブログ記事のスケッチを試していただいて、いつも感謝しております。
      ありがとうございます。
      m(_ _)m

      ところで、まだ取組中の課題が多くて、SSD1351 に着手できておりません。
      今しばらくお待ちくださいませ。
      m(_ _)m

  7. でん より:

    いつも参考にさせていただいております。
    どうもありがとうございます!
    さて、こちらのコードですが表示はされるものの、文字が圧縮されている形で判読不可の状態のようです
    *Arduino1.8.5以外は、ボードマネージャー経由でインストールしたESP32環境他、 “ESP32_LCD_ILI9341_SPI.h”
    “ESP32_SPIFFS_ShinonomeFNT.h”
    “ESP32_SPIFFS_UTF8toSJIS.h”
    など全て新規にセットアップいたしました。
    どこを直せば正常に表示されるかヒントを教えていただけると幸いです。

    • mgo-tec mgo-tec より:

      「でん」さん

      記事をご覧いただき、ありがとうございます。

      ライブラリやフォントファイルが散らばっていて、インストールし辛く、申し訳なく思っております。
      私自身も久々にこの記事を見返して、改めてインストールし辛いなぁと思いました。
      近々、徐々にまとめて行こうとは考えております。

      さて、ライブラリはインストール済みということで、その他を確認させてください。

      1. スケッチフォルダに /data/font/ フォルダを作って、以下の3種類のフォントを保存しましたでしょうか?
        (私は font フォルダを作り忘れていて、/data/フォルダに置いてしまって文字化けする失敗を何度もしました。)
        Utf8Sjis.tbl
        shnmk16.bdf
        shnm8x16.bdf ( “r”文字を削除したファイル名)

      2. その3つのフォントファイルを SPIFFS プラグインアップローダーでアップロードされましたでしょうか?
        アップロード方法は以下の記事を参照してください。
        ESP-WROOM-32 ( ESP32 ) SPIFFS アップローダープラグインの使い方
        なお、ブログには記載しておりませんが、最近発見したことがあります。
        Arduino-ESP32 stable 1.0.0 では、ESP32 のパーティション領域をサイズアップしなくても、Arduino IDE の「ツール」で、
        Partition Scheme “No OTA(Large APP)”
        にすればOKです。
        そこで、まず、フォントをSPIFFSアップロードしてから、次にスケッチをコンパイル書き込みしてください。
        その時、必ずシリアルモニタを閉じておいてください。

      おそらく、文字化けの原因は SPIFFS にフォントデータを正しくアップロードできていないことが多いです。
      以上、ご確認ください。

      • でん より:

        でんです。
        早々のご回答ありがとうございます!
        追って状況を報告させていただきます。

      • でん より:

        確認いたしました。きちんと動いています!

        >スケッチフォルダに /data/font/ フォルダを作って、以下の3種類のフォントを保存しましたでしょうか?

        その通りでした。
        「data」を「font」に入れ替えた状態で、東雲フォントを入れておりました(><)
        よくスケッチを見れば理解できるところを、最近の頻繁なアップデートが原因と勘繰り質問してしまった次第です。

        どうもありがとうございました。

        • mgo-tec mgo-tec より:

          でん さん

          動いて良かったです(^^)
          自分自身も久々に使うと、そこを忘れるんですよね。

          因みに、最近私はSPIFFSを殆ど使っておりません。
          micro SD カードの方を使った方が圧倒的に表示速度速いですし、Arduino-ESP32のアップデートを気にしなくて済みます。
          東雲フォント表示は micro SDHC コードを使う事をお勧めします。

  8. Watchbase より:

    こんにちは。ESP32 devのボードとHiLetgo 2.8″ ILI9341 LCDを使って、日本語表示させたくてこちらに辿り着いて試しているのですが、どうしても文字が正しく表示されません。 いえ、文字そのものは表示されているのですが、反転しているのです。表示が右から左に流れており、さらに、その文字が鏡に映したように反転しています。
    何かヒントを頂けないでしょうか?
    宜しくお願いします。

    • mgo-tec mgo-tec より:

      Watchbaseさん

      ブログをご覧いただきありがとうございます。

      この記事は2年も前に書いたので、ソースコードやライブラリも古いものでした。
      最近のM5StackのLCDディスプレイもIPSタイプに変更されており、過去のコードが正常に動作しなくなっております。
      (IPSディスプレイについては下記記事を参照してみてください)
      M5Stack FIRE (PSRAM付き)およびIPSタイプのLCD ILI9342Cを使ってみた

      そこで、私の自作ESP32_LCD_ILI9341_SPIライブラリを久々に更新しておきました。
      beta ver 1.27
      です。
      https://github.com/mgo-tec/ESP32_LCD_ILI9341_SPI
      新しいライブラリをインストールする場合は古いライブラリのフォルダごと削除してからインストールしてください。

      そして、

      LCD.ILI9341_Init();

      という行の後に、以下のようにローテーションおよび反転関数を追加してみてください。

      LCD.ILI9341_Init();
      LCD.Disp_Rotation(4);
      

      Disp_Rotationの数値を0~13、又は250~254の値に変えてコンパイルしてみてください。
      M5Stackの場合、左右反転の値は4です。

      これで試してみて下さい。

      • 匿名 より:

        早々にありがとうございます。 漢字は正しく表示されるようになりました!
        LCD.Disp_Rotation(4);だと、画面の範囲を超えたときにカットされるという機能は動作せず、行の前に戻って上書きされてしまいました。また、画面の下、1/4くらいの背景が白くなっていたので、画面のサイズの識別がおかしいのかなと思い、LCD.Disp_Rotation(251)に変えたところ、全て正しく表示されるようになりました。 ありがとうございました。 素晴らしい

        • mgo-tec mgo-tec より:

          おー!
          無事動いて良かったです。

          古いプログラムなので、私自身改めて見ると、コーディングスタイルが統一されていなくて恥ずかしい限りです。
          でも、お役に立てて光栄です。

          あと、もう一つの件について、確かに受け取らせて頂きました。
          本当にありがとうございました。
          (該当ページのコメント欄に匿名コメントしております)
          m(_ _)m

タイトルとURLをコピーしました