ESP32 で 日本語漢字フォント をカラー OLED に表示させ、4行同時スクロール ( SSD1331 使用)

ESP32 ( ESP-WROOM-32 )

自作ライブラリのダウンロード

Arduino core for ESP32 が大幅アップデートされました。
それに伴い、自作ライブラリもアップデートしましたので、最新版をダウンロードしてください。

Arduino core for the ESP32 用に私が自作したライブラリは GitHub の以下のページにあります。
ZIP ファイルをダウンロードしてインストールしてください。
ZIPファイルからそのまま Arduino IDE にインストールする方法は以下のページを参照してください。

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

ESP32_SD_UTF8toSJIS Beta ver 1.21

GitHub の以下のページにあります。

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

ESP8266 のライブラリを基に、ESP32 用に改良しました。
これは、UTF-8 文字コードから Shift_JIS へ変換するテーブルファイルが必要です。
それは以下のものです。

Utf8Sjis.tbl

これは後で述べるリンクからダウンロードできます。

Arduino IDE のスケッチ(ソースコード)に入力した日本語漢字は UTF-8 コードの文字列になるので、それを Shift_JIS  文字コードに変換するライブラリです。
String クラスなどの文字列は全て UTF-8 になるので、2バイト~3 バイトで構成された文字コードです。
Shift_JIS コードに変換することで、全て2バイト以下になります。
半角のASCII コードはそのまま出力します。

ESP32_SD_ShinonomeFNT Beta ver 1.21

GitHub の以下のページにあります。

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

これもまた、ESP8266 のライブラリを基に改変しました。
UTF-8コードのString 文字列から直接東雲フォントをSDカードから読み込めるようにしました。
よって、上記の ESP32_SD_UTF8toSJIS ライブラリをインクルードしています。

以前の ESP8266 のライブラリよりもフォント読み込みは格段に簡単になったと思います。

ESP32_SSD1331 Beta ver1.3

前々回の記事でアップしたライブラリですが、今回 Beta ver 1.3 にバージョンアップしました
GitHub の以下のページにあります。

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

文字フォントを右から左へスクロールする関数をできるだけ簡素化してみました。

必要なフォントおよびテーブルファイル

GitHub の以下のページにあります。

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

ZIPファイルをダウンロードして、解凍してください。
font フォルダの中の以下の3つのファイルが必要です。

これらを micro SDHC カードのルートに /font というフォルダを作成し、そこにコピーしておいてください。

Utf8Sjis.tbl

UTF-8 から Shift_JIS へ変換するためのテーブルファイルです。
私の自作のバイナリファイルです。
ライセンスは MIT です。
著作権表記してあれば、自由に使うことができます。

shnmk16.bdf

16×16 東雲フォント(全角)

shnm8x16.bdf

8×16 東雲フォント(半角)
上記でも述べましたが、ファイル名の ”r” を削除して、8文字に収めたものです。

文字列表示サンプルスケッチの入力

では、まず、ただ単に文字列を OLED ディスプレイに表示するだけのスケッチを紹介します。
SSD1331 は 96 x 64 pixel なので、全角16×16ドットフォントは横に6文字しか表示できません。
半角 8×16 ならば12文字表示できます。

ブラウザからスケッチをコピーしたら、必ず一旦保存してください。そうしないと正しく表示されませんので要注意!!

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

#include "ESP32_SD_ShinonomeFNT.h"
#include "ESP32_SD_UTF8toSJIS.h"
#include "ESP32_SSD1331.h"

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"; //半角フォントファイル名を定義

const uint8_t CS_SD = 5; //SD card CS ( Chip Select )

const uint8_t SCLK_OLED =  14; //SCLK
const uint8_t MOSI_OLED =  13; //MOSI (Master Output Slave Input)
const uint8_t MISO_OLED =  12; //これは実際は使っていない。MISO (Master Input Slave Output)
const uint8_t CS_OLED = 15;
const uint8_t DC_OLED =  16; //OLED DC(Data/Command)
const uint8_t RST_OLED =  4; //OLED Reset

