Skip to content

Commit 5be0e14

Browse files
committed
add heart rate measurments in the background
1 parent 616aa91 commit 5be0e14

3 files changed

Lines changed: 79 additions & 35 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
22

33
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release")
44

5-
project(pinetime VERSION 1.11.0 LANGUAGES C CXX ASM)
5+
project(pinetime VERSION 1.11.1 LANGUAGES C CXX ASM)
66

77
set(CMAKE_C_STANDARD 99)
88
set(CMAKE_CXX_STANDARD 14)

src/heartratetask/HeartRateTask.cpp

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,62 +24,59 @@ void HeartRateTask::Process(void* instance) {
2424
}
2525

2626
void HeartRateTask::Work() {
27-
int lastBpm = 0;
28-
while (true) {
29-
auto delay = portMAX_DELAY;
30-
if (state == States::Running) {
31-
if (measurementStarted) {
32-
delay = 40;
33-
} else {
34-
delay = 100;
35-
}
36-
} else {
37-
delay = portMAX_DELAY;
38-
}
27+
lastBpm = 0;
3928

29+
while (true) {
30+
auto delay = CurrentTaskDelay();
4031
Messages msg;
32+
4133
if (xQueueReceive(messageQueue, &msg, delay) == pdTRUE) {
4234
switch (msg) {
4335
case Messages::GoToSleep:
44-
StopMeasurement();
45-
state = States::Idle;
36+
if (state == States::Running) {
37+
state = States::Idle;
38+
} else if (state == States::Measuring) {
39+
state = States::BackgroundWaiting;
40+
backgroundMeasurementWaitingStart = xTaskGetTickCount();
41+
StopMeasurement();
42+
}
4643
break;
4744
case Messages::WakeUp:
48-
state = States::Running;
49-
if (measurementStarted) {
50-
lastBpm = 0;
45+
if (state == States::Idle) {
46+
state = States::Running;
47+
} else if (state == States::BackgroundMeasuring) {
48+
state = States::Measuring;
49+
} else if (state == States::BackgroundWaiting) {
50+
state = States::Measuring;
5151
StartMeasurement();
5252
}
5353
break;
5454
case Messages::StartMeasurement:
55-
if (measurementStarted) {
55+
if (state == States::Measuring || state == States::BackgroundMeasuring) {
5656
break;
5757
}
58+
state = States::Measuring;
5859
lastBpm = 0;
5960
StartMeasurement();
60-
measurementStarted = true;
6161
break;
6262
case Messages::StopMeasurement:
63-
if (!measurementStarted) {
63+
if (state == States::Running || state == States::Idle) {
6464
break;
6565
}
66+
if (state == States::Measuring) {
67+
state = States::Running;
68+
} else if (state == States::BackgroundMeasuring) {
69+
state = States::Idle;
70+
}
6671
StopMeasurement();
67-
measurementStarted = false;
6872
break;
6973
}
7074
}
7175

72-
if (measurementStarted) {
73-
ppg.Preprocess(static_cast<float>(heartRateSensor.ReadHrs()));
74-
auto bpm = ppg.HeartRate();
75-
76-
if (lastBpm == 0 && bpm == 0) {
77-
controller.Update(Controllers::HeartRateController::States::NotEnoughData, 0);
78-
}
79-
if (bpm != 0) {
80-
lastBpm = bpm;
81-
controller.Update(Controllers::HeartRateController::States::Running, lastBpm);
82-
}
76+
if (state == States::BackgroundWaiting) {
77+
HandleBackgroundWaiting();
78+
} else if (state == States::BackgroundMeasuring || state == States::Measuring) {
79+
HandleSensorData();
8380
}
8481
}
8582
}
@@ -103,3 +100,43 @@ void HeartRateTask::StopMeasurement() {
103100
heartRateSensor.Disable();
104101
vTaskDelay(100);
105102
}
103+
104+
void HeartRateTask::HandleBackgroundWaiting() {
105+
if (xTaskGetTickCount() - backgroundMeasurementWaitingStart >= DURATION_BETWEEN_BACKGROUND_MEASUREMENTS) {
106+
state = States::BackgroundMeasuring;
107+
StartMeasurement();
108+
}
109+
}
110+
111+
void HeartRateTask::HandleSensorData() {
112+
ppg.Preprocess(static_cast<float>(heartRateSensor.ReadHrs()));
113+
auto bpm = ppg.HeartRate();
114+
115+
if (lastBpm == 0 && bpm == 0) {
116+
controller.Update(Controllers::HeartRateController::States::NotEnoughData, 0);
117+
}
118+
119+
if (bpm != 0) {
120+
lastBpm = bpm;
121+
controller.Update(Controllers::HeartRateController::States::Running, lastBpm);
122+
if (state == States::BackgroundMeasuring) {
123+
StopMeasurement();
124+
state = States::BackgroundWaiting;
125+
backgroundMeasurementWaitingStart = xTaskGetTickCount();
126+
}
127+
}
128+
}
129+
130+
int HeartRateTask::CurrentTaskDelay() {
131+
switch (state) {
132+
case States::Measuring:
133+
case States::BackgroundMeasuring:
134+
return 50;
135+
case States::Running:
136+
return 100;
137+
case States::BackgroundWaiting:
138+
return 500;
139+
default:
140+
return portMAX_DELAY;
141+
}
142+
}

src/heartratetask/HeartRateTask.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <queue.h>
55
#include <components/heartrate/Ppg.h>
66

7+
#define DURATION_BETWEEN_BACKGROUND_MEASUREMENTS 5 * 60 * 1000 // 5 Minutes assuming 1 Hz
8+
79
namespace Pinetime {
810
namespace Drivers {
911
class Hrs3300;
@@ -17,7 +19,7 @@ namespace Pinetime {
1719
class HeartRateTask {
1820
public:
1921
enum class Messages : uint8_t { GoToSleep, WakeUp, StartMeasurement, StopMeasurement };
20-
enum class States { Idle, Running };
22+
enum class States { Idle, Running, Measuring, BackgroundWaiting, BackgroundMeasuring };
2123

2224
explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller);
2325
void Start();
@@ -29,13 +31,18 @@ namespace Pinetime {
2931
void StartMeasurement();
3032
void StopMeasurement();
3133

34+
void HandleBackgroundWaiting();
35+
void HandleSensorData();
36+
int CurrentTaskDelay();
37+
3238
TaskHandle_t taskHandle;
3339
QueueHandle_t messageQueue;
3440
States state = States::Running;
3541
Drivers::Hrs3300& heartRateSensor;
3642
Controllers::HeartRateController& controller;
3743
Controllers::Ppg ppg;
38-
bool measurementStarted = false;
44+
int lastBpm = 0;
45+
TickType_t backgroundMeasurementWaitingStart;
3946
};
4047

4148
}

0 commit comments

Comments
 (0)