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

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

文字列をスクロールさせるサンプルスケッチ

次に、文字列をスクロールさせる関数を使ってみるサンプルスケッチを紹介します。

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

#include "ESP32_LCD_ILI9341_SPI.h"
#include "ESP32_SPIFFS_ShinonomeFNT.h"
#include "ESP32_SPIFFS_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 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_SPIFFS_ShinonomeFNT SFR;

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.SPIFFS_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く

  LCD.ILI9341_Init();
  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]);
}

【解説】

●24行:
スクロールさせる場合、別途グローバル変数領域で専用のバッファを宣言しなければなりませんので、かなりのメモリを消費します。
ILI9341 ディスプレイ 65Kカラーの場合、1pixel は 2byte で表現します。
ですから、横幅は 640 byte 必要になりますので、これだけの配列を宣言することになってしまいます。
私のプログラミングが未熟で、こういう方法しか思い浮かびませんでした。
文字列を2列スクロールさせる領域を確保していますが、多くなるとメモリオーバーで、動作しなくなるので注意してください。

●52-56行:
56行や 62行で文字列スクロールをセットアップするために、変数を予め代入します。
max_txt は、サイズ1倍の場合の文字表示数です。
これを少なくすると、スクロールする横幅を決定できます。
ただし、サイズアップした場合、その分を換算するように関数を組んでおりません。
例えば、max_txt = 30 としても、横幅を6倍にしてしまうと画面からはみ出てしまうので、意味の無い設定となってしまいます。
この辺はまだ試作段階なので、いろいろ試してみてください。
スクロール速度は、ゼロが最速です。

●68行目:
メインループ内でこの関数を置くことによって、文字列がスクロールします。
サイズを大きくしてしまうと、描画速度が追い付かないので、スムースさに欠けます。
横幅サイズを大きくすると、描画計算が少なくなるので、スクロール速度が速くなります。

では、Arduino IDE でコンパイル書き込み実行させてみてください。
下図の様に2列の文字サイズとスクロール速度が変わっていればOKです。

M5Stack のボタンで文字サイズを変えたり、スクロール速度を変えたりするサンプルスケッチ

次は、自作ボタンライブラリを使って、M5Stack のボタンで文字サイズを変更したり、スクロール速度を変えてみたりするスケッチを紹介します。
この場合、ボタンスイッチをメインループ内で制御して、文字スクロールをマルチタスクで動作させています。
ボタンスイッチに関して、割込みは一切使用していません。

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

#include "ESP32_LCD_ILI9341_SPI.h"
#include "ESP32_Button_Switch.h"
#include "ESP32_SPIFFS_ShinonomeFNT.h"
#include "ESP32_SPIFFS_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 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_SPIFFS_ShinonomeFNT SFR;
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.SPIFFS_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file); //ライブラリ初期化。3ファイル同時に開く

  LCD.ILI9341_Init(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]);
}

【解説】

●2行目:
ここで、新たに自作のボタンスイッチライブラリをインクルードしています。

●31-36行:
ここでは、プログラムを分かりやすくするために、敢えてグローバル変数領域で宣言しています。
これらは、関数呼び出し時に直接入力して良いものです。
33行目の変数は、文字をサイズダウンする場合に描画を一部消去するために使う変数です。

●39-46行:
自作ボタンスイッチライブラリで使う定数や変数宣言です。
_Release などの値は、ライブラリ内のグローバル変数領域でenum宣言しているものです。
enum の値については前回の記事を参照してください。
46行目の変数は、スクロール関数をマルチタスクループ内に置いているため、ボタンスイッチによる変数変更を受け渡すためのものです。

●57行:
LCD ILI9341 の SPI クロック周波数は、データシートによると最高 10MHz のはずですが、テストしてみた結果 40MHz まで動作しました。
高速に描画させたいならば、ここは 40MHz にすると良いと思います。
ただ、動作保証はしません。

●72-76行:
前項で使ったスクロールセットアップ関数と異なる変数のセットアップ関数ですです。
サイズやスクロール速度を代入しません。
スクロール動作中にサイズアップやスクロール速度をコントロールするためです。

●79-126行:
文字をスクロールせずに固定位置で文字サイズを決める whileループです。
最初の動画を見てもらえれば分かると思います。
決定したら、Cボタンを押すと、117-118行で、マルチタスクを定義して、whileループを抜けます。

●129-185行:
メインループはボタンスイッチ専用ループにしています。
ボタンスイッチの変数については以下の記事を参照してください。
M5Stack ボタンスイッチの、チャタリング、誤作動防止、感度調整、長押し設定を考えてみる

●188-202行:
マルチタスクを Core 0 で動かしています。
Core 1 はメインループです。
ここでは、文字スクロール専用ループにしています。
196-199行では、縦方向の文字サイズがサイズダウンされた場合、余った画像を消去しています。
ここで、V_size_down 変数をメインループのボタンスイッチ制御から受け取っています。
グローバル変数領域で宣言すれば受け渡し可能かと思ってやってみても、うまくボタンに反応してくれませんでした。
恐らく、1ループがボタンスイッチの押された時間に追い付かなかったものと思われ、この方法を使ってみました。

以上、これをコンパイル実行書き込みしてみてください。
最初に紹介した動画のように操作できればOKです。

因みに、長押しは0.3秒以上です。
この感度は各自変えてみて下さい。
また、操作方法は以下の通りです。

【A button】
長押し → 垂直方向サイズアップ
瞬時押し→垂直方向サイズダウン

【B button】
長押し → 水平方向サイズアップ
瞬時押し→水平方向サイズダウン

【C button】
固定画面では、スクロールスタート。
スクロールスタートしたら、
長押し →スクロール速度アップ
瞬時押し→スクロール速度ダウン

次のページでは、新たに micro SD カード用のスケッチを追記しています。

コメント

  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をコピーしました