ESP32_SSD1331 ssd1331(SCLK_OLED, MISO_OLED, MOSI_OLED, CS_OLED, DC_OLED, RST_OLED);

ESP32_SD_ShinonomeFNT SFR(CS_SD, 24000000);

void setup() {
  Serial.begin(115200);
  ssd1331.SSD1331_Init(); //OLED SSD1331 初期化

  //※この関数を使う場合はStrDirect_ShinoFNT_readALL関数を使う場合限定。
  //3つのファイルを同時に開くため、後でクローズすることが必要。
  SFR.SD_Shinonome_Init3F(UTF8SJIS_file, Shino_Half_Font_file, Shino_Zen_Font_file);

  uint8_t font_buf[12][16];
  uint16_t sj_length;
  String str = "日本語漢字!";
  
  sj_length = SFR.StrDirect_ShinoFNT_readALL(str, font_buf); //String 文字列から一気にフォント変換
  ssd1331.SSD1331_8x16_Font_DisplayOut(sj_length, 0, 0, 7, 7, 3, font_buf); //OLED SSD1331 へ出力
  
  str = "ESP-WROOM-32";
  sj_length = SFR.StrDirect_ShinoFNT_readALL(str, font_buf); //String 文字列から一気にフォント変換
  ssd1331.SSD1331_8x16_Font_DisplayOut(sj_length, 0, 16, 7, 0, 0, font_buf); //OLED SSD1331 へ出力

  str = "半角もイケる";
  sj_length = SFR.StrDirect_ShinoFNT_readALL(str, font_buf); //String 文字列から一気にフォント変換
  ssd1331.SSD1331_8x16_Font_DisplayOut(sj_length, 0, 32, 0, 7, 0, font_buf); //OLED SSD1331 へ出力

  str = "アカサタナハマヤラワン";
  sj_length = SFR.StrDirect_ShinoFNT_readALL(str, font_buf); //String 文字列から一気にフォント変換
  ssd1331.SSD1331_8x16_Font_DisplayOut(sj_length, 0, 48, 0, 0, 3, font_buf); //OLED SSD1331 へ出力

  SFR.SD_Shinonome_Close3F(); //StrDirect_ShinoFNT_readALL関数を使う場合、必ず閉じておく
}

void loop() {

}

ただ単にディスプレイに東雲フォントを表示するだけならば、ESP8266 でやっていた時よりも格段に簡単にしました。

【解説】

●1-3行目:
自作ライブラリのインクルードです。
ESP32_SD_ShinonomeFNT.h 内で ESP32_SDUTF8toSJIS.h をインクルードしていますが、このライブラリが必要ということで、あえてここでもインクルードしています。
2重インクルードしないように設定していますので、ご安心を。

●5-7行目:
テーブルファイルやフォントファイルをここで定義します。

●9-16行目:
ESP32-DevKitC の GPIO ピン設定です。
OLED SSD1331 は HSPI ピンアサインです。

●18行目:
自作ライブラリ ESP32_SSD1331 のクラス宣言です。
このライブラリの使い方は以前の記事を参照してください。

●20行目:
自作の ESP32 用 東雲フォントライブラリのクラス宣言です。
micro SDHC カードのCS ( Chip Select )ピンと SPI クロック周波数を設定できます。
ここでは、SPIモードの理論上最大値と思われる24MHz としています。

●24行:
SSD1331 の初期化です。
初期化の内容は過去の記事を参照してください。

●28行目:
この関数は、ESP32_SD_ShinonomeFNTライブラリの初期化なのですが、3つのファイルを同時に開いているので注意です。
Arduino core for the ESP32 では、2017/5/31 時点で同時に4つまでしかファイルを開けません。
(以下記事参照)
ESP32 ( ESP-WROOM-32 ) で micro SDHC メモリカードを使う場合の注意点

