Skip to content

Commit

Permalink
add heart rate measurments in the background
Browse files Browse the repository at this point in the history
increase task delay when waiting in the background to 10s

remove background start timestamp reset on sleep

rebase on main

stop background after 30s of no data from the heart rate sensor

properly format using clang-format

add settings screen to choose heartrate measurement background

use different style for the heartrate settings and fix issues with settings file

use enum instead of uint32_t for heartrater interval setting

add heart rate measurments in the background

rebase on main

stop background after 30s of no data from the heart rate sensor

properly format using clang-format

add settings screen to choose heartrate measurement background

fix rebase mistakes

bump settings version, fix types

use pdMS_TO_TICKS correctly, format using clang-format

fix DisplayApp.cpp

fix issues after rebase on main

fix bug where settings open pair pin screen

fix settings screen

refactor heartrate task (switch cases, comments with explanation)

reduce RAM size

use switch case

keep measuring when transitioning to background

Co-authored-by: Simon Effenberg <[email protected]>

use switch case

remove unnecessary file

use better state names

integrate code review

use interval as interval, instead of wait time
  • Loading branch information
patricgruber committed Jan 3, 2025
1 parent d69cfcf commit a5feb1f
Show file tree
Hide file tree
Showing 11 changed files with 418 additions and 79 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/components/settings/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ Settings::Settings(Pinetime::Controllers::FS& fs) : fs {fs} {
}

void Settings::Init() {

// Load default settings from Flash
LoadSettingsFromFile();
}

void Settings::SaveSettings() {

// verify if is necessary to save
if (settingsChanged) {
SaveSettingsToFile();
Expand Down
26 changes: 25 additions & 1 deletion src/components/settings/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ namespace Pinetime {
int colorIndex = 0;
};

enum class HeartRateBackgroundMeasurementInterval : uint8_t {
Off,
Continuous,
FifteenSeconds,
ThirtySeconds,
OneMinute,
FiveMinutes,
TenMinutes,
ThirtyMinutes,
};

Settings(Pinetime::Controllers::FS& fs);

Settings(const Settings&) = delete;
Expand Down Expand Up @@ -298,10 +309,21 @@ namespace Pinetime {
return bleRadioEnabled;
};

HeartRateBackgroundMeasurementInterval GetHeartRateBackgroundMeasurementInterval() const {
return settings.heartRateBackgroundMeasurementInterval;
}

void SetHeartRateBackgroundMeasurementInterval(HeartRateBackgroundMeasurementInterval newHeartRateBackgroundMeasurementInterval) {
if (newHeartRateBackgroundMeasurementInterval != settings.heartRateBackgroundMeasurementInterval) {
settingsChanged = true;
}
settings.heartRateBackgroundMeasurementInterval = newHeartRateBackgroundMeasurementInterval;
}

private:
Pinetime::Controllers::FS& fs;

static constexpr uint32_t settingsVersion = 0x0008;
static constexpr uint32_t settingsVersion = 0x0009;

struct SettingsData {
uint32_t version = settingsVersion;
Expand All @@ -325,6 +347,8 @@ namespace Pinetime {
uint16_t shakeWakeThreshold = 150;

Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;

HeartRateBackgroundMeasurementInterval heartRateBackgroundMeasurementInterval = HeartRateBackgroundMeasurementInterval::Off;
};

SettingsData settings;
Expand Down
4 changes: 4 additions & 0 deletions src/displayapp/DisplayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -603,6 +604,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>(settingsController);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
break;
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/Apps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Pinetime {
SettingWatchFace,
SettingTimeFormat,
SettingWeatherFormat,
SettingHeartRate,
SettingDisplay,
SettingWakeUp,
SettingSteps,
Expand Down
75 changes: 75 additions & 0 deletions src/displayapp/screens/settings/SettingHeartRate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "displayapp/screens/settings/SettingHeartRate.h"
#include <lvgl/lvgl.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;

namespace {
void event_handler(lv_obj_t* obj, lv_event_t event) {
auto* screen = static_cast<SettingHeartRate*>(obj->user_data);
screen->UpdateSelected(obj, event);
}
}

constexpr std::array<Option, 8> SettingHeartRate::options;

SettingHeartRate::SettingHeartRate(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {

lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);

lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);

lv_obj_set_pos(container1, 10, 60);
lv_obj_set_width(container1, LV_HOR_RES - 20);
lv_obj_set_height(container1, LV_VER_RES - 50);
lv_cont_set_layout(container1, LV_LAYOUT_PRETTY_TOP);

lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text_static(title, "Backg. Interval");
lv_label_set_text(title, "Backg. Interval");
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15);

lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_label_set_text_static(icon, Symbols::heartBeat);
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);

for (unsigned int i = 0; i < options.size(); i++) {
cbOption[i] = lv_checkbox_create(container1, nullptr);
lv_checkbox_set_text(cbOption[i], options[i].name);
cbOption[i]->user_data = this;
lv_obj_set_event_cb(cbOption[i], event_handler);
SetRadioButtonStyle(cbOption[i]);

if (settingsController.GetHeartRateBackgroundMeasurementInterval() == options[i].interval) {
lv_checkbox_set_checked(cbOption[i], true);
}
}
}

SettingHeartRate::~SettingHeartRate() {
lv_obj_clean(lv_scr_act());
settingsController.SaveSettings();
}

void SettingHeartRate::UpdateSelected(lv_obj_t* object, lv_event_t event) {
if (event == LV_EVENT_CLICKED) {
for (unsigned int i = 0; i < options.size(); i++) {
if (object == cbOption[i]) {
lv_checkbox_set_checked(cbOption[i], true);
settingsController.SetHeartRateBackgroundMeasurementInterval(options[i].interval);
} else {
lv_checkbox_set_checked(cbOption[i], false);
}
}
}
}
47 changes: 47 additions & 0 deletions src/displayapp/screens/settings/SettingHeartRate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#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 {

struct Option {
const Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval interval;
const char* name;
};

class SettingHeartRate : public Screen {
public:
SettingHeartRate(Pinetime::Controllers::Settings& settings);
~SettingHeartRate() override;

void UpdateSelected(lv_obj_t* object, lv_event_t event);

private:
Pinetime::Controllers::Settings& settingsController;

static constexpr std::array<Option, 8> options = {{
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::Off, " Off"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::Continuous, "Cont"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::FifteenSeconds, " 15s"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::ThirtySeconds, " 30s"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::OneMinute, " 1m"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::FiveMinutes, " 5m"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::TenMinutes, " 10m"},
{Pinetime::Controllers::Settings::HeartRateBackgroundMeasurementInterval::ThirtyMinutes, " 30m"},
}};

lv_obj_t* cbOption[options.size()];
};
}
}
}
15 changes: 6 additions & 9 deletions src/displayapp/screens/settings/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,19 @@ namespace Pinetime {
{Symbols::home, "Watch face", Apps::SettingWatchFace},

{Symbols::shoe, "Steps", Apps::SettingSteps},
{Symbols::clock, "Date & Time", Apps::SettingSetDateTime},
{Symbols::heartBeat, "Heartrate", Apps::SettingHeartRate},
{Symbols::clock, "Date&Time", Apps::SettingSetDateTime},
{Symbols::cloudSunRain, "Weather", Apps::SettingWeatherFormat},
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},

{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},
{Symbols::clock, "Chimes", Apps::SettingChimes},
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
{Symbols::check, "Firmware", Apps::FirmwareValidation},
{Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},

{Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},
{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},
}};
ScreenList<nScreens> screens;
};
Expand Down
Loading

0 comments on commit a5feb1f

Please sign in to comment.