M5Paperでデジタルモノクロフォトフレームを作る(前編)

  • 2021-11-09
  • 2021-11-09
  • IoT
  • 46回
  • 0件
IoT

はじめに

こんにちは。CTO室のringoです。電子ペーパーが搭載されたガジェットであるM5Paperを使ってフォトフレームを作成したことについて書きます。
簡単に実装できると思っていたのですが、Google Drive APIを使用するところで手間取ってしまい記事が長くなったので前後編に分けました。今回はwebサーバーから画像をダウンロードしてM5Paperで表示するところまでを説明します。
部屋に設置して、勝手に変化したり動いたりするインテリアが好きなので、スマホからお気に入りの画像を送信して、時間が立つと自動的に次の画像へと更新されるのが理想です。
M5Paperはモノクロ16段階調の表現が可能なので、どのように描画されるかも気になります。

M5Paper

ESP32が搭載された電子ペーパーです。スイッチサイエンスさんで買うことができます。
M5Paper V1.1
タッチセンサで操作可能で、デフォルトで書き込まれているプログラムでもある程度遊ぶことができます。


左はiPhone8、右がM5Paperです。
サイズ感的にはiPhone8より少し小さくて軽いです。
TwitterでM5paperで検索をかけるといろいろな人の工作を見ることができて参考になります。
自分でカスタマイズ可能なkindleみたいで色々できそうです。
書き換えたら電源を落としても表示が残り続けるので、消費電力が少なくてすむという電子ペーパーの利点と、WiFiモジュール搭載のESP32マイコンの特徴を合わせると定期的にデータを送受信して画面を更新するアプリケーションにM5Paperは向いてそうです。

フォトペーパー概要

「実生活で使える」というのを目標にしたいと思います。理由としては、買ったはいいけどサンプルプログラムを書き込んで以降、埃かぶって部屋の隅に放置されるのを避けたいからです。そうならないために何が必要か考えたときに使いやすさが大事だと考えました。

M5Paperに画像を転送する方法としては

  • SDカードに保存した画像を表示する
  • WiFi経由でサーバーから画像取得して表示する
  • スマホから直接M5Paperに送信する。WiFi or Bluetooth?
  • ESP32のFlashに直接書き込む

他にも方法はあると思いますが、ざっくり分けるとこんな感じだと思います。
それぞれシチュエーションや開発を考慮してもう少し考えてみます。

SDカードに保存した画像を表示する

SDカードに保存して表示するのはシンプルだけど、画像を更新するたびにSDカードに画像を入れるのは面倒な気がします。

WiFi経由でサーバーから画像取得して表示する

WiFi経由だとサーバー側をどうするかについて考えなければなりません。
自分でサーバーを用意するのもいいですが、GoogleDriveやDropboxなどと連携すればスマホから直接アップロードした画像をM5Paperが自動でダウンロードして表示できそうな気がします。
シチュエーションを考えると、外出先で画像をアップロードしておいて帰宅したら反映されてるとか、遠方に住んでる家族にフォトフレーム経由のコミュニケーションをするとか活用方法が思い浮かびます。

スマホから直接M5Paperに送信する

家庭内で使用する分にはスマホから直接M5Paperにアップロードするのが楽かもしれません。
方法としては、M5Paper自身をサーバーにしてスマホからアップロードすることもできなくはないと思います。ですが、サーバーとして常に待機させておくのは低消費電力なフォトフレームとは逆になってしまいます。

ESP32のFlashに直接書き込む

Flashに直接書き込む方法は、画像を更新するたびにPCと接続して書き込まなければなりません。スマホから直接書き込むのも不可能ではないと思うのですが、実装するのが大変そうです。


悩んだ結果、今回はGoogleDriveにスマホから画像をアップロードし、定期的、または手動でDriveの更新を確認する方法にしました。

理由としては

  • 普段からGoogleDriveを使用している。
  • 自分でサーバーを用意する必要がない
  • GoogleDriveのAPIをESP32から使ってみたかった

などの理由です。

プロトタイプを作る

いきなりGoogleDriveと接続して画像を表示しても良かったのですが、M5PaperのサンプルにURLから画像を取得して表示するプログラムがありました。
DISPLAY_URL_JPG.ino
ソースコードを見るとHttpClientとjpgDecodeがラップされています。これでも良さそうですが最終的にはAPIを叩いて画像データをダウンロードしたいのでそのまま使うことはできません。
ただ、プロトタイプを作成し、フォトペーパーの雰囲気を掴むには十分です。
というわけでプロトタイプとして画像をスライドショーにして表示するプログラムを作成します。
開発環境はVSCodeとPlatformIOを使用しています。
参考:M5PaperのFactoryTest書込み手順メモ

#include <string.h>
#include <M5EPD.h>
#include <WiFi.h>

M5EPD_Canvas canvas(&M5.EPD);

String host = "http://192.168.xxx.xxx/images/:8080/";
String url[9] = {"img01.jpg", "img02.jpg", "img03.jpg", "img04.jpg", "img05.jpg", "img06.jpg", "img07.jpg", "img08.jpg", "img09.jpg"};

void setup()
{
    M5.begin();
    M5.EPD.SetRotation(90);
    M5.EPD.Clear(true);
    WiFi.begin("Your SSID", "Your Password");

    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    int i = 0;
    while (1)
    {
        canvas.createCanvas(540, 960);
        canvas.setTextSize(3);
        canvas.drawJpgUrl(host + url[i]);
        canvas.pushCanvas(0, 0, UPDATE_MODE_GC16);
        i++;
        if (i == 9)
            i = 0;
        delay(5000);
    }
}

void loop()
{
}

画像のパスを配列として格納しておき、ループの中でdrawJpgUrlを呼び出しているシンプルなプログラムです。
プログラムをloopの中に書くとエラーでM5Paperが再起動してしまうのでsetupの中でwhile文作って動かしています。
画像は適当にwebサーバーを用意し、リサイズした画像を配置しておきます。

動画用に切り替わる時間を短くしてますがいい感じです。思ったよりキレイに表示されて満足です。
モノクロの画像を用意する必要があると思っていたのですが、フルカラーの画像をいい感じに変換して表示してくれるみたいです。
少し白色が暗いですが解像度はフォトフレームとして使用するには申し分なさそうです。16階調なのでグラデーションがある画像よりコントラストが強めのパキっとした画像のほうが映えるのかなとも思います。元写真部として今後M5Paperで映える加工など試してみたいところです。

おわりに

プロトタイプのおかげでなんとなく完成形は見えてきました。
今の方法だとスマホでリサイズした画像をPCに転送して、さらにwebサーバーに配置しています。また、プログラムに画像のURIをハードコートしているので毎回ビルドする必要があります。
このままでは画像の更新が手間で放置される可能性大です。
そこで次回の記事ではGoogle Driveから画像を取得することについて書きたいと思います。
お読みいただきありがとうございました。