この3つ同時に開く必要があるライブラリ関数は、
StrDirect_ShinoFNT_readALL
だけです。
この関数を使い終わった後には、49行目にあるように3つのファイルをクローズしておかないと、新しいファイルを開く時に開けないことがありますので要注意です。

●34行目:
この関数が今回初登場した関数で、String 文字列をいちいち Shift_JIS コード変換しなくても、そのまま東雲フォントを読み込んで、font_buf に格納できるようになりました。
Shift_JIS コードのバイト数を返します。
そのバイト数が全て半角に換算した文字数です。

●35行目:
8×16ドットフォントを OLED SSD1331 ディスプレイに表示する関数です。

SSD1331_8x16_Font_DisplayOut(半角換算文字数, 始点X0, 始点Y0, 赤, 緑, 青, フォントbuf);

色は256色カラーで、
赤:0-7
緑:0-7
青:0-3
で指定して混ぜます。
半角換算文字数は12を超えないようにしてください。

●49行目:
開いた3つのファイルをまとめてクローズします。
これを忘れないようにしてください。

以上、これをコンパイル実行してみてください。
下図の様に表示されればOKです。

ブラウザからスケッチをコピーしたら、必ず一旦保存してください。そうしないと正しく表示されませんので要注意!!

どうでしょうか。
ESP8266 のときよりも格段に表示しやすくなったと思います。

コメント

  1. juchang より:

    mgo-tec 様

    「ESP32 で 日本語漢字フォント をカラー OLED に表示させ、4行同時スクロール」に挑戦していますが、「文字列表示サンプルスケッチ」のところでトラブっています。
    入力後、コンパイルをかけるとしばらくは動作するのですが、
    exit status-1
    ボード ESP32 Dev Module に対するコンパイル時にエラーが発生しました。
    とのメッセージとなってしまいます。
    「( ESP8266 )用 Arduino IDF ライブラリを作ってみました」、「関数1行で UTF-8 文字列を フリーの日本語漢字( 東雲 ) フォントに変換できるようにしてみました」ほか、色々調べてみましたが解決策が見出せません。
    SPIFFS メモリを大きくして、micro SDHC カードを使わない方法もあるとのことで、それにも挑戦してみたのですが、同様に、コンパイル時エラーとなってしまいます。
    何か解決のアドバイスをいただけると幸いです。

    • mgo-tec mgo-tec より:

      juchangさん

      毎度お試しいただき、ありがとうございます。

      まず、お伺いしたいのは、exit status 1 の前に何かエラーメッセージが出ていませんか?
      出ていなければ、Arduino IDEのファイルメニューの環境設定のコンパイラの警告表示を「全て」にして、コンパイルし直してみてください。

      エラーメッセージを解読しないと、私も全く分かりません。

      因みに、ネットでエラーメッセージを検索すると、解決策がでている場合が多いですよ。

  2. juchang より:

    mgo-tec 様

    大変お手数をお掛け致します。

    警告表示を「全て」にしてエラーメッセージを確認しました。
    「SPI.h」、「SD.h」、「FS.h」に対し複数のライブラリがあることが原因の一つと判明したので、ファイルを削除し改めてコンパイルし直したところ、その部分のエラーメッセージは消えました。
    残っているエラーメッセージは下記のとおりです。
    Archiving built core (caching) in: C:\Users\Sadao\AppData\Local\Temp\arduino_cache_202978\core\core_espressif_esp32_esp32_FlashMode_qio,FlashFreq_80,FlashSize_4M,UploadSpeed_921600,DebugLevel_none_d7731e9bf27ea9782339ebd79c5efa1f.a
    Traceback (most recent call last):

    File “gen_esp32part.py”, line 386, in

    File “gen_esp32part.py”, line 355, in main

    UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xef in position 0: ordinal not in range(128)

    Failed to execute script gen_esp32part

    解読を試みたのですが難しくてわかりません。
    ご助言の程お願いいたします。

    • mgo-tec mgo-tec より:

      juchangさん

      spi.h SD.h FS.h は大切なファイルです。
      削除してしまうと、ますます動かなくなってしまいます。
      それを削除する前のエラーメッセージを解読しなければなりません。
      それを教えて下さい。

  3. juchang より:

    mgo-tec 様

    削除前のエラーメッセージは、
    「SPI.h」に対して複数のライブラリが見つかりました
    使用済:C:\Users\Sadao\Documents\Arduino\libraries\SPI
    未使用:C:\Users\Sadao\Documents\Arduino\hardware\espressif\esp32\libraries\SPI
    となっていました。
    「SD.h」では、使用済と未使用が逆となっていたので、どちらも有効と思い、
    C:\Users\Sadao\Documents\Arduino\hardware\espressif\esp32\libraries\””
    を残し、片方を削除しました。
    その後、コンパイルし直したところこの部分のエラーメッセージが出なくなりました。
    取り急ぎ現状までの報告です。
    これから、mgo-tec さんのアドバイス通りネットで検索してみます。

    • mgo-tec mgo-tec より:

      複数のライブラリが見つかりましたというメッセージは実は直接関係ありません。
      他のエラーが原因です。
      例えば、必要なライブラリがインストールされていなかったとか、Timeライブラリが無いとかです。

      これより前のコンパイラメッセージは何かありませんでしたか?

  4. juchang より:

    mgo-tec 様

    エラーメッセージが解消しました!

    ネットで検索をしたところ、「str 型と unicode 型を混ぜるな」という記事があり、昨日、「SPIFFS メモリサイズを大きくする作業」をしたことを思い出しました。
    とりあえずこの作業は不要と思い、Arduino core for the ESP32 を再インストールし直したところ、エラーメッセージが消えました。
    その後、コンパイル実行をしたら画面に表示はされたのですが、画面左半分だけの表示となります。
    これからこの問題に取り組んでいきたいと思います。
    以上、これまでの経過を報告いたします。

    • mgo-tec mgo-tec より:

      そうなんですね。
      とりあえず、エラーが消えて良かったですね。
      基本的には、SPIFFSサイズを大きくしても、正しく手順を踏んでいれば問題なく動きます。
      ただ、esp8266の方はメモリサイズが2GBのものが流通していたりして、大きくすると問題が生じてしまいます。
      ESP32ならば、今のところ問題なく動いています。

      近々、ESP32用のトラブルシューティング記事を書こうと思っていますので、今回の件は私なりにも再検証したいとおもいます。
      いろいろ情報ありがとうございました。

  5. juchang より:

    mgo-tec 様

    本ページの画面表示に成功しました!

    画面半分表示の状態で、シリアルモニタを見たところ、
    UTF8toSjis file has not been up load to the flash in SD file system
    Shinonome file has not been up load to the flash in SD file system
    となっていました。
    SD カードスロット・ピッチ変換基板へのピンヘッダのはんだ付けがよくなっかたようで、はんだ付けをし直したところきれいに表示されました。
    休日にもかかわらず拙問にお付き合いをいただきありがとうございました。
    今後ともご指導の程よろしくお願い致します。

    • mgo-tec mgo-tec より:

      juchangさん

      それは良かった!!
      そういうことだったんですね。
      SDカードからファイルと読み取れない場合も、コンパイラ警告メッセージで、SPI.h や FS.h が重複しているという文が出ますね。
      私も最初は意味わかりませんでしたが、その前のメッセージが重要で、それを読み解くと大体解決できます。
      ですからライブラリ重複メッセージは、その前の段階のエラーが影響してそういうメッセージが出るという事です。
      ビギナーの方々には分かりづらいと思います。

      でも、良かったですね。
      私もホッとしました。

      私も何かと忙しく、すぐにお答えできない場合も多々ありますが、当ブログ記事による不具合にはできるだけ対応していきたいとは思っております。
      こちらこそ、今後ともよろしくお願いいたします。

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