From fd52ca8fe6f42226ec32a001f4c61dc100ead94a Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Fri, 3 Sep 2021 14:35:38 +0300 Subject: [PATCH 1/4] Detect full charge and improve watchface display --- src/components/battery/BatteryController.cpp | 10 +++++-- src/components/battery/BatteryController.h | 9 +++++- src/displayapp/screens/BatteryInfo.cpp | 4 +-- src/displayapp/screens/PineTimeStyle.cpp | 31 +++++++++++--------- src/displayapp/screens/PineTimeStyle.h | 4 ++- src/displayapp/screens/WatchFaceAnalog.cpp | 28 +++++++++++++++--- src/displayapp/screens/WatchFaceAnalog.h | 2 ++ src/displayapp/screens/WatchFaceDigital.cpp | 12 ++++++-- src/displayapp/screens/WatchFaceDigital.h | 1 + 9 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index f8a64ecd..619e227c 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -19,6 +19,12 @@ void Battery::Update() { isCharging = !nrf_gpio_pin_read(chargingPin); isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); + if (isPowerPresent && !isCharging) { + isFull = true; + } else if (!isPowerPresent) { + isFull = false; + } + if (isReading) { return; } @@ -65,12 +71,12 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024; - if (voltage > battery_max) { + if (isFull) { percentRemaining = 100; } else if (voltage < battery_min) { percentRemaining = 0; } else { - percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); + percentRemaining = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), 99); } nrfx_saadc_uninit(); diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 6f09b737..164057c4 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -23,13 +23,19 @@ namespace Pinetime { } bool IsCharging() const { - return isCharging; + // isCharging will go up and down when fully charged + // isFull makes sure this returns false while fully charged. + return isCharging && !isFull; } bool IsPowerPresent() const { return isPowerPresent; } + bool IsFull() const { + return isFull; + } + private: static Battery* instance; nrf_saadc_value_t saadc_value; @@ -40,6 +46,7 @@ namespace Pinetime { uint16_t voltage = 0; uint8_t percentRemaining = 0; + bool isFull = false; bool isCharging = false; bool isPowerPresent = false; diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 91c26512..4dcf29c5 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -60,10 +60,10 @@ void BatteryInfo::Refresh() { batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); - if (batteryController.IsCharging() and batteryPercent < 100) { + if (batteryController.IsCharging()) { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); lv_label_set_text_static(status, "Charging"); - } else if (batteryPercent == 100) { + } else if (batteryController.IsFull()) { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); lv_label_set_text_static(status, "Fully charged"); } else if (batteryPercent < 10) { diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp index 7a712f43..6766ecb0 100644 --- a/src/displayapp/screens/PineTimeStyle.cpp +++ b/src/displayapp/screens/PineTimeStyle.cpp @@ -100,10 +100,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_label_set_text(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); - - batteryPlug = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); - lv_obj_align(batteryPlug, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); + lv_obj_set_auto_realign(batteryIcon, true); bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); @@ -205,18 +202,24 @@ PineTimeStyle::~PineTimeStyle() { lv_obj_clean(lv_scr_act()); } +void PineTimeStyle::SetBatteryIcon() { + auto batteryPercent = batteryPercentRemaining.Get(); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); +} + void PineTimeStyle::Refresh() { - batteryPercentRemaining = batteryController.PercentRemaining(); - if (batteryPercentRemaining.IsUpdated()) { - auto batteryPercent = batteryPercentRemaining.Get(); - if (batteryController.IsCharging()) { - auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent(); - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); - lv_obj_realign(batteryPlug); - lv_label_set_text(batteryIcon, ""); + isCharging = batteryController.IsCharging(); + if (isCharging.IsUpdated()) { + if (isCharging.Get()) { + lv_label_set_text(batteryIcon, Symbols::plug); } else { - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); - lv_label_set_text(batteryPlug, ""); + SetBatteryIcon(); + } + } + if (!isCharging.Get()) { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { + SetBatteryIcon(); } } diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index cb74ead5..ba473806 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -41,6 +41,7 @@ namespace Pinetime { uint8_t currentDay = 0; DirtyValue batteryPercentRemaining {}; + DirtyValue isCharging {}; DirtyValue bleState {}; DirtyValue> currentDateTime {}; DirtyValue motionSensorOk {}; @@ -58,7 +59,6 @@ namespace Pinetime { lv_obj_t* backgroundLabel; lv_obj_t* batteryIcon; lv_obj_t* bleIcon; - lv_obj_t* batteryPlug; lv_obj_t* calendarOuter; lv_obj_t* calendarInner; lv_obj_t* calendarBar1; @@ -76,6 +76,8 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::MotionController& motionController; + void SetBatteryIcon(); + lv_task_t* taskRefresh; }; } diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 75e35c1b..843e557c 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -176,11 +176,31 @@ void WatchFaceAnalog::UpdateClock() { } } +void WatchFaceAnalog::SetBatteryIcon() { + auto batteryPercent = batteryPercentRemaining.Get(); + if (batteryPercent == 100) { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + } else { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + } + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); +} + void WatchFaceAnalog::Refresh() { - batteryPercentRemaining = batteryController.PercentRemaining(); - if (batteryPercentRemaining.IsUpdated()) { - auto batteryPercent = batteryPercentRemaining.Get(); - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + isCharging = batteryController.IsCharging(); + if (isCharging.IsUpdated()) { + if (isCharging.Get()) { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); + lv_label_set_text(batteryIcon, Symbols::plug); + } else { + SetBatteryIcon(); + } + } + if (!isCharging.Get()) { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { + SetBatteryIcon(); + } } notificationState = notificationManager.AreNewNotificationsAvailable(); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 406f4d50..001414a6 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -49,6 +49,7 @@ namespace Pinetime { uint8_t currentDay = 0; DirtyValue batteryPercentRemaining {0}; + DirtyValue isCharging {}; DirtyValue> currentDateTime; DirtyValue notificationState {false}; @@ -81,6 +82,7 @@ namespace Pinetime { Controllers::Settings& settingsController; void UpdateClock(); + void SetBatteryIcon(); lv_task_t* taskRefresh; }; diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 58ab6190..3e755f8e 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -102,12 +102,20 @@ WatchFaceDigital::~WatchFaceDigital() { } void WatchFaceDigital::Refresh() { + isCharging = batteryController.IsCharging(); + if (isCharging.IsUpdated()) { + lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging.Get())); + } + batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); + if (batteryPercent == 100) { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + } else { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + } lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); - auto isCharging = batteryController.IsCharging() or batteryController.IsPowerPresent(); - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); } bleState = bleController.IsConnected(); diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 48dc1373..69a6067d 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -44,6 +44,7 @@ namespace Pinetime { uint8_t currentDay = 0; DirtyValue batteryPercentRemaining {}; + DirtyValue isCharging {}; DirtyValue bleState {}; DirtyValue> currentDateTime {}; DirtyValue motionSensorOk {}; From ac2ccaeff6e713b0121b39a6ae5dfce15ea8680c Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Fri, 3 Sep 2021 14:57:07 +0300 Subject: [PATCH 2/4] Auto realign battery icon in Analog watch face --- src/displayapp/screens/WatchFaceAnalog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 843e557c..53e7faf7 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -68,6 +68,7 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryHalf); lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0); + lv_obj_set_auto_realign(batteryIcon, true); notificationIcon = lv_label_create(lv_scr_act(), NULL); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); From b31b2425f8afd5022173852f5a78592b37104c39 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Fri, 3 Sep 2021 16:57:00 +0300 Subject: [PATCH 3/4] Use percentage instead of IsFull --- src/components/battery/BatteryController.h | 4 ---- src/displayapp/screens/BatteryInfo.cpp | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 164057c4..b66da5e4 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -32,10 +32,6 @@ namespace Pinetime { return isPowerPresent; } - bool IsFull() const { - return isFull; - } - private: static Battery* instance; nrf_saadc_value_t saadc_value; diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 4dcf29c5..25fd1efa 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -63,7 +63,7 @@ void BatteryInfo::Refresh() { if (batteryController.IsCharging()) { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); lv_label_set_text_static(status, "Charging"); - } else if (batteryController.IsFull()) { + } else if (batteryPercent == 100) { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); lv_label_set_text_static(status, "Fully charged"); } else if (batteryPercent < 10) { From 980ac173888883b34367395fdf8ee76c0aea6f72 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Wed, 22 Sep 2021 13:58:45 +0300 Subject: [PATCH 4/4] Show plug icon while plugged in --- src/components/battery/BatteryController.cpp | 2 +- src/displayapp/screens/WatchFaceDigital.cpp | 6 +++--- src/displayapp/screens/WatchFaceDigital.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index d2ddae74..b43b229f 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -74,7 +74,7 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { } else if (voltage < battery_min) { percentRemaining = 0; } else { - percentRemaining = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), 99); + percentRemaining = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), isCharging ? 99 : 100); } nrfx_saadc_uninit(); diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 3e755f8e..2ecab609 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -102,9 +102,9 @@ WatchFaceDigital::~WatchFaceDigital() { } void WatchFaceDigital::Refresh() { - isCharging = batteryController.IsCharging(); - if (isCharging.IsUpdated()) { - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging.Get())); + powerPresent = batteryController.IsPowerPresent(); + if (powerPresent.IsUpdated()) { + lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get())); } batteryPercentRemaining = batteryController.PercentRemaining(); diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 69a6067d..e27545f3 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -44,7 +44,7 @@ namespace Pinetime { uint8_t currentDay = 0; DirtyValue batteryPercentRemaining {}; - DirtyValue isCharging {}; + DirtyValue powerPresent {}; DirtyValue bleState {}; DirtyValue> currentDateTime {}; DirtyValue motionSensorOk {};