add settings screen to choose heartrate measurement background

This commit is contained in:
Patric Gruber 2023-08-25 02:10:45 +02:00
parent 5dbe1f77b5
commit 27ee1eb2c8
9 changed files with 169 additions and 12 deletions

View file

@ -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

View file

@ -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;

View file

@ -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<Screens::SettingWakeUp>(settingsController);
break;
case Apps::SettingHeartRate:
currentScreen = std::make_unique<Screens::SettingHeartRate>(this, settingsController);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
break;

View file

@ -0,0 +1,85 @@
#include "displayapp/screens/settings/SettingHeartRate.h"
#include <lvgl/lvgl.h>
#include "displayapp/DisplayApp.h"
#include "displayapp/screens/Styles.h"
#include "displayapp/screens/Screen.h"
#include "displayapp/screens/Symbols.h"
#include <array>
#include <algorithm>
using namespace Pinetime::Applications::Screens;
constexpr const char* SettingHeartRate::title;
constexpr const char* SettingHeartRate::symbol;
namespace {
constexpr std::array<uint32_t, 6> intervalOptions = {{
0,
30 * 1000,
60 * 1000,
5 * 60 * 1000,
10 * 60 * 1000,
30 * 60 * 1000,
}};
constexpr std::array<CheckboxList::Item, 8> 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<std::function<std::unique_ptr<Screen>()>, nScreens> screens;
for (size_t i = 0; i < screens.size(); i++) {
screens[i] = [this, i]() -> std::unique_ptr<Screen> {
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<Screen> SettingHeartRate::CreateScreen(unsigned int screenNum) const {
std::array<Screens::CheckboxList::Item, optionsPerScreen> optionsOnThisScreen;
for (int i = 0; i < optionsPerScreen; i++) {
optionsOnThisScreen[i] = options[screenNum * optionsPerScreen + i];
}
return std::make_unique<Screens::CheckboxList>(
screenNum,
nScreens,
title,
symbol,
GetDefaultOption(settings.GetHeartRateBackgroundMeasurementInterval()),
[&settings = settings](uint32_t index) {
settings.SetHeartRateBackgroundMeasurementInterval(intervalOptions[index]);
settings.SaveSettings();
},
optionsOnThisScreen);
}

View file

@ -0,0 +1,42 @@
#pragma once
#include <cstdint>
#include <lvgl/lvgl.h>
#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<Screen> 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<nScreens> screens;
};
}
}
}

View file

@ -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},
}};

View file

@ -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();
}

View file

@ -3,9 +3,9 @@
#include <task.h>
#include <queue.h>
#include <components/heartrate/Ppg.h>
#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;

View file

@ -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;