From 27ee1eb2c85b70280c1f31b316ae99dc7825adb8 Mon Sep 17 00:00:00 2001 From: Patric Gruber Date: Fri, 25 Aug 2023 02:10:45 +0200 Subject: [PATCH] add settings screen to choose heartrate measurement background --- src/CMakeLists.txt | 1 + src/components/settings/Settings.h | 13 +++ src/displayapp/DisplayApp.cpp | 4 + .../screens/settings/SettingHeartRate.cpp | 85 +++++++++++++++++++ .../screens/settings/SettingHeartRate.h | 42 +++++++++ src/displayapp/screens/settings/Settings.h | 8 +- src/heartratetask/HeartRateTask.cpp | 13 ++- src/heartratetask/HeartRateTask.h | 9 +- src/main.cpp | 6 +- 9 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 src/displayapp/screens/settings/SettingHeartRate.cpp create mode 100644 src/displayapp/screens/settings/SettingHeartRate.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8ece62..ca373119 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -411,6 +411,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingWeatherFormat.cpp displayapp/screens/settings/SettingWakeUp.cpp displayapp/screens/settings/SettingDisplay.cpp + displayapp/screens/settings/SettingHeartRate.cpp displayapp/screens/settings/SettingSteps.cpp displayapp/screens/settings/SettingSetDateTime.cpp displayapp/screens/settings/SettingSetDate.cpp diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 06312077..77c1ca1a 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -283,6 +283,17 @@ namespace Pinetime { return bleRadioEnabled; }; + uint32_t GetHeartRateBackgroundMeasurementInterval() const { + return settings.heartRateBackgroundMeasurementInterval; + } + + void SetHeartRateBackgroundMeasurementInterval(uint32_t newHeartRateBackgroundMeasurementInterval) { + if (newHeartRateBackgroundMeasurementInterval != settings.heartRateBackgroundMeasurementInterval) { + settingsChanged = true; + } + settings.heartRateBackgroundMeasurementInterval = newHeartRateBackgroundMeasurementInterval; + } + private: Pinetime::Controllers::FS& fs; @@ -308,6 +319,8 @@ namespace Pinetime { uint16_t shakeWakeThreshold = 150; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; + + uint32_t heartRateBackgroundMeasurementInterval = 0; }; SettingsData settings; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 3fd34b3a..94975db8 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -47,6 +47,7 @@ #include "displayapp/screens/settings/SettingSteps.h" #include "displayapp/screens/settings/SettingSetDateTime.h" #include "displayapp/screens/settings/SettingChimes.h" +#include "displayapp/screens/settings/SettingHeartRate.h" #include "displayapp/screens/settings/SettingShakeThreshold.h" #include "displayapp/screens/settings/SettingBluetooth.h" @@ -506,6 +507,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::SettingWakeUp: currentScreen = std::make_unique(settingsController); break; + case Apps::SettingHeartRate: + currentScreen = std::make_unique(this, settingsController); + break; case Apps::SettingDisplay: currentScreen = std::make_unique(this, settingsController); break; diff --git a/src/displayapp/screens/settings/SettingHeartRate.cpp b/src/displayapp/screens/settings/SettingHeartRate.cpp new file mode 100644 index 00000000..8460e260 --- /dev/null +++ b/src/displayapp/screens/settings/SettingHeartRate.cpp @@ -0,0 +1,85 @@ +#include "displayapp/screens/settings/SettingHeartRate.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Styles.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include +#include + +using namespace Pinetime::Applications::Screens; + +constexpr const char* SettingHeartRate::title; +constexpr const char* SettingHeartRate::symbol; + +namespace { + constexpr std::array intervalOptions = {{ + 0, + 30 * 1000, + 60 * 1000, + 5 * 60 * 1000, + 10 * 60 * 1000, + 30 * 60 * 1000, + }}; + + constexpr std::array options = {{ + {"Off", true}, + {"30s", true}, + {"1 min", true}, + {"5 min", true}, + {"10 min", true}, + {"30 min", true}, + {"", false}, + {"", false}, + }}; + + uint32_t GetDefaultOption(uint32_t currentInterval) { + for (size_t i = 0; i < intervalOptions.size(); i++) { + if (intervalOptions[i] == currentInterval) { + return i; + } + } + return 0; + } +} + +auto SettingHeartRate::CreateScreenList() const { + std::array()>, nScreens> screens; + for (size_t i = 0; i < screens.size(); i++) { + screens[i] = [this, i]() -> std::unique_ptr { + return CreateScreen(i); + }; + } + return screens; +} + +SettingHeartRate::SettingHeartRate(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settings) + : app {app}, settings {settings}, screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} { +} + +SettingHeartRate::~SettingHeartRate() { + lv_obj_clean(lv_scr_act()); +} + +bool SettingHeartRate::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr SettingHeartRate::CreateScreen(unsigned int screenNum) const { + std::array optionsOnThisScreen; + for (int i = 0; i < optionsPerScreen; i++) { + optionsOnThisScreen[i] = options[screenNum * optionsPerScreen + i]; + } + + return std::make_unique( + screenNum, + nScreens, + title, + symbol, + GetDefaultOption(settings.GetHeartRateBackgroundMeasurementInterval()), + [&settings = settings](uint32_t index) { + settings.SetHeartRateBackgroundMeasurementInterval(intervalOptions[index]); + settings.SaveSettings(); + }, + optionsOnThisScreen); +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingHeartRate.h b/src/displayapp/screens/settings/SettingHeartRate.h new file mode 100644 index 00000000..6b4ba581 --- /dev/null +++ b/src/displayapp/screens/settings/SettingHeartRate.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include "components/settings/Settings.h" +#include "displayapp/screens/ScreenList.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/CheckboxList.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingHeartRate : public Screen { + public: + SettingHeartRate(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settings); + ~SettingHeartRate() override; + + bool OnTouchEvent(TouchEvents event) override; + + private: + DisplayApp* app; + + auto CreateScreenList() const; + std::unique_ptr CreateScreen(unsigned int screenNum) const; + + Pinetime::Controllers::Settings& settings; + + static constexpr const char* title = "Backg. Interval"; + static constexpr const char* symbol = Symbols::heartBeat; + + static constexpr int optionsPerScreen = 4; + static constexpr int nScreens = 2; + + ScreenList screens; + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index a21b4ccd..0098b304 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -38,6 +38,7 @@ namespace Pinetime { {Symbols::home, "Watch face", Apps::SettingWatchFace}, {Symbols::shoe, "Steps", Apps::SettingSteps}, + {Symbols::heartBeat, "Heartrate", Apps::SettingHeartRate}, {Symbols::clock, "Date&Time", Apps::SettingSetDateTime}, {Symbols::cloudSunRain, "Weather", Apps::SettingWeatherFormat}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, @@ -49,9 +50,10 @@ namespace Pinetime { {Symbols::list, "About", Apps::SysInfo}, - // {Symbols::none, "None", Apps::None}, - // {Symbols::none, "None", Apps::None}, - // {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + // {Symbols::none, "None", Apps::None}, }}; diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 25437c42..e833dfe0 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -5,8 +5,10 @@ using namespace Pinetime::Applications; -HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) - : heartRateSensor {heartRateSensor}, controller {controller} { +HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, + Controllers::HeartRateController& controller, + Controllers::Settings& settings) + : heartRateSensor {heartRateSensor}, controller {controller}, settings {settings} { } void HeartRateTask::Start() { @@ -105,7 +107,12 @@ void HeartRateTask::StartWaiting() { } void HeartRateTask::HandleBackgroundWaiting() { - if (xTaskGetTickCount() - backgroundWaitingStart >= DURATION_BETWEEN_BACKGROUND_MEASUREMENTS) { + if (settings.GetHeartRateBackgroundMeasurementInterval() == 0) { + // stay waiting + return; + } + + if (xTaskGetTickCount() - backgroundWaitingStart >= settings.GetHeartRateBackgroundMeasurementInterval()) { state = States::BackgroundMeasuring; StartMeasurement(); } diff --git a/src/heartratetask/HeartRateTask.h b/src/heartratetask/HeartRateTask.h index d087d517..80b6abc8 100644 --- a/src/heartratetask/HeartRateTask.h +++ b/src/heartratetask/HeartRateTask.h @@ -3,9 +3,9 @@ #include #include #include +#include "components/settings/Settings.h" -#define DURATION_BETWEEN_BACKGROUND_MEASUREMENTS 5 * 60 * 1000 // 5 minutes assuming 1 Hz -#define DURATION_UNTIL_BACKGROUND_MEASURMENT_IS_STOPPED 30 * 1000 // 30 seconds assuming 1 Hz +#define DURATION_UNTIL_BACKGROUND_MEASURMENT_IS_STOPPED 30 * 1000 // 30 seconds assuming 1 Hz namespace Pinetime { namespace Drivers { @@ -22,7 +22,9 @@ namespace Pinetime { enum class Messages : uint8_t { GoToSleep, WakeUp, StartMeasurement, StopMeasurement }; enum class States { Idle, Running, Measuring, BackgroundWaiting, BackgroundMeasuring }; - explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller); + explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor, + Controllers::HeartRateController& controller, + Controllers::Settings& settings); void Start(); void Work(); void PushMessage(Messages msg); @@ -42,6 +44,7 @@ namespace Pinetime { States state = States::Running; Drivers::Hrs3300& heartRateSensor; Controllers::HeartRateController& controller; + Controllers::Settings& settings; Controllers::Ppg ppg; TickType_t backgroundWaitingStart = 0; TickType_t measurementStart = 0; diff --git a/src/main.cpp b/src/main.cpp index ee6a6d3d..6a957336 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,13 +93,13 @@ TimerHandle_t debounceChargeTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; -Pinetime::Controllers::HeartRateController heartRateController; -Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); - Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::Settings settingsController {fs}; Pinetime::Controllers::MotorController motorController {}; +Pinetime::Controllers::HeartRateController heartRateController; +Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController, settingsController); + Pinetime::Controllers::DateTime dateTimeController {settingsController}; Pinetime::Drivers::Watchdog watchdog; Pinetime::Controllers::NotificationManager notificationManager;