05.T-Watch S3 plusでアラーム時刻設定画面テスト
05.T-Watch S3 plusでアラーム時刻設定画面テスト
T-Watch S3 plusにて、アラーム時刻を設定する画面をLVGL 9 で作ります。examples/others/observer/lv_example_observer_3.c を参照し、lv_observer, lv_roller 等を使用します。
画面説明
1行目
・Cancelボタン : 何もしません。後の連結時は、時計画面に戻る予定です。・Setボタン : シリアルモニタに設定時刻を表示します。後の連結時は、時計画面に戻り、アラーム設定時刻を表示する予定です。
2行目
・ローラーで設定した時刻をリアルタイムで表示します。例 1+ 1:30は、翌日のam1:30です。初期値は、今日の昼12:30(0+ 12:30)とします。
3行目
・左 : ローラーを上下に回転し、今日(0)か翌日(1)にあわせます。・中央 : ローラーを上下に回転し、時(0~23)を合わせます。
・右 : ローラーを上下に回転し、分(0~59)を合わせます。
ローラーはエンドレスとします。..., 58, 59, 0, 1, ...
スケッチ
// アラーム時刻セット画面
// examples/others/observer/lv_example_observer_3.c 参照
#include <LilyGoLib.h> // LilyGoLib 0.1.0(最新)を使用
#include <LV_Helper.h> // LVGL 9.2.2(固定)を使用
static lv_subject_t day_subject; // 今日/翌日 値が変わると、登録コールバックが呼ばれます
static lv_subject_t hour_subject; // 時
static lv_subject_t minute_subject; // 分
static lv_subject_t time_subject; // 上3つが入るグループ
static lv_subject_t *time_group_array_subject[] = { &day_subject, &hour_subject, &minute_subject }; // グループにする
const char *day_options = "0\n1"; // 今日/翌日
const char *hour_options =
"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23"; // 時 0-23
const char *minute_options = // 分 0-59
"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59";
int32_t setDay, setHour, setMinute; // set_btnで引き渡す日&時&分
static void time_observer_cb(lv_observer_t *observer, lv_subject_t *subject) { // ローラーの値をlabelに表示
int32_t day = lv_subject_get_int(lv_subject_get_group_element(subject, 0));
int32_t hour = lv_subject_get_int(lv_subject_get_group_element(subject, 1));
int32_t minute = lv_subject_get_int(lv_subject_get_group_element(subject, 2));
// lv_subject_get_int( )は、整数Subjectの現在の値を取得(Subjectへのpointer)、戻り値:現在の値
// lv_subject_get_group_element( )は、
// Subject Groupのリストから要素を取得(Group型のSubjectへのpointer,取得する要素のインデックス)
// 戻り値:リスト内のインデックス付Subjectへのpointer インデックスが範囲外の場合はNULL
setDay = day; // set_btnをクリックしたら引き渡す 日
setHour = hour; // 時
setMinute = minute; // 分
lv_obj_t *label = (lv_obj_t *)lv_observer_get_target(observer);
// Observerのターゲットを取得(Observerへのpointer)、戻り値:保存されたターゲットへのpointer
lv_label_set_text_fmt(label, "Alam %" LV_PRId32 "+ %" LV_PRId32 " : %02" LV_PRId32, day, hour, minute); // ローラーの値
}
static void set_btn_clicked_event_cb(lv_event_t *e) { // set_btnを押したら呼出される関数
lv_obj_t *set_btn = lv_event_get_target_obj(e);
// イベントの元のターゲットobjを取得(イベント記述子へのpointer)、戻り値:event_codeの元のターゲットへのpointer
Serial.printf("Alam %1d+ %2d:%02d", setDay, setHour, setMinute); // シリアルモニタに日時分を表示
}
static void cxl_clicked_event_cb(lv_event_t *e) { // cxl_btnを押したら
// そのまま時計画面に戻る予定
}
void setup() {
Serial.begin(115200); // シリアルモニタの通信速度
instance.begin(); // LilyGoLibを初期化
beginLvglHelper(instance); // LVGLを初期化
lv_task_handler();
instance.setBrightness(100); // 明るさ0-255
lv_subject_init_int(&day_subject, 0); // 初期値 0今日
lv_subject_init_int(&hour_subject, 12); // 初期値 12時
lv_subject_init_int(&minute_subject, 30); // 初期値 30分
//整数型のSubjectを初期化(Subjectへのpointer,初期値)
lv_subject_init_group(&time_subject, time_group_array_subject, 3);
// グループ型サブジェクトを初期化(グループ型サブジェクトへのpointer,
// 他のサブジェクトアドレスのリスト,list[]内の要素数)
// キャンセルボタン ------------------------------
lv_obj_t *cxl_btn = lv_button_create(lv_screen_active()); // cxl_btnを作成
lv_obj_set_pos(cxl_btn, 2, 5); // btnの位置
lv_obj_t *cxl_label = lv_label_create(cxl_btn); // cxl_btnにlabelを作成
lv_obj_set_style_text_font(cxl_label, &lv_font_montserrat_24, 0); // 英数文字サイズ24,28,32,36,40,44,48
lv_label_set_text(cxl_label, "Cancel"); // labelのtextを設定
// ラベル ------------------------------
lv_obj_t *time_label = lv_label_create(lv_screen_active()); // time_labelを作成
lv_obj_set_style_text_font(time_label, &lv_font_montserrat_28, 0); // 英数文字サイズ24,28,32,36,40,44,48
lv_subject_add_observer_obj(&time_subject, time_observer_cb, time_label, NULL);
// ウィジェットのサブジェクトにオブザーバーを追加(サブジェクトへのポインタ,
// 通知コールバック,ウィジェットへのpointer,オプションのユーザーデータ)
// 戻り値:新しく作成されたオブザーバーへのpointer
// ウィジェットが削除されると、オブザーバーはサブジェクトから自動的に登録解除。
// 注:この方法で作成されたオブザーバーは呼出さない。
// これらのオブザーバーは、次のいずれかの方法でのみクリーンアップしてください。
// lv_observer_remove()ウィジェットを削除するか、
// すべてのオブザーバーを適切に分離して削除するには、lv_subject_deinit() を呼出す。
lv_obj_set_pos(time_label, 0, 60); // ラベルの位置 70,20
// セットボタン ------------------------------
lv_obj_t *set_btn = lv_button_create(lv_screen_active()); // set_btnを作成
lv_obj_set_pos(set_btn, 120, 5); // btnの位置
lv_obj_set_width(set_btn, 115); // btn幅
lv_obj_add_event_cb(set_btn, set_btn_clicked_event_cb, LV_EVENT_CLICKED, NULL); // set_btnを押したらコールバック関数へ
lv_obj_t *set_label = lv_label_create(set_btn); // btnにlabelを作成
lv_obj_set_style_text_font(set_label, &lv_font_montserrat_24, 0); // 英数文字サイズ24,28,32,36,40,44,48
lv_label_set_text(set_label, " Set"); // labelのtextを設定
// 翌日ローラー ------------------------------
lv_obj_t *day_roller = lv_roller_create(lv_screen_active()); // 画面に翌日用ローラーを作成
lv_roller_set_options(day_roller, day_options, LV_ROLLER_MODE_INFINITE); // 永久スクロール
lv_roller_bind_value(day_roller, &day_subject); // 関連付
lv_obj_set_pos(day_roller, 10, 105); // rollerの位置
lv_obj_set_style_text_font(day_roller, &lv_font_montserrat_28, 0); // 英数文字サイズ24,28,32,36,40,44,48
// 時ローラー ------------------------------
lv_obj_t *hour_roller = lv_roller_create(lv_screen_active()); // 画面に時用ローラーを作成
lv_obj_add_flag(hour_roller, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
// 1つ以上のフラグを設定(objへのpointer, 設定する値のOR演算)
// LV_OBJ_FLAG_FLEX_IN_NEW_TRACK:このアイテムで新しいFlexトラックを開始
lv_roller_set_options(hour_roller, hour_options, LV_ROLLER_MODE_INFINITE); // 永久スクロール ...22,23,0,1,...
// ローラーのオプションを設定(ローラーobjへのpointer,\nで区切られた文字列,
// or LV_ROLER_MODE_NORMAL LV_ROLLER_MODE_INFINITE)
// LV_ROLLER_MODE_NORMAL:ローラーはオプションの最後で停止
// LV_ROLLER_MODE_INFINITE:ローラーは永久にスクロール
lv_roller_bind_value(hour_roller, &hour_subject);
// 整数SubjectをRollerの値に関連付(Rollerへのpointer,Subjectへのpointer)
// 戻り値:新しく作成されたObserverへのpointer
lv_obj_set_pos(hour_roller, 85, 105); // rollerの位置
lv_obj_set_style_text_font(hour_roller, &lv_font_montserrat_28, 0); // 英数文字サイズ24,28,32,36,40,44,48
// 分ローラー ------------------------------
lv_obj_t *min_roller = lv_roller_create(lv_screen_active()); // 画面に分用のローラーを作成
lv_roller_set_options(min_roller, minute_options, LV_ROLLER_MODE_INFINITE); // 永久スクロール 上と同様
lv_roller_bind_value(min_roller, &minute_subject); // 関連付け 上と同様
lv_obj_set_pos(min_roller, 160, 105); // rollerの位置
lv_obj_set_style_text_font(min_roller, &lv_font_montserrat_28, 0); // 英数文字サイズ24,28,32,36,40,44,48
}
void loop() {
lv_task_handler();
delay(5); // 5mS待つ
}
* flash memory(3.1Mbyte)のうち、スケッチが31%使用。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
lvgl 9.2.2
esptool 5.1.0
