diff --git a/src/epdgui/epdgui.cpp b/src/epdgui/epdgui.cpp index ffb348d..3c46a24 100644 --- a/src/epdgui/epdgui.cpp +++ b/src/epdgui/epdgui.cpp @@ -16,8 +16,12 @@ std::stack frame_stack; std::map frame_map; uint8_t frame_switch_count = 0; bool _is_auto_update = true; + +uint16_t _is_last_finger_up = 0xFFFF; uint16_t _last_pos_x = 0xFFFF, _last_pos_y = 0xFFFF; +uint32_t g_last_active_time_millis = 0; + void EPDGUI_AddObject(EPDGUI_Base* object) { object->SetID(obj_id); @@ -102,11 +106,16 @@ void EPDGUI_Run(Frame_Base* frame) if (M5.TP.avaliable()) { M5.TP.update(); - bool is_finger_up = M5.TP.isFingerUp(); - if(is_finger_up || (_last_pos_x != M5.TP.readFingerX(0)) || (_last_pos_y != M5.TP.readFingerY(0))) + uint16_t is_finger_up = M5.TP.isFingerUp() ? 1 : 0; + uint16_t pos_x = M5.TP.readFingerX(0); + uint16_t pos_y = M5.TP.readFingerY(0); + // Avoid duplicate events + if (_is_last_finger_up != is_finger_up || _last_pos_x != pos_x || _last_pos_y != pos_y) { - _last_pos_x = M5.TP.readFingerX(0); - _last_pos_y = M5.TP.readFingerY(0); + EPDGUI_UpdateGlobalLastActiveTime(); + _last_pos_x = pos_x; + _last_pos_y = pos_y; + _is_last_finger_up = is_finger_up; if(is_finger_up) { EPDGUI_Process(); @@ -114,7 +123,7 @@ void EPDGUI_Run(Frame_Base* frame) } else { - EPDGUI_Process(M5.TP.readFingerX(0), M5.TP.readFingerY(0)); + EPDGUI_Process(pos_x, pos_y); last_active_time = 0; } } @@ -211,3 +220,9 @@ void EPDGUI_SetAutoUpdate(bool isAuto) { _is_auto_update = isAuto; } + +/// Update active time to avoid power saving +void EPDGUI_UpdateGlobalLastActiveTime() +{ + g_last_active_time_millis = millis(); +} diff --git a/src/epdgui/epdgui.h b/src/epdgui/epdgui.h index 30ed0d6..c6437dc 100644 --- a/src/epdgui/epdgui.h +++ b/src/epdgui/epdgui.h @@ -24,4 +24,8 @@ void EPDGUI_AddFrameArg(String name, int n, void* arg); Frame_Base* EPDGUI_GetFrame(String name); void EPDGUI_SetAutoUpdate(bool isAuto); +extern uint32_t g_last_active_time_millis; + +void EPDGUI_UpdateGlobalLastActiveTime(); + #endif //__EPDGUI_H \ No newline at end of file diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp index dd82583..911c748 100644 --- a/src/frame/frame_base.cpp +++ b/src/frame/frame_base.cpp @@ -15,6 +15,7 @@ Frame_Base::Frame_Base(bool _has_title) } _frame_id = 0; _frame_name = "Frame_Base"; + EPDGUI_UpdateGlobalLastActiveTime(); } Frame_Base::~Frame_Base() @@ -23,6 +24,10 @@ Frame_Base::~Frame_Base() delete _key_exit; if(_canvas_title != NULL) delete _canvas_title; + if (_canvas_footer != NULL) + { + delete _canvas_footer; + } } void Frame_Base::exitbtn(String title, uint16_t width) @@ -38,8 +43,48 @@ void Frame_Base::exitbtn(String title, uint16_t width) _key_exit->CanvasPressed()->ReverseColor(); } +void Frame_Base::CheckAutoPowerSave() +{ + unsigned long now = millis(); + int footer_height = 28; + int margin_bottom = 10; + if (now - g_last_active_time_millis > TIME_BEFORE_SHUTDOWN_MS) + { + log_d("The idle time reached, shutdown now."); + Shutdown(); + } + else if (now - g_last_active_time_millis > TIME_BEFORE_SHUTDOWN_PROMPT_MS) + { + if (!_shutdown_prompt_is_shown) + { + log_d("Show shutdown prompt"); + _canvas_footer = new M5EPD_Canvas(&M5.EPD); + _canvas_footer->createCanvas(540, footer_height); + _canvas_footer->setTextSize(26); + _canvas_footer->setTextDatum(CC_DATUM); + char buf[128]; + sprintf(buf, "Shutdown to save power, touch to continue?"); + _canvas_footer->drawString(buf, 270, footer_height / 2); + _canvas_footer->pushCanvas(0, 960 - footer_height - margin_bottom, UPDATE_MODE_DU4); + _shutdown_prompt_is_shown = true; + } + } + else if (_shutdown_prompt_is_shown) + { + // active again and _shutdown_prompt_is_shown == true, hide prompt + log_d("Become active again, hide prompt"); + _canvas_footer->fillCanvas(0); + _canvas_footer->pushCanvas(0, 960 - footer_height - margin_bottom, UPDATE_MODE_DU4); + _shutdown_prompt_is_shown = false; + } +} + int Frame_Base::run(void) { + if (ENABLE_AUTO_POWER_SAVE) + { + CheckAutoPowerSave(); + } return _is_run; } diff --git a/src/frame/frame_base.h b/src/frame/frame_base.h index 0e6f430..a56c7a7 100644 --- a/src/frame/frame_base.h +++ b/src/frame/frame_base.h @@ -21,11 +21,16 @@ class Frame_Base uint32_t GetFrameID() {return _frame_id;} protected: static void exit_cb(epdgui_args_vector_t &args); + void UpdateLastActiveTime(); String _frame_name; int _is_run = 1; M5EPD_Canvas *_canvas_title = NULL; + M5EPD_Canvas *_canvas_footer = NULL; EPDGUI_Button *_key_exit = NULL; uint32_t _frame_id; +private: + bool _shutdown_prompt_is_shown = false; + void CheckAutoPowerSave(); }; diff --git a/src/frame/frame_compare.cpp b/src/frame/frame_compare.cpp index 5d085ef..e000f9f 100644 --- a/src/frame/frame_compare.cpp +++ b/src/frame/frame_compare.cpp @@ -145,6 +145,7 @@ Frame_Compare::~Frame_Compare(void) int Frame_Compare::run() { + Frame_Base::run(); switch(_update_flag) { case 1: diff --git a/src/frame/frame_factorytest.cpp b/src/frame/frame_factorytest.cpp index 29bf5d4..98aa86e 100644 --- a/src/frame/frame_factorytest.cpp +++ b/src/frame/frame_factorytest.cpp @@ -234,6 +234,7 @@ void Frame_FactoryTest::scan(String *ssid, int32_t *rssi) int Frame_FactoryTest::run() { + Frame_Base::run(); uint16_t pass_flag = _pass_flag; char buf[100]; // POS diff --git a/src/frame/frame_fileindex.cpp b/src/frame/frame_fileindex.cpp index c73fd6c..e755206 100644 --- a/src/frame/frame_fileindex.cpp +++ b/src/frame/frame_fileindex.cpp @@ -166,7 +166,7 @@ void Frame_FileIndex::listDir(fs::FS &fs, const char *dirname) btn->CanvasNormal()->setTextDatum(CR_DATUM); String suffix = filename.substring(filename.lastIndexOf(".")); - if(suffix.indexOf("txt") >= 0) + if (suffix.indexOf("txt") >= 0 || suffix.indexOf("TXT") >= 0) { btn->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_file_text_32x32); btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, btn); diff --git a/src/frame/frame_keyboard.cpp b/src/frame/frame_keyboard.cpp index c97f46f..55bd4da 100644 --- a/src/frame/frame_keyboard.cpp +++ b/src/frame/frame_keyboard.cpp @@ -142,6 +142,7 @@ int Frame_Keyboard::init(epdgui_args_vector_t &args) int Frame_Keyboard::run(void) { + Frame_Base::run(); inputbox->AddText(keyboard->getData()); return 1; } diff --git a/src/frame/frame_lifegame.cpp b/src/frame/frame_lifegame.cpp index 97f8502..db065a9 100644 --- a/src/frame/frame_lifegame.cpp +++ b/src/frame/frame_lifegame.cpp @@ -171,9 +171,11 @@ void LifeGame_NextGen(void *pvParameters) int Frame_Lifegame::run() { + Frame_Base::run(); M5.update(); if(M5.BtnP.wasReleased()) { + EPDGUI_UpdateGlobalLastActiveTime(); LifeGame_RandomCell(); } xTaskCreatePinnedToCore(LifeGame_NextGen, "LifeGame_NextGen", 4096, NULL, 1, NULL, 0); diff --git a/src/frame/frame_main.cpp b/src/frame/frame_main.cpp index f75b420..d4648d8 100644 --- a/src/frame/frame_main.cpp +++ b/src/frame/frame_main.cpp @@ -326,6 +326,7 @@ int Frame_Main::init(epdgui_args_vector_t &args) int Frame_Main::run() { + Frame_Base::run(); StatusBar(UPDATE_MODE_GL16); return 1; } \ No newline at end of file diff --git a/src/frame/frame_pictureviewer.cpp b/src/frame/frame_pictureviewer.cpp index d0cadac..ad2cabb 100644 --- a/src/frame/frame_pictureviewer.cpp +++ b/src/frame/frame_pictureviewer.cpp @@ -54,6 +54,7 @@ void Frame_PictureViewer::err(String info) int Frame_PictureViewer::run() { + Frame_Base::run(); if(_is_first) { _is_first = false; diff --git a/src/frame/frame_setting.cpp b/src/frame/frame_setting.cpp index 0c1d0d4..9025e70 100644 --- a/src/frame/frame_setting.cpp +++ b/src/frame/frame_setting.cpp @@ -9,16 +9,7 @@ const uint16_t kTimeZoneY = 520; void key_shutdown_cb(epdgui_args_vector_t &args) { - M5.EPD.WriteFullGram4bpp(GetWallpaper()); - M5.EPD.UpdateFull(UPDATE_MODE_GC16); - M5.EPD.UpdateFull(UPDATE_MODE_GC16); - SaveSetting(); - delay(600); - M5.disableEPDPower(); - M5.disableEXTPower(); - M5.disableMainPower(); - esp_deep_sleep_start(); - while(1); + Shutdown(); } void key_restart_cb(epdgui_args_vector_t &args) diff --git a/src/frame/frame_txtreader.cpp b/src/frame/frame_txtreader.cpp index e3268aa..6c919db 100644 --- a/src/frame/frame_txtreader.cpp +++ b/src/frame/frame_txtreader.cpp @@ -88,6 +88,7 @@ uint32_t Frame_txtReader::renderText(uint32_t cursor, uint32_t length, M5EPD_Can int Frame_txtReader::run() { + Frame_Base::run(); if(_is_first) { LoadingAnime_32x32_Start(254, 500); @@ -123,6 +124,7 @@ int Frame_txtReader::run() M5.update(); if(M5.BtnR.wasReleased() || (_key_operation == 1)) { + EPDGUI_UpdateGlobalLastActiveTime(); _key_operation = 0; if(_page != _page_end) { @@ -156,6 +158,7 @@ int Frame_txtReader::run() } else if(M5.BtnL.wasReleased() || (_key_operation == -1)) { + EPDGUI_UpdateGlobalLastActiveTime(); _key_operation = 0; if(_page > 0) { diff --git a/src/frame/frame_wifipassword.cpp b/src/frame/frame_wifipassword.cpp index 45441fa..4b228e3 100644 --- a/src/frame/frame_wifipassword.cpp +++ b/src/frame/frame_wifipassword.cpp @@ -82,6 +82,7 @@ int Frame_WifiPassword::init(epdgui_args_vector_t &args) int Frame_WifiPassword::run(void) { + Frame_Base::run(); String data = keyboard->getData(); if(data.indexOf("\n") >= 0) { diff --git a/src/frame/frame_wifiscan.cpp b/src/frame/frame_wifiscan.cpp index 985da75..897e53d 100644 --- a/src/frame/frame_wifiscan.cpp +++ b/src/frame/frame_wifiscan.cpp @@ -114,6 +114,7 @@ void Frame_WifiScan::DrawItem(EPDGUI_Button *btn, String ssid, int rssi) int Frame_WifiScan::run() { + Frame_Base::run(); if(_connect) { _connect = false; diff --git a/src/global_setting.cpp b/src/global_setting.cpp index 4117f69..c82e46a 100644 --- a/src/global_setting.cpp +++ b/src/global_setting.cpp @@ -313,3 +313,18 @@ void LoadingAnime_32x32_Stop() xSemaphoreGive(_xSemaphore_LoadingAnime); delay(200); } + +void Shutdown() +{ + log_d("Now the system is shutting down."); + M5.EPD.WriteFullGram4bpp(GetWallpaper()); + M5.EPD.UpdateFull(UPDATE_MODE_GC16); + M5.EPD.UpdateFull(UPDATE_MODE_GC16); + SaveSetting(); + delay(600); + M5.disableEPDPower(); + M5.disableEXTPower(); + M5.disableMainPower(); + esp_deep_sleep_start(); + while(1); +} \ No newline at end of file diff --git a/src/global_setting.h b/src/global_setting.h index cbf12cd..2b8bc08 100644 --- a/src/global_setting.h +++ b/src/global_setting.h @@ -7,6 +7,16 @@ #define WALLPAPER_NUM 3 +// 是否开启自动关机省电 +#define ENABLE_AUTO_POWER_SAVE true + +// 1分钟提醒即将关机 +static const uint32_t TIME_BEFORE_SHUTDOWN_PROMPT_MS = 60 * 1000; +// 显示10秒钟的关机提示 +static const uint32_t SHUTDOWN_PROMPT_DELAY_MS = 10 * 1000; +// 最终关机时间 +static const uint32_t TIME_BEFORE_SHUTDOWN_MS = TIME_BEFORE_SHUTDOWN_PROMPT_MS + SHUTDOWN_PROMPT_DELAY_MS; + enum { LANGUAGE_EN = 0, // default, English @@ -45,5 +55,6 @@ void SetTTFLoaded(uint8_t val); uint8_t isTTFLoaded(void); void SetInitStatus(uint8_t idx, uint8_t val); uint8_t GetInitStatus(uint8_t idx); +void Shutdown(); #endif //_GLOBAL_SETTING_H_ \ No newline at end of file