🙌

How to: M5PaperS3で電子ペーパー名札を作ろう

2025/04/13に公開

みんな、こんにちは!メイカー憧れの電子ペーパー名札、1回は作ってみたいと思ったことあるよね?今回はそんなみんなの憧れの電子ペーパー名札を作る方法を紹介するよ。

この記事ではM5PaperS3を使って電子ペーパー名札を作る方法を紹介するんだけど、もし、そんなことはいいからお手軽に名札を作りたいんだ!ってみんなはボクが作ったM5PEasyTag!というソフトを使ってみてね。

ブラウザからの書き込みはこちら👇
https://app.nanana.uno/

ソースコードはこちら👇
https://github.com/nananauno/M5PEasyTag

完成イメージ
https://x.com/nananauno/status/1893615196943622638

やること&学べるポイント

やりたいことは、M5PaperS3の電子ペーパーディスプレイ (EPD) に好きな画像を表示させて名札を作ること。画像はmicroSDカードとLittleFSのそれぞれから読み込んで表示するよ。

今回の学べるポイントは、以下の3つだよ。

  • LittleFSの概要と使い方
  • SDカードの概要と使い方
  • EPDでの画像表示

対象読者

  • 電子ペーパーで憧れの名札を作ってみたい
  • M5PaperS3の使い方を知りたい
  • 画像を読み込んで表示する方法を知りたい

M5PaperS3って?

M5PaperS3はEPDとESP32-S3を搭載したM5Stackさんのマイコンモジュール。電子ペーパーだから他のM5Stack Coreシリーズと違ったコードが必要になりそう?とか思うかもしれないけど、M5Unifiedを使えばCoreシリーズと同じように画面描画もできるし、タッチも検出できるよ!電子ペーパー特有の設定がちょっとあるから、それは後で説明するね。

https://ssci.to/10112

電子ペーパーディスプレイ(EPD: Electronic Paper Display)は、普通の液晶やOLEDとは違った技術が使われていて、以下のような特徴があるよ:

  • 省電力
  • 描画は遅い
  • 日光の下でもくっきり

省電力
これはEPDの最大の特徴かもしれないね。EPDは画面を書き換える時にだけ電力を消費するから、一度書き換えてしまえば、そのあとは電力をほとんど消費しないのが最大の強みだね!画面を「更新(描画)」するときにだけ電力を使うので、いったん表示すれば 電池で何日〜何週間も持つ名札が作れるよ。

描画は遅い
EPDは表示の更新に数百ミリ秒〜数秒程度かかることがあるよ。これは仕組み上しょうがないことなんだけど、電子書籍や今回作ろうとしている名札のようにほとんど画面が変化しない用途ではあまり問題にはならないよね。逆に動画の再生やアニメーションには向いていないから、適材適所で使ってみてね。

日光の下でもくっきり
液晶ディスプレイはバックライトの光が無いと見えないけど、EPDはバックライトがなくても自然光でくっきり表示することができるよ。だから屋外の明るい場所でも紙のように読みやすいのがとっても魅力だね。

画像を読み込む色々な方法

EPDに名札の画像を表示しようと思ったら、まずは名札画像をどこかに保存しておく必要があるよね。ここではM5PaperS3に搭載されたフラッシュメモリーから読み込む方法と、microSDカードから読み込む方法について説明するよ。

LittleFS

LittleFSはフラッシュメモリー上に任意のデータを保持して読み書きするためのファイルシステムだよ。M5PaperS3には16MBのフラッシュメモリーが搭載されていて、このフラッシュメモリーの中身はPCと同じようにパーティションで区切ることができるよ。特に何も指定していないときは、以下のようなデフォルトの設定が使用されるようになっているよ。

https://github.com/espressif/arduino-esp32/blob/master/tools/partitions/default_16MB.csv

各パーティションの用途をざっくりと以下に書いておくよ。LittleFSで画像を保存する領域はspiffsというところになるよ。余談だけど、otaはWi-Fi経由でファームを書き換える仕組みで、2つのアプリ領域を使用して、使っていない領域にファームをダウンロードして、完全にダウンロードできたことが確認できたら起動する領域を切り替える、失敗したら既存の領域から起動することで、Wi-Fi経由で安全にファームを書き換えられるようになっているよ。

名前 用途
nvs 設定保存用の不揮発性領域(Wi-Fi設定など)。暗号化可能
ota OTA(無線アップデート)関連の情報を保存。現在のアプリ領域がどれ?とか
ota_0 1つ目のアプリ領域
ota_1 2つ目のアプリ領域
spiffs ユーザーがファイルを保存できる領域
coredump 異常終了時のダンプデータ保存(デバッグ用)

