From ad0436c61043ed33b7ea864e815981c4ccd89841 Mon Sep 17 00:00:00 2001 From: Kevin Le Date: Sat, 17 Oct 2026 14:50:43 +0700 Subject: [PATCH] UI changes for PowerSaving variant --- examples/companion_radio/ui-new/UITask.cpp | 35 ++++++++++++++++++++++ examples/simple_repeater/UITask.cpp | 14 ++++++++- examples/simple_repeater/UITask.h | 5 +++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index bc25de79c..f527baf58 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -123,6 +123,14 @@ class HomeScreen : public UIScreen { bool discovery_disp_names = true; // by default desplay names if available (removes SNR_O) #endif + // PowerSaving variant + // Uptime tracking + // Stores the last 32-bit millis() value used to calculate elapsed time. + // uint32_t naturally handles the ~49.7-day millis() rollover. + uint32_t uptime_last_millis = millis(); + // 64-bit accumulated uptime in milliseconds. + // Allows uptime to continue beyond the 49.7-day millis() rollover. + uint64_t uptime_millis = 0; void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) { // Convert millivolts to percentage #ifndef BATT_MIN_MILLIVOLTS @@ -174,6 +182,33 @@ class HomeScreen : public UIScreen { display.drawXbm(iconX - (charging ? 18 : 9), iconY + 1, muted_icon, 8, 8); } #endif + + // PowerSaving variant + // Uptime + uint32_t now = millis(); + uptime_millis += (uint32_t)(now - uptime_last_millis); + uptime_last_millis = now; + + uint64_t uptimeMinutes = uptime_millis / 60000ULL; + + unsigned long days = uptimeMinutes / 1440; + unsigned long hours = (uptimeMinutes % 1440) / 60; + unsigned long minutes = uptimeMinutes % 60; + char uptime[16]; + if (days > 0) { + snprintf(uptime, sizeof(uptime), "%lud %luh", days, hours); + } else if (hours > 0) { + snprintf(uptime, sizeof(uptime), "%luh %lum", hours, minutes); + } else { + snprintf(uptime, sizeof(uptime), "%lum", minutes); + } + + display.setTextSize(1); + int uptimeWidth = display.getTextWidth(uptime); + int uptimeX = display.width() - uptimeWidth - 2; + int uptimeY = iconY + iconHeight + 1; + display.setCursor(uptimeX, uptimeY); + display.print(uptime); } CayenneLPP sensors_lpp; diff --git a/examples/simple_repeater/UITask.cpp b/examples/simple_repeater/UITask.cpp index e0b6a41df..a60bea722 100644 --- a/examples/simple_repeater/UITask.cpp +++ b/examples/simple_repeater/UITask.cpp @@ -29,7 +29,9 @@ static const uint8_t meshcore_logo [] PROGMEM = { 0xe3, 0xe3, 0x8f, 0xff, 0x1f, 0xfc, 0x3c, 0x0e, 0x1f, 0xf8, 0xff, 0xf8, 0x70, 0x3c, 0x7f, 0xf8, }; -void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* firmware_version) { +// PowerSaving variant +// Added board for battery display +void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* firmware_version, mesh::MainBoard* board) { _prevBtnState = HIGH; _auto_off = millis() + AUTO_OFF_MILLIS; _started_at = millis(); @@ -106,6 +108,16 @@ void UITask::renderCurrScreen() { _display->setCursor(0, 30); sprintf(tmp, "BW: %03.2f CR: %d", _node_prefs->bw, _node_prefs->cr); _display->print(tmp); + + // Battery + _display->setCursor(0, 40); + sprintf(tmp, "BAT: %.2fV", _board->getBattMilliVolts() / 1000.0); + _display->print(tmp); + + // PowerSaving + _display->setCursor(0, 50); + sprintf(tmp, "PowerSaving: %s", _node_prefs->powersaving_enabled? "ON" : "off"); + _display->print(tmp); } } diff --git a/examples/simple_repeater/UITask.h b/examples/simple_repeater/UITask.h index d8e3ce1d2..b1c63e397 100644 --- a/examples/simple_repeater/UITask.h +++ b/examples/simple_repeater/UITask.h @@ -16,7 +16,10 @@ class UITask { void renderCurrScreen(); public: UITask(mesh::MainBoard& board, DisplayDriver& display) : _board(&board), _display(&display) { _next_read = _next_refresh = 0; } - void begin(NodePrefs* node_prefs, const char* build_date, const char* firmware_version); + + // PowerSaving variant + // Added board for battery display + void begin(NodePrefs* node_prefs, const char* build_date, const char* firmware_version, mesh::MainBoard* board); void loop(); }; \ No newline at end of file