概要
前回は公式ライブラリのスケッチ例を確認してみました。今回は最近サポートされたばかりの電子ペーパーを搭載しているM5Stack CoreInkとM5Paperの使い方を説明したいと思います。
LovyanGFXの限界
LovyanGFXはグラフィックライブラリです。そのため、グラフィック以外の機能はありません。たとえば電源管理なども画面で利用する範囲のみ初期化しています。ボタン周りのライブラリも搭載していません。
電子ペーパー系の機能でいうと、RTCと呼ばれるリアルタイムクロック系のライブラリも搭載していません。このへんが公式ライブラリとの最大の違いになります。これまで紹介してきたみたいに、公式ライブラリのグラフィック関連をLovyanGFXに置き換えるのであれば、比較的問題はありません。しかしながらLovyanGFXライブラリのみでコーディングをしようとした場合には公式ライブラリで実装されているような機能を自分を組み合わせて実現する必要があります。
ESP32-Chimera-Core
キメラコアは、複数の公式ライブラリをがっちゃんとした統合ライブラリです。グラフィック関連はLovyanGFXを利用しています。しかしながらまだ電子ペーパー系のボードはサポートしていないようです。M5StickCなどもサポートが弱いですので、電子ペーパーはサポートされないかもしれません。
M5Lite
ESP32LitePackというごった煮のライブラリの中にある、M5Liteもキメラコアに近いコンセプトで作られたライブラリです。ただしM5StickC風のライブラリになっており、グラフィック関連はLovyanGFXを利用しており、機種判定をしなくても同じようにコーディングできるようなライブラリになっています。
しかしながら、まだ電子ペーパーのサポートはありません。すみません、私が作業していません。。。これは公式ライブラリとLovyanGFXで差分を確認して、差分を独自に作成しているためちょっと時間がかかっています。
RTCとの連携サンプル
#define LGFX_AUTODETECT
#include <LovyanGFX.hpp>
#include "I2C_BM8563.h"
LGFX lcd;
I2C_BM8563 rtc(I2C_BM8563_DEFAULT_ADDRESS, Wire1);
void setup() {
// Init lcd
lcd.init();
// Init I2C
int board = lcd.getBoard();
if (board == lgfx::board_M5Stack_CoreInk) {
Wire1.begin(21, 22);
lcd.setTextColor(TFT_BLACK, TFT_WHITE);
} else if (board == lgfx::board_M5Paper) {
Wire1.begin(21, 22);
lcd.setTextColor(TFT_BLACK, TFT_WHITE);
}
// Get RTC
rtc.begin();
I2C_BM8563_DateTypeDef dateStruct;
I2C_BM8563_TimeTypeDef timeStruct;
rtc.getDate(&dateStruct);
rtc.getTime(&timeStruct);
// 描画
lcd.setTextSize(3);
lcd.printf("%04d/%02d/%02d\n%02d:%02d:%02d\n",
dateStruct.year,
dateStruct.month,
dateStruct.date,
timeStruct.hours,
timeStruct.minutes,
timeStruct.seconds
);
lcd.display();
lcd.waitDisplay(); // 描画終了まで待たないと描画終了前に電源OFFになる
// Timer Set
rtc.SetAlarmIRQ(5);
// Sleep
if (board == lgfx::board_M5Stack_CoreInk) {
lcd.sleep();
pinMode(12, OUTPUT);
digitalWrite(12, 0);
} else if (board == lgfx::board_M5Paper) {
lcd.sleep();
pinMode(2, OUTPUT);
digitalWrite(2, 0);
} else {
esp_sleep_enable_timer_wakeup(5 * 1000 * 1000);
esp_deep_sleep_start();
}
}
void loop() {
// ここに入ってくるってことはスリープにはいれていない
delay(1000);
lcd.wakeup(); // 復帰しないと描画できない
lcd.printf("I'm not sleeping.\n");
lcd.display();
delay(4000);
ESP.restart();
}
おそらくボタン周りは自分で組んでも大変ではないと思いますので、一番の懸念事項のRTCまわりの使い方を説明したいと思います。RTCはM5StickCと同じBM8563が利用されていますので、M5Lite用に作成したライブラリがそのまま利用できました。
I2C_BM8563とライブラリマネージャで検索することでインストール可能です。事前にRTCの時刻合わせをする必要があります。I2C_BM8563ライブラリの中にBM8563_SET_NTPというスケッチ例でNTPでの時刻合わせが可能です。WiFi.begin(“SSID”, “KEY”)の部分でWi-Fiに接続できるSSIDとKEYを入力することでインターネット経由で時刻合わせがされます。
// 描画
lcd.setTextSize(3);
lcd.printf("%04d/%02d/%02d\n%02d:%02d:%02d\n",
dateStruct.year,
dateStruct.month,
dateStruct.date,
timeStruct.hours,
timeStruct.minutes,
timeStruct.seconds
);
lcd.display();
lcd.waitDisplay(); // 描画終了まで待たないと描画終了前に電源OFFになる
実際の描画は上記で実行しています。特徴としてdisplay()を実行しないかぎり電子ペーパーは画面に反映されません。そして、通常は描画完了まで待機する必要がないのですが、描画して電源を切る場合には描画完了まで待機しないと描画途中で電源OFFになってしまいます。
// Timer Set
rtc.SetAlarmIRQ(5);
上記で5秒後に起動する設定になります。
// Sleep
if (board == lgfx::board_M5Stack_CoreInk) {
lcd.sleep();
pinMode(12, OUTPUT);
digitalWrite(12, 0);
} else if (board == lgfx::board_M5Paper) {
lcd.sleep();
pinMode(2, OUTPUT);
digitalWrite(2, 0);
} else {
esp_sleep_enable_timer_wakeup(5 * 1000 * 1000);
esp_deep_sleep_start();
}
スリープに入る設定です。これはボードにより異なるので注意してください。CoreInkとM5Paperは電源ONを保持するためのPINが存在しています。CoreInkはGPIO12、M5PaperはGPIO2です。このGPIOをLOWに設定することで電源OFFにすることができます。ただし、USB接続されていると電源OFFにはならないので注意してください。
一番下にはM5Stackなどが接続した場合用にESP32のスリープを設定しています。M5Stackだとスリープすると画面が消えてしまいます。AXP192などを搭載するM5Stack Core2やM5StickCなどは画面は消えません。
void loop() {
// ここに入ってくるってことはスリープにはいれていない
delay(1000);
lcd.wakeup(); // 復帰しないと描画できない
lcd.printf("I'm not sleeping.\n");
lcd.display();
delay(4000);
ESP.restart();
}
loop関数には本来入ってこないはずです。しかしながらCoreInkやM5PaperはUSB接続したままだと電源が切れない設計になっています。ここに入ってきている場合にはUSB接続されている状態です。最初に画面をスリープしているので、復帰する必要があり警告を表示してからESP32のリセットを実行しています。
この動作により、次にリセットがかかった場合にUSB接続が抜かれていた場合には、通常のスリープ動作に移行することになります。
まとめ
将来的にはM5Liteで対応する予定ですが、現在はこのように各機能を実行するためにどのような実装にしたらよいのかを確認している段階です。ボタンの数も多いのでいろいろと他のボードとの調整が発生しそうです。。。
コメント