フラッシュメモリーのパーティションは、Arduinoだとボードの設定から、PlatformIOだとplatformio.iniのboard_build.partitionsでパーティションの区切り方を選択することができるよ。

パーティションは自由に変更できるけど、推奨の設定とかサイズの決まりがあるから、Espressifさんが用意しているパーティションから選択するか、もし自分で変更する場合はEspressifさんの公式ドキュメントをよく読んでみてね。

https://docs.espressif.com/projects/arduino-esp32/en/latest/tutorials/partition_table.html

LittleFS領域にデータをアップロードするには?
LittleFS領域にデータをアップロードするには、PlatformIOの場合、srcと同じレベルにdataというフォルダを作成して、そこにアップロードしたいデータを保存しておくよ。あとは、PlatformIOのメニューからUpload Filesystem Imageを選択するよ。たまに失敗することもあるから、失敗したら何回か試してみてね。

LittleFS領域から画像を読み込むには?
LittleFSの領域から画像を読み込んで表示する方法はとっても簡単!以下のコードはcard.pngというファイルをLittleFS領域から読み込んで画面に表示しているよ。

#include <LittleFS.h>
#include <M5Unified.h>
#include <epdiy.h>

void setup() {
  // Initialize M5Unified
  M5.begin();

  // Initialize LittleFS
  if (!LittleFS.begin()) {
    M5.Display.println("LittleFS init .. NG");
    esp_restart();
  }
  M5.Display.drawPngFile(LittleFS, "/card.png");
}

void loop() {
}

microSD

M5PaperS3にはmicroSDカードスロットが搭載されているから、microSDカードに画像を保存して、それを読み込んで表示することもできるよ。ここでは、microSDカードから画像を読み込んで画面に表示する方法を説明するよ。

microSDカードはESP32-S3とSPI(Serial Peripheral Interface)という信号方式で接続されているよ。SPIではMOSI, MISO, SCLK, CSの4つの信号を使用していて、それぞれのピン番号はM5Unifiedを使うことで簡単に取得することができるよ。

#include <SD.h>
#include <M5Unified.h>
#include <epdiy.h>

void setup() {
  // Initialize M5Unified
  M5.begin();

  // Get SPI pins
  auto mosi = M5.getPin(m5::pin_name_t::sd_spi_mosi);
  auto miso = M5.getPin(m5::pin_name_t::sd_spi_miso);
  auto sclk = M5.getPin(m5::pin_name_t::sd_spi_sclk);
  auto cs = M5.getPin(m5::pin_name_t::sd_spi_cs);

  // Initialize SD card
  SPI.begin(sclk, miso, mosi);
  if (!SD.begin(cs, SPI, 4000000)) {
    M5.Display.println("SD card init .. NG");
    esp_restart();
  }

  M5.Display.drawPngFile(SD, "/card.png");
}

LittleFSと同様にdrawPngFileを使って、1つ目の引数にSDを指定するだけでmicroSDカードから画像を読み込むことができるよ。とっても簡単だね!

JEPG画像の場合は?
M5.Display.drawJpgFileを使ってね。

EPDで画像表示

LittleFSやmicroSDカードから画像を読み込んで画面に表示する方法を説明したけど、改めておさらいすると、M5.Display.drawPngFile(ストリーム名, パス)という感じでとっても簡単に読み込めるというお話だったよね。M5Stack Core2とかも同じなんだけど、M5PaperS3で使用しているEPDでは。EPD特有の設定もあるから、ここではEPDでしか使わない設定について説明しておくね。

電子ペーパー特有の設定 (EPDmode)

EPDは液晶ディスプレイと比較すると、描画の速度が遅いという特徴があったよね。M5Unifiedで描画する場合、EPDでも描画する内容に応じて「品質は落としてもいいから速く描画したい」とか「遅くてもいいから綺麗に描画したい」といった調整ができるようになっているよ。

M5Unifiedでは、M5.Display.setEpdMode() で描画モードを切り替えることができるよ。それぞれのモードには用途に応じた特性があるから、うまく使い分けてみてね。

M5Unifiedで選択できるEPDモードと用途を紹介するね。モードの切り替えは簡単で、モードを切り替えたいところで以下のようにsetEpdModeを呼び出すだけだよ。

M5.Display.setEpdMode(epd_mode_t::epd_fast);

epd_mode_t の種類と比較

モード名 特徴
epd_quality 最も品質が良い。最も遅い描画速度。
epd_text
epd_fast
epd_fastest 最も速い描画速度。品質は最も低い。

作ってみよう

ここまでで画像をフラッシュメモリーやmicroSDカードに保存して読み込む方法とEPDで画像を表示する方法は理解してもらえたかな?これらができたら、もう完成したようなものだよね?あとは、コードを組み合わせて完成品として仕上げてみよう。

ここでは、以下のように作ってみるよ。

  • microSDカードにcard.pngがあれば、それを読み込んで画面に表示
  • 無ければLittleFSのcard.pngを読み込んで画面に表示
  • どちらも無ければ"No image"と画面に表示

環境

今回のビルド環境は以下の通りだよ。M5paperS3で必要なEPDiyっていうライブラリに問題があって、環境設定は要注意だから、ビルドできない時はここをよく読んでみてね。

  • M5PaperS3
  • PlatformIO
  • M5Unified 0.22以降
  • epdiy @ 2.0.0+sha.cbdaaa7

Platformio.ini

https://github.com/nananauno/M5PEasyTag/blob/main/platformio.ini

上記のPlatformio.iniでepdiyの指定は以下のように置き換えてね。

epdiy=https://github.com/vroland/epdiy.git#cbdaaa7

サンプルコード

ここまで説明した内容で、自分でコードを書いてもいいし、一応サンプルのコードも以下に記載しておくよ。

#include <LittleFS.h>
#include <SD.h>
#include <M5Unified.h>
#include <epdiy.h>

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  
  // Get SPI pins
  auto mosi = M5.getPin(m5::pin_name_t::sd_spi_mosi);
  auto miso = M5.getPin(m5::pin_name_t::sd_spi_miso);
  auto sclk = M5.getPin(m5::pin_name_t::sd_spi_sclk);
  auto cs = M5.getPin(m5::pin_name_t::sd_spi_cs);

  // Initialize SD card
  SPI.begin(sclk, miso, mosi);
  if (!SD.begin(cs, SPI, 4000000)) {
    //SD card init .. NG
  }

  // Initialize LittleFS
  if (!LittleFS.begin()) {
    //LittleFS init .. NG
  }

  M5.Display.setEpdMode(epd_mode_t::epd_quality);
  bool success = M5.Display.drawPngFile(SD, "/card.png");
  if (!success) {
    success = M5.Display.drawPngFile(LittleFS, "/card.png");
  }
  if (!success) {
    M5.Display.println("No image");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

動かしてみよう

M5PaperS3のEPDの解像度は横が540ピクセルで縦が960ピクセルだから、このサイズでcard.pngを作成して、microSDカードのルートとLittleFS用のdataフォルダに入れておいてね。作成する画像はグレースケールでもいいし、カラーでも大丈夫だよ。カラーで作成した場合は描画時に自動的にグレースケールに変換されるよ。

画像が作成できたら、サンプルコードをビルドしてM5PaperS3に書き込んでみてね。M5PaperS3に書き込むときはリセットボタンを赤LEDが点滅するまで長押しするとブートローダーモードで起動するから、その状態でファームウェアを書き込んでね。

最初はLittleFS領域に何も書き込まず、microSDカードも挿入しない状態でM5PaperS3を起動すると"No image"と左上に超小さく表示されるはずだよ。その後に、microSDカードを挿したり、LittleFS領域にファイルをアップしたりしてどうなるのか試してみてね。

まとめ

M5PaperS3を使用して自分だけの電子ペーパー名札を作ることができたかな?今回は、M5PaperS3を使って憧れの電子ペーパー名札を作る方法を紹介したよ!主にLittleFSとmicroSDカードから画像を読み込んで表示する方法と、EPD特有の設定について説明したよ。電子ペーパーだからといって、他のM5Stackシリーズと全然違う使い方というわけではなかったよね。

電子ペーパー名札は画像を差し替えるだけで名札をどんどん更新できるから、気分に合わせて画像を変更することも簡単だよね。イベントや展示会などでもとっても目立つし、タッチで表示を変えたりすればもっと面白そうだよね。

最後にもう一度、ボクが作ったM5Paper/S3でお手軽に電子ペーパー名札を作れるソフトを紹介しておくよ。これはブラウザやM5Burnerで簡単に書き込むことができるから開発環境がなくてもお手元のM5Paper/S3を超簡単に電子ペーパー名札できるからぜひ使ってみてね。

ブラウザからの書き込みはこちら👇
https://app.nanana.uno/

みんなも、自分だけの電子ペーパー名札を作ってみてね!じゃあ、またね!

参考

https://qiita.com/mitsuharu_e/items/63e9f278bd48933f372a

Discussion