見出し画像

電子ペーパーの卓上カレンダーがほしい(5)

なぜ(5)かというと、この動機で記事を書くのが5回目だからです。

これまでの試みで、「7.5インチの電子ペーパーにカレンダーのスクショを送信」「4.7インチのM5PaperにGoogleカレンダーの内容を表示」の二つは達成できていました。そこで今回は…「7.5インチの電子ペーパーにGoogleカレンダーの内容を表示」したい。そのためにはまず部品を集めるところからです。

電子ペーパー

まずは電子ペーパー。M5Stackシリーズの扱いに慣れてきたので、ESP32で制御できそうな電子ペーパー、かつそれなりのサイズがあるものを探しました。使ったのはこれ。

こちらの製品は赤黒白の三色を表示できるので、休日を赤で表示することができそうです。Raspberry PiやArduinoから制御するサンプルコードもWikiから参照できるので、それをベースに改造すれば行けるはず。

https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(B)_Manual#Precautions

ただし注意点がいくつかあって、画面の更新に20秒くらいかかること、更新間隔は180秒以上おくこと、画面を更新したら速やかにSleepモードにした方がよいこと、24時間に1回は画面を更新した方がよいことなどが書かれています。つまり電子ペーパーとはいってもKindleのようにインターフェースとしての使用が可能なものではありませんが、一日一回更新するカレンダー用途にはぴったりです。

ESP32のボード

M5Paperで既にGoogleカレンダーの内容を表示できているので、同じESP32のボードがあればほぼそのままコードを使えるでしょう。ただM5PaperはPSRAMを8MB装備しており、ESP32の中ではかなり潤沢にメモリを使用できます。同じような感覚でプログラムするためにはPSRAMが欲しい。使ったのはこれ。

これは付属のLEDとかカメラとかを自由に繋いで電子工作できるキットで、本当に必要なのはESP32-S3-WROOMの載ってる部分だけです。ただ今回は電子ペーパーの制御用配線を色々組み替えて試す必要があるかもな…と思ってキットごと買ってみました。

最終的にはこの部分だけ使いました。カメラとかも要らないので、もっと安い開発用ボードがあるはずです。

配線とSPI通信

さてじゃあこの二つをどうやって接続するの?ってことなんですが…マニュアルには色々なボードの配線例が載っています。ESP32-S3-WROOMそのものはリストに無いものの、色々比べてみると何が必要なのか見えてきます。

https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(B)_Manual

e-Paper側のピンの意味と今回ESP32-S3のどのピンを使ったか

まず電源は3.3Vですが、レギュレータがついているので5Vでも行けるらしいです。GNDはグラウンド、接地ですね。

SPI通信用に3つ、CLK(Serial clock, SCK)、CS(Chip Select, Slave Select, SSとも)、DIN(MOSI, Master Out Slave In)のラインがあります。これらはESP32-S3-WROOMとArduinoフレームワークの既定値では、SPI.begin()するとGPIOの10〜13番を使用するので、それに合わせて配線しています。

ここの記述を参考にしました。Technical Reference ManualにもESP32-S3がどのピンを何に使っているか書いてあります。

他の制御用ラインは多分どのGPIOでもいいんですが、上記のマニュアルを見てSDカード用とか他の用途があるピンを除いて割り当てています。ただし、元々のキットではカメラ用に使っているピンが多数あり、今回は使用しないカメラをむしり取ってカメラ用のGPIOを流用しています。

PlatformIO用のBoard定義を作る

どのピンを使用するか決まったら、コードで設定していきます…が、まずESP32-S3-WROOMの開発にPlatformIOを使用できるようにしたいです。Arduino IDEはコードが見づらいので…

以前同じくESP32-S3を使用するSenseCAP Indicatorの開発用にPlatformIOの設定をしたことがあったので、上記記事を参考にボード定義ファイルを作りました。

デモ用コードを改変する

PlatformIOでプロジェクトが作れるようになったら、上記のマニュアルページからArduino用デモコードをダウンロードし、今回のピン設定用に改変して動かしてみます。「Arduino」フォルダの中の「epd7in5b_V2」フォルダがそれです。

epdif.hのピン設定を変更する

epdif.hに使用するGPIOの番号を設定します。SPI用の番号を設定していないのは、このデモコードがデフォルトのSPI設定を使用するからのようです。
もし変更したい場合はepdif.cppの「SPI.begin();」を「SPI.begin(12, 13, 11, 10);」のようにすればいいはずです。

配線をちゃんと接続し、デモコードが動くとこんな感じになります

LovyanGFXで表示用データを作る

上記のデモでは、1bitモノクロの画像データを下記のようなコードで電子ペーパーに送信して表示しています。

epd.Displaypart(IMAGE_DATA,250, 100,240,103, 0);
epd.Displaypart(IMAGE_DATA,250, 300,240,103, 1);

IMAGE_DATAにはデモに含まれる1bitモノクロの画像データ、あとは表示位置とサイズ、最後に黒か赤を0か1で設定しています。なぜこういう形式になるかというとマニュアルの下記に書いてあるのですが、

https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(B)_Manual#Programming_Principle

まずこの電子ペーパーでは、黒と赤は別のデータになっています。画像ファイルに例えると、黒用と赤用の二枚を用意してレイヤーで重ねる感じです。

さらにそれぞれのデータは1bitモノクロです。つまり、1バイトに8ピクセル分のデータが入っています。

上記のようなカレンダーの画像データを作ってDisplaypart()で転送すればカレンダーの表示ができるはずです。そこで、LovyanGFXの出番です。

M5StackやSenseCAP Indicatorでお世話になっているグラフィックライブラリLovyanGFXですが、Spriteというオフスクリーンバッファに描画することができます。そしてSpriteの色深度は1bitにもできるため、1ピクセル1bitで作成したSpriteのバッファ内容をDisplaypart()に渡してやればよさそうです。

LovyanGFXを使用することにより、使い慣れた図形の描画関数やLovyanGFX内蔵の日本語フォントなどを利用することができます。

// こうやってグローバル変数を作っておいたりして
LGFX_Sprite blackSprite;
LGFX_Sprite redSprite;

// 1bitモノクロで800x480のSpriteを2つ作る
blackSprite.setColorDepth(1);
blackSprite.createSprite(800, 480);

redSprite.setColorDepth(1);
redSprite.createSprite(800, 480);

// Spriteに描画が終わったら電子ペーパーに転送
epd.Displaypart((unsigned char *)(blackSprite.getBuffer()), 0, 0, 800, 480, 0);
epd.Displaypart((unsigned char *)(redSprite.getBuffer()), 0, 0, 800, 480, 1);
epd.Sleep();

カレンダー表示コードを書く

ここまで出来れば、あとは以前M5Paper用に書いたコードの流用です。

ただし、休日を赤色で表示するために少し変えています。「settings.txt」でWi-FiやGoogleカレンダーのアドレス、pemファイルの名前などを指定するのは同じですが、祝日カレンダー用のアドレスを別に指定するようになっています。

SSID:アクセスポイント名
PASS:パスワード
pemFileName:/google-com.pem
iCalendarURL:https://calendar.google.com/calendar/ical/ほにゃらら
holidayURL:https://calendar.google.com/calendar/ical/ほにゃらら
timezone:9.0

実際に使用したコードはこちら。

できたもの

ケース1:CanDoで見つけたプラスチックの2Lフォトフレーム
ケース1の裏側。養生テープで留められている

100円ショップで2Lサイズ用のフォトフレームを買ってきて入れてみました。ESP32-S3-WROOMの工作用キットについてきたボードや、電子ペーパーについてきた延長コードなど不要なものを外すとフォトフレーム裏面に貼り付けられるサイズです。電源はType-Cから供給し、SwitchBotのスマートプラグを使って一日一回5分だけ電源が入るようにしています。電源が入るとGoogleカレンダーを読みに行って、画面を更新し、5分後には元から電源が落ちるというわけです。

ケース2:CanDoで見つけた2L用木製フォトフレーム。
木製は厚みがあるので影が落ちて見づらくなるため、上部に適当な紙を入れている
ケース2の裏側。CanDoで買ってきた2穴書類留め用プラスチックファスナーを、写真押さえ用のプラスチック板に接着して基板を留められるようにした

未来へ…

ケース1でM5Paperとのサイズ比較

こうして、ほぼ理想に近い電子ペーパーの卓上カレンダーが錬成されました。欲を言えばGoogleカレンダーはちゃんとAPIを使いたいし、電子ペーパーがもっと大きければ壁掛けにだって出来るでしょう。ESP32-S3-WROOMを使いましたが、別に旧機種のESP-WROOM32でだって出来るはずです。しかしともかくはかなりいいものができたので、しばらくこれを使うことにします。

ケース2の写真をよく見ると5/6に海の日とか書いてあります。バグですね


この記事が気に入ったらサポートをしてみませんか?