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

M5Stack,に日本語漢字フォント表示させ、スクロールさせたりしてみた M5Stack
この記事は SPIFFS 用ですが、記事の最後のページで、micro SD カード用のスケッチを追記しました。
それに伴い、以下のライブラリをバージョンアップしました。

●ESP32_LCD_ILI9341_SPIライブラリ
beta ver 1.2
●ESP32_SD_UTF8toSJIS ライブラリ
beta ver 1.22
●ESP32_SD_ShinonomeFNT ライブラリ
beta ver 1.22

(2018/04/28)

 

こんばんは。

前回に引き続き、M5Stack ( ESP32搭載 )でいろいろ遊んでみます。

今回は、M5Stack の TFT LCD (液晶ディスプレイ)ILI9341 に、日本語漢字フォントを表示させてみました。
使用したフォントはいつも当ブログで使っている、東雲(しののめ)フォントを使いました。

ただ、今回はスクロールしながら M5Stack のボタン操作で縦横にサイズを変えられるようにしてみました。

スポンサーリンク

以前、OLED SSD1331SSD1306 で表示させていましたが、320 x 240 pixel の大きなディスプレイで作ったのは初めてです。
さすがに情報量が多いので、沢山の文字を表示できましたし、文字をサイズアップしても有り余るほどのスペースで、なかなか良いです。

このサイズのディスプレイ一杯にビットマップフォントを表示させようとすると、描画速度が問題になってきますが、SPI通信でも意外とそれなりに速く表示させることができました。

できるだけ、高速で描画できるように、老いた脳ミソをフル回転させてプログラムを組んでみました。
スクロールさせる関数も一から見直し、サイズアップしてもある程度の速度でスクロールさせることができました。

では、早速以下の動画をご覧ください。

プロならばもっとスムースで高速描画できるプログラムが組めそうですね。
素人の私にはこれが限界です。

でも、文字をかなりサイズアップしても、有る程度の速度でスクロールしてくれるようになりました。
しかも、OLED SSD1331SSD1306より遙かに多い情報量なのにこの速度です。
これは、自分的にはちょっとした進歩です。

文字サイズを大きくすると、スクロール速度が上がります。
逆に小さくすると情報量が多くなるので、スクロール速度が下がります。
Cボタンは長押しでスクロール速度アップしていますが、文字サイズの効果の方が大きいです。
文字サイズを縦方向5倍以上にしてしまうと、画面のスムースさが欠けてしまいますね。
これは今後の課題です。
因みに、バッテリーは15分程しか持ちません。
CPUをフル稼働させていますので、仕方ありません。

でも、これはちょっとしたメッセージボード電光掲示板として使えるのではないでしょうか。

ということで、これの作り方を説明してみます。
因みに、以下で紹介するプログラムは素人コードですので無保証です。
無駄が多かったり、誤った使い方をしている場合があります。
その場合、コメント投稿等でご連絡いただけると助かります。

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

 

使うもの

M5Stack

ESP32 搭載の技適取得済みモジュールです。
今、とても人気があり、多くの所で欠品中です。

(追記)
M5Stack Basicは、この記事を書いた当時より格段にバージョンアップしております。
以下のスイッチサイエンスさんの公式サイトをご参照ください。
https://www.switch-science.com/collections/%E5%85%A8%E5%95%86%E5%93%81/products/9010

※M5Stack Gray(9軸IMU搭載)現在は販売終了しております

 

パソコン、USBケーブル等

ここでは、Windows 10 環境で説明しています。

Arduino – ESP32 や SPIFFS 設定、ライブラリインストール、Fontファイルアップロードを済ませておく

Arduino core for the ESP32 のインストールや、SPIFFS フラッシュ設定、東雲フォントのダウンロード等については、新たに以下の記事にまとめました。
ただ、それでもダウンロードリンクや、How to ページが散在していますので、ご容赦ください。

Arduino – ESP32 ( SPIFFS ) 自作Fontライブラリインストール方法

新たに作成した自作ライブラリのダウンロードおよびインストール

前回や、前々回の記事から、今回は新たに Arduino core for the ESP32 用のライブラリを自作しました。
GitHub の以下のリンクから ZIP ファイルをダウンロードして、Arduino IDE にインストールします。
ZIPファイルのインストール方法は以下の記事を参照してください。

GitHubにある ZIP形式ライブラリ のインストール方法 ( Arduino IDE )

ESP32_LCD_ILI9341_SPI ライブラリ

自作ライブラリ ESP32_LCD_ILI9341_SPI を修正し Beta ver 1.1 では長い文字列の表示が制限されてしまう問題を修正しました。
関数の引数 uint8_t txt_length を uint16_t txt_length に変更。
現在は beta ver 1.2 になっています。
(2018/04/28)

これは、M5Stack に SPI 接続されている TFT LCD ( 液晶ディスプレイ ) ILI9341 を駆動するためのライブラリです。
グラフィック描画に加えて、東雲フォントを表示させる関数や、スクロールさせる関数を追加しています。
素人自作なので、描画速度は公式ライブラリに及びませんが、何とか日本語フォントを表示させることができました。

https://github.com/mgo-tec/ESP32_LCD_ILI9341_SPI

ESP32_Button_Switch ライブラリ

ボタン操作だけに特化したライブラリです。
スケッチプログラムの行数を節約するために作りました。
前回の記事にあるように、長押し設定ができる関数を作っています。

https://github.com/mgo-tec/ESP32_Button_Switch

東雲フォント表示のみのサンプルスケッチ

では、まず、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[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.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

  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() {

}

【解説】

●1-3行目
私の自作ライブラリのインクルードです。

●5-11行:
M5Stack の LCD ILI9341 に SPI 接続されている、ESP32 の GPIO 番号設定です。
これに関しての詳細は、前々回の記事を参照してください。

●13-15行:
先に M5Stack の SPIFFS フラッシュへアップロードした Font ファイルや、変換テーブルファイルの定義です。
ここで注意していただきたいのは、/font/フォルダがあることと、半角フォントファイルを
shnm8x16r.bdf → shnm8x16.bdf
と変更していることです。

●17-18行:
ここで、自作ライブラリのクラス名を設定しています。

●20-22行:
文字列は 7 種類格納するようにします。
20行目で String 型の文字列を定義し、21行目で 16 x 16 pixel の東雲フォントバッファを定義しています。
文字数は半角 8 x 16 相当の最大文字数を 80 としています。
ここは、グローバル変数領域なので、文字数が多くなるとそれだけメモリを圧迫してしまいます。

●25行目:
文字の色設定を 65K色カラーで定義します。
RGBを混ぜて色を作ります。
赤色は 0~31、緑は 0~63、青は 0~31 です。
関数に直接色設定しても良いのですが、ここでは分かりやすくするため、グローバル変数で定義しています。

●26行目:
V_size は垂直方向の文字サイズで、H_size は水平方向の文字サイズです。
1~14 の間で設定できます。

●33行目:
東雲フォントファイルと、UTF8toSjis 変換テーブルファイルの、東雲フォントライブラリ初期化です。

●35行目:
TFT LCD ( 液晶ディスプレイ ) ILI9341 の初期化です。

●47-50行:
ここで、文字コード UTF-8 の String型文字列を東雲フォントバッファに格納しています。

●52-86行:
56行で、LCD ディスプレイにフォントを描画しています。
ILI9341 ディスプレイに描画できる文字数は以下の通りです。

横:半角 40 文字
縦:15文字

画面からはみ出た場合は、それ以降の文字は無視されるようにしました。

では、このスケッチをコンパイル書き込み実行させてみて下さい。
以下のように表示されればOKです。

ご覧のように、サイズ1倍の場合の半角文字数 40 文字を超えると画面からはみ出て無視されます。
縦横で別々のサイズにすると、表現の幅が広がりますね。
最小サイズの1倍はかなり小さい文字です。
でも、この液晶ディスプレイは、老眼の私でも判読できました。

では、次のページでは、文字スクロールするスケッチを紹介します。

コメント

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