03.T-Watch S3 plus + LVGL 9でsleep


03.T-Watch S3 plus + LVGL 9でsleep

ブログ"01.T-Watch S3 plus + LGVL 9で簡易時計表示"にsleep機能を追加しました。電源ボタンでsleep (画面off)。復帰(画面on)は画面タッチです。(本当は、時計画面なら30秒後に画面off(sleep)、復帰は電源ボタン。 にしたいのですがとりあえずサンプルの通り)
...\LilyGoLib-master\examples\sleep\WakeUpFromTouchPanel\WakeUpFromTouchPanel.inoを参照しました。
写真は01のブログと同じです。

sleepのスケッチ例

Arduino-IDE > ファイル > スケッチ例 > (カスタムライブラリのスケッチ例) LilyGoLib > sleep の下に6つのサンプルスケッチがあります。

・1.LightSleep.ino
 LightSleep 電源ボタンを1回押すとゆっくり暗くなり、ゆっくり明るくなります。

・2.WakeUpFromBootButton.ino
 BOOTボタンで復帰。時計内部のボタンの為、対象機種外です。

下記3-6は電源ボタンを押すと5秒カウントダウンしてsleepします。復帰が異なります。

・3.WakeUpFromPowerButton.ino
  電源ボタンを押すと2秒ぐらい後に復帰します。タッチでも復帰する時があります。?

・4.WakeUpFromSensor.ino
 ダブルクリックで復帰しますが、1回では動作しない時もあります。

・5.WakeUpFromTimer.ino
 設定時間15秒+起動時間が過ぎると(=23秒)自動復帰します。

・6.WakeupFormTouchScreen.ino
 タッチで復帰しますが、1回では動作しない時もあります。

スケッチ


// 時計表示 (ただし、設定時刻はスケッチに記入)
// sleep:電源ボタンを押す 5秒以下(6秒でoffします)。復帰:画面タッチ
// (ボード) esp32 by Espressif Systems 3.3.5(最新) 3.3.0以上
// lvgl by kisvegabor 9.2.2固定 (LilyGoLib 0.1.0より)
// エラーのためLovyanGFX 1.2.7(最新)は更新待ちで使用せず
// lv_conf.hでデフォルトfont:中日韓16pxの lv_font_simsun_16_cjk
// ツール > ボード > esp32 > LilyGo T-Watch-S3
// ●は、ブログ01.からの追加・修正
#include <LilyGoLib.h>              // LilyGoLib 0.1.0(最新)を使用
#include <LV_Helper.h>              // LVGL 9.2.2を使用
#include <time.h>                   // 時間を使用
long unsigned int BattInterval;     // バッテリー測定間隔用
int BattPer;                        // バッテリー残量
bool BattCher;                      // 1=充電マーク or " "
bool power_button_clicked = false;  // 電源ボタンは押していない ●

char youbi[7][4] = { "日", "月", "火", "水", "木", "金", "土" };  // 曜日配列

void setup() {
  Serial.begin(115200);                // シリアルモニタの通信速度
  instance.begin();                    // LilyGoLibを初期化
  beginLvglHelper(instance);           // LVGLを初期化
  instance.pmu.enableBattDetection();  // 電源機能の有効化
  //instance.rtc.setDateTime(2026, 1, 9, 15, 49, 55);// 1回目8分後の時刻にRTCセット 2回目1分後にセット その後注釈に

  lv_display_t *disp = lv_display_create(240, 240);  // 指定解像度で新しいディスプレイを作成

  lv_style_t style_48;                                                                      // 基本スタイル
  lv_style_init(&style_48);                                                                 // スタイル初期化
  lv_obj_set_style_bg_color(lv_screen_active(), lv_color_make(0, 0, 0), LV_PART_MAIN);      // rgb 黒地
  lv_obj_set_style_text_color(lv_screen_active(), lv_color_make(0, 255, 0), LV_PART_MAIN);  // rgb 緑字

  // 1行目1 年/月/日( 表示はloop内
  lv_obj_t *label11 = lv_label_create(lv_screen_active());  // 現在の画面にラベル11を追加
  lv_obj_set_style_text_font(label11,
                             &lv_font_montserrat_24, LV_PART_MAIN);                  // 英数字 24px
  lv_obj_align(label11, LV_ALIGN_TOP_LEFT, 0, 0);                                    // 左上からの位置
  lv_obj_set_style_text_color(label11, lv_color_make(255, 255, 255), LV_PART_MAIN);  // rgb 白字
  lv_obj_set_style_transform_zoom(label11, 240, 0);                                  // ズーム(=/256)倍 384(1.5) 320(1.25) 384

  // 1行目2 曜日 表示はloop内 デフォルトfont
  lv_obj_t *label12 = lv_label_create(lv_screen_active());                           // 現在の画面にラベル11を追加
  lv_obj_align(label12, LV_ALIGN_TOP_LEFT, 130, 0);                                  // 左上からの位置
  lv_obj_set_style_text_color(label12, lv_color_make(255, 255, 255), LV_PART_MAIN);  // rgb 白字
  lv_obj_set_style_transform_zoom(label12, 352, 0);                                  // ズーム(=/256)倍 384(1.5) 320(1.25)320

  // 1行目3 ")"
  lv_obj_t *label13 = lv_label_create(lv_screen_active());                           // 現在の画面にラベル11を追加
  lv_obj_set_style_text_font(label13, &lv_font_montserrat_24, LV_PART_MAIN);         // 英数字 24px
  lv_obj_align(label13, LV_ALIGN_TOP_LEFT, 156, 0);                                  // 左上からの位置
  lv_obj_set_style_text_color(label13, lv_color_make(255, 255, 255), LV_PART_MAIN);  // rgb 白字
  lv_obj_set_style_transform_zoom(label13, 240, 0);                                  // ズーム(=/256)倍 384(1.5) 320(1.25)
  lv_label_set_text(label13, ")");                                                   // ラベルにセット

  // 1行目4 充電マーク 表示はloop内
  lv_obj_t *label14 = lv_label_create(lv_screen_active());                         // 現在の画面にラベル12を追加
  lv_obj_align(label14, LV_ALIGN_TOP_LEFT, 170, 5);                                // 左上からの位置
  lv_obj_set_style_text_color(label14, lv_color_make(0, 255, 255), LV_PART_MAIN);  // rgb 水色字
  lv_obj_set_style_transform_zoom(label14, 240, 0);                                // ズーム(=/256)倍 384(1.5) 320(1.25) 384

  // 1行目5 Batt(%) 表示はloop内
  lv_obj_t *label15 = lv_label_create(lv_screen_active());                         // 現在の画面にラベル12を追加
  lv_obj_set_style_text_font(label15, &lv_font_montserrat_24, LV_PART_MAIN);       // 英数字 24px
  lv_obj_align(label15, LV_ALIGN_TOP_LEFT, 182, 0);                                // 左上からの位置
  lv_obj_set_style_text_color(label15, lv_color_make(0, 255, 255), LV_PART_MAIN);  // rgb 水色字
  lv_obj_set_style_transform_zoom(label15, 240, 0);                                // ズーム(=/256)倍 384(1.5) 320(1.25) 384

  // 2行目1 "am" or "pm" 表示はloop内
  lv_obj_t *label21 = lv_label_create(lv_screen_active());  // 現在の画面にラベル21を追加
  lv_obj_set_style_text_font(label21,
                             &lv_font_montserrat_24, LV_PART_MAIN);  // 英数字 24px
  lv_obj_align(label21, LV_ALIGN_TOP_LEFT, 0, 70 * 0 + 40 + 25);     // 左上からの位置

  // 2行目2 現在時刻(12H) 表示はloop内
  lv_obj_t *label22 = lv_label_create(lv_screen_active());  // 現在の画面にラベル22を追加
  lv_obj_set_style_text_font(label22,
                             &lv_font_montserrat_48, LV_PART_MAIN);  // 英数字 48px
  lv_obj_align(label22, LV_ALIGN_TOP_LEFT, 60, 70 * 0 + 40);         // 左上からの位置
  lv_obj_set_style_transform_zoom(label22, 320, 0);                  // ズーム(=/256)倍 384(1.5) 320(1.25)

  // 3行目1 "設定" デフォルトfont
  lv_obj_t *label31 = lv_label_create(lv_screen_active());             // 現在の画面にラベル31を追加
  lv_obj_align(label31, LV_ALIGN_TOP_LEFT, 0, 70 * 1 + 40 + 25 - 10);  // 左上からの位置
  lv_obj_set_style_transform_zoom(label31, 448, 0);                    // ズーム(=/256)倍 384(1.5) 320(1.25)320
  lv_label_set_text(label31, "設定");                                  // テキスト

  // 3行目2 設定時刻(24H)
  lv_obj_t *label32 = lv_label_create(lv_screen_active());  // 現在の画面にラベル32を追加
  lv_obj_set_style_text_font(label32,
                             &lv_font_montserrat_48, LV_PART_MAIN);  // 英数字 48px
  lv_obj_align(label32, LV_ALIGN_TOP_LEFT, 60, 70 * 1 + 40);         // 左上からの位置
  lv_obj_set_style_transform_zoom(label32, 320, 0);                  // ズーム(=/256)倍
  lv_label_set_text(label32, "00:00");                               // テキスト 目標時刻

  // 4行目1 "あと" デフォルトfont
  lv_obj_t *label41 = lv_label_create(lv_screen_active());             // 現在の画面にラベル41を追加
  lv_obj_align(label41, LV_ALIGN_TOP_LEFT, 0, 70 * 2 + 40 + 25 - 10);  // 左上からの位置
  lv_obj_set_style_transform_zoom(label41, 448, 0);                    // ズーム(=/256)倍 384(1.5) 320(1.25)320
  lv_label_set_text(label41, "あと");                                  // テキスト

  // 4行目2 残りの分数
  lv_obj_t *label42 = lv_label_create(lv_screen_active());  // 現在の画面にラベル42を追加
  lv_obj_set_style_text_font(label42,
                             &lv_font_montserrat_48, LV_PART_MAIN);  // 英数字 48px
  lv_obj_align(label42, LV_ALIGN_TOP_RIGHT, -60, 70 * 2 + 40);       // 左上からの位置
  lv_obj_set_style_transform_zoom(label42, 320, 0);                  // ズーム4(=/256)倍
  lv_label_set_text(label42, "0");                                   // ラベルのテキスト 残り時間

  // 4行目3 "分" デフォルトfont
  lv_obj_t *label43 = lv_label_create(lv_screen_active());     // 現在の画面にラベル43を追加
  lv_obj_align(label43, LV_ALIGN_TOP_LEFT, 200, 70 * 2 + 40);  // 左上からの位置
  lv_obj_set_style_transform_zoom(label43, 768, 0);            // ズーム(=/256)倍 384(1.5) 320(1.25)
  lv_label_set_text(label43, "分");                            // ラベル1のテキスト 現在時刻

  instance.setBrightness(100);  // 明るさ off(0)-max(255)

  lv_task_handler();                                           // ●
  instance.onEvent([](DeviceEvent_t event, void *user_data) {  // ●
    power_button_clicked = true;
  },
                   PMU_EVENT_KEY_CLICKED, NULL);
  // (DeviceEventCb_t cbEvent, DeviceEvent_t event, void*user_data)

  while (!power_button_clicked) {                                  // ● 電源ボタンを押すまで(押したらsleep)
    if (BattInterval < millis()) {                                 // 時間を過ぎたら ●loopから移動
      char buf[64], buf2[64];                                      // buf文字データ用
      struct tm timeinfo;                                          // 時刻を取得するCライブラリ構造体
      instance.rtc.getDateTime(&timeinfo);                         // RTCから読み込む
      size_t written = strftime(buf, 64, "%Y/%m/%d(", &timeinfo);  // 年/月/日(
      lv_label_set_text(label11, buf);                             // ラベルにセット

      written = strftime(buf2, 64, "%w", &timeinfo);  // 曜日の数 日(0)-土(6)
      sprintf(buf, "%s", youbi[atoi(buf2)]);          // 曜日
      lv_label_set_text(label12, buf);                // ラベルにセット

      written = strftime(buf, 64, "%P", &timeinfo);  // am or pm
      lv_label_set_text(label21, buf);               // ラベルにセット

      written = strftime(buf, 64, "%l:%M", &timeinfo);  // 時:分
      lv_label_set_text(label22, buf);                  // ラベルにセット

      BattCher = instance.pmu.isCharging();  // 充電中か測定
      lv_label_set_text_fmt(label14, "%s",
                            BattCher ? LV_SYMBOL_CHARGE : "  ");  // "充電マーク" or " "

      BattPer = instance.pmu.getBatteryPercent();  // バッテリー残量(%)測定
      if (BattPer < 0) BattPer = 0;                // バッテリ残量最低値は0%
      if (BattPer > 100) BattPer = 100;            // バッテリ残量最高値は100%
      String s = "   " + String(BattPer);          // 左に空白をつなげる
      s = s.substring(s.length() - 3);             // 右3文字をとる
      lv_label_set_text_fmt(label15, "%s%%", s);   //  残量+%

      BattInterval = millis() + 2000;  // 2秒ごとに測定
    }
    instance.loop();     // ● LVGLの内部状態を更新
    lv_timer_handler();  // LVGLの内部処理を進める ●loopから移動
    delay(2);            // 2mS待つ ●loopから移動
  }
  instance.sleep(WAKEUP_SRC_TOUCH_PANEL);  // ● sleepします touchで復帰
  Serial.println("ここは表示されません");  // ● sleep中
}
void loop() {}  // ●setupへ移動
* flash memory(3.1Mbyte)のうち、スケッチが34%使用。RAM(327kbyte)のうち、global変数が7%使用、local変数で301kbyte使用可能。(1000byte=1kbyteで計算)

以下を使用しています。
LilyGoLib 0.1.0
FFat 3.3.5
FS 3.3.5
Wire 3.3.5
SensorLib 0.3.3
SPI 3.3.5
RadioLib 7.1.0
TinyGPSPlus 1.1.0
ESP_I2S 3.3.5
XPowersLib 0.3.1
lvgl 9.2.2
esptool v5.1.0