Skip to content

Commit 5737b95

Browse files
committed
split state machine
1 parent c53abd4 commit 5737b95

2 files changed

Lines changed: 46 additions & 152 deletions

File tree

src/heartratetask/HeartRateTask.cpp

Lines changed: 37 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55

66
using namespace Pinetime::Applications;
77

8-
TickType_t CurrentTaskDelay(HeartRateTask::States state, TickType_t ppgDeltaTms) {
9-
switch (state) {
10-
case HeartRateTask::States::ScreenOnAndMeasuring:
11-
case HeartRateTask::States::ScreenOffAndMeasuring:
12-
return ppgDeltaTms;
13-
case HeartRateTask::States::ScreenOffAndWaiting:
14-
return pdMS_TO_TICKS(1000);
15-
default:
16-
return portMAX_DELAY;
8+
TickType_t CurrentTaskDelay(bool isMeasurmentActivated, bool isScreenOn, bool isBackgroundMeasuring, TickType_t ppgDeltaTms) {
9+
if (!isMeasurmentActivated) {
10+
return portMAX_DELAY;
1711
}
12+
13+
if (isScreenOn || isBackgroundMeasuring) {
14+
return ppgDeltaTms;
15+
}
16+
17+
return pdMS_TO_TICKS(100);
1818
}
1919

2020
HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor,
@@ -41,7 +41,7 @@ void HeartRateTask::Work() {
4141
int lastBpm = 0;
4242

4343
while (true) {
44-
TickType_t delay = CurrentTaskDelay(state, ppg.deltaTms);
44+
TickType_t delay = CurrentTaskDelay(isMeasurementActivated, isScreenOn, isBackgroundMeasuring, ppg.deltaTms);
4545
Messages msg;
4646

4747
if (xQueueReceive(messageQueue, &msg, delay) == pdTRUE) {
@@ -61,18 +61,14 @@ void HeartRateTask::Work() {
6161
}
6262
}
6363

64-
switch (state) {
65-
case States::ScreenOffAndWaiting:
66-
HandleBackgroundWaiting();
67-
break;
68-
case States::ScreenOffAndMeasuring:
69-
case States::ScreenOnAndMeasuring:
70-
HandleSensorData(&lastBpm);
71-
break;
72-
case States::ScreenOffAndStopped:
73-
case States::ScreenOnAndStopped:
74-
// nothing to do -> ignore
75-
break;
64+
if (!isMeasurementActivated) {
65+
continue;
66+
}
67+
68+
if (isScreenOn || isBackgroundMeasuring) {
69+
HandleSensorData(&lastBpm);
70+
} else if (!isBackgroundMeasuring) {
71+
HandleWaiting();
7672
}
7773
}
7874
}
@@ -83,98 +79,49 @@ void HeartRateTask::PushMessage(HeartRateTask::Messages msg) {
8379
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
8480
}
8581

86-
void HeartRateTask::StartMeasurement() {
82+
void HeartRateTask::StartSensor() {
8783
heartRateSensor.Enable();
8884
ppg.Reset(true);
8985
vTaskDelay(100);
90-
91-
if (state == States::ScreenOffAndMeasuring) {
92-
// only set the start timestamp when the screen is off
93-
measurementStart = xTaskGetTickCount();
94-
}
9586
}
9687

97-
void HeartRateTask::StopMeasurement() {
88+
void HeartRateTask::StopSensor() {
9889
heartRateSensor.Disable();
9990
ppg.Reset(true);
10091
vTaskDelay(100);
10192
}
10293

10394
void HeartRateTask::HandleGoToSleep() {
104-
switch (state) {
105-
case States::ScreenOnAndStopped:
106-
state = States::ScreenOffAndStopped;
107-
break;
108-
case States::ScreenOnAndMeasuring:
109-
state = States::ScreenOffAndWaiting;
110-
StopMeasurement();
111-
break;
112-
case States::ScreenOffAndStopped:
113-
case States::ScreenOffAndWaiting:
114-
case States::ScreenOffAndMeasuring:
115-
// shouldn't happen -> ignore
116-
break;
117-
}
95+
isScreenOn = false;
11896
}
11997

12098
void HeartRateTask::HandleWakeUp() {
121-
switch (state) {
122-
case States::ScreenOffAndStopped:
123-
state = States::ScreenOnAndStopped;
124-
break;
125-
case States::ScreenOffAndMeasuring:
126-
state = States::ScreenOnAndMeasuring;
127-
break;
128-
case States::ScreenOffAndWaiting:
129-
state = States::ScreenOnAndMeasuring;
130-
StartMeasurement();
131-
break;
132-
case States::ScreenOnAndStopped:
133-
case States::ScreenOnAndMeasuring:
134-
// shouldn't happen -> ignore
135-
break;
99+
if (isMeasurementActivated) {
100+
StartSensor();
136101
}
102+
isScreenOn = true;
137103
}
138104

139105
void HeartRateTask::HandleStartMeasurement(int* lastBpm) {
140-
switch (state) {
141-
case States::ScreenOnAndStopped:
142-
state = States::ScreenOnAndMeasuring;
143-
*lastBpm = 0;
144-
StartMeasurement();
145-
break;
146-
case States::ScreenOffAndStopped:
147-
case States::ScreenOnAndMeasuring:
148-
case States::ScreenOffAndMeasuring:
149-
case States::ScreenOffAndWaiting:
150-
// shouldn't happen -> ignore
151-
break;
152-
}
106+
isMeasurementActivated = true;
107+
*lastBpm = 0;
108+
StartSensor();
153109
}
154110

155111
void HeartRateTask::HandleStopMeasurement() {
156-
switch (state) {
157-
case States::ScreenOnAndMeasuring:
158-
state = States::ScreenOnAndStopped;
159-
StopMeasurement();
160-
break;
161-
case States::ScreenOffAndMeasuring:
162-
case States::ScreenOffAndWaiting:
163-
case States::ScreenOnAndStopped:
164-
case States::ScreenOffAndStopped:
165-
// shouldn't happen -> ignore
166-
break;
167-
}
112+
isMeasurementActivated = false;
113+
StopSensor();
168114
}
169115

170-
void HeartRateTask::HandleBackgroundWaiting() {
171-
if (!IsBackgroundMeasurementActivated()) {
116+
void HeartRateTask::HandleWaiting() {
117+
if (!IsBackgroundMeasurementActivated() || !isMeasurementActivated) {
118+
StopSensor();
172119
return;
173120
}
174121

175122
if (ShouldStartBackgroundMeasuring()) {
176-
state = States::ScreenOffAndMeasuring;
177-
StartMeasurement();
123+
isBackgroundMeasuring = true;
124+
StartSensor();
178125
}
179126
}
180127

@@ -204,14 +151,10 @@ void HeartRateTask::HandleSensorData(int* lastBpm) {
204151
controller.Update(Controllers::HeartRateController::States::Running, bpm);
205152
}
206153

207-
if (state == States::ScreenOnAndMeasuring || IsContinuousModeActivated()) {
154+
if (isScreenOn || IsContinuousModeActivated()) {
208155
return;
209156
}
210157

211-
// state == States::ScreenOffAndMeasuring
212-
// (because state != ScreenOnAndMeasuring and the only state that enables measuring is ScreenOffAndMeasuring)
213-
// !IsContinuousModeActivated()
214-
215158
if (ShouldStartBackgroundMeasuring()) {
216159
// This doesn't change the state but resets the measurment timer, which basically starts the next measurment without resetting the
217160
// sensor. This is basically a fall back to continuous mode, when measurments take too long.
@@ -222,8 +165,8 @@ void HeartRateTask::HandleSensorData(int* lastBpm) {
222165
bool noDataWithinTimeLimit = bpm == 0 && ShoudStopTryingToGetData();
223166
bool dataWithinTimeLimit = bpm != 0;
224167
if (dataWithinTimeLimit || noDataWithinTimeLimit) {
225-
state = States::ScreenOffAndWaiting;
226-
StopMeasurement();
168+
isBackgroundMeasuring = false;
169+
StopSensor();
227170
}
228171
}
229172

src/heartratetask/HeartRateTask.h

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,58 +7,6 @@
77

88
#define DURATION_UNTIL_BACKGROUND_MEASUREMENT_IS_STOPPED pdMS_TO_TICKS(30 * 1000)
99

10-
/*
11-
*** Background Measurement deactivated ***
12-
13-
14-
15-
┌─────────────────────────┐ ┌─────────────────────────┐
16-
│ ├───StartMeasurement───►│ │
17-
│ ScreenOnAndStopped │ │ ScreenOnAndMeasuring │
18-
│ │◄──StopMeasurement │ │
19-
└──▲────────────────┬─────┘ └──▲──────────────────┬───┘
20-
│ │ │ │
21-
WakeUp GoToSleep WakeUp GoToSleep
22-
│ │ │ │
23-
┌──┴────────────────▼─────┐ ┌──┴──────────────────▼───┐
24-
│ │ │ │
25-
│ ScreenOffAndStopped │ │ ScreenOffAndWaiting │
26-
│ │ │ │
27-
└─────────────────────────┘ └─────────────────────────┘
28-
29-
30-
31-
32-
33-
*** Background Measurement activated ***
34-
35-
36-
37-
┌─────────────────────────┐ ┌─────────────────────────┐
38-
│ ├───StartMeasurement───►│ │
39-
│ ScreenOnAndStopped │ │ ScreenOnAndMeasuring │
40-
│ │◄──StopMeasurement │ │
41-
└──▲────────────────┬─────┘ └──▲──────────────────┬───┘
42-
│ │ ┌───────┘ │
43-
WakeUp GoToSleep │ WakeUp GoToSleep
44-
│ │ │ │ │
45-
┌──┴────────────────▼─────┐ │ ┌──┴──────────────────▼───┐
46-
│ │ │ │ │
47-
│ ScreenOffAndStopped │ │ │ ScreenOffAndWating │
48-
│ │ │ │ │
49-
└─────────────────────────┘ │ └───┬──────────────────▲──┘
50-
│ │ │
51-
│ Waited Got sensor
52-
│ interval data
53-
│ time │
54-
│ │ │
55-
WakeUp ┌───▼──────────────────┴──┐
56-
│ │ │
57-
└────┤ ScreenOffAndMeasuring │
58-
│ │
59-
└─────────────────────────┘
60-
*/
61-
6210
namespace Pinetime {
6311
namespace Drivers {
6412
class Hrs3300;
@@ -73,8 +21,6 @@ namespace Pinetime {
7321
public:
7422
enum class Messages : uint8_t { GoToSleep, WakeUp, StartMeasurement, StopMeasurement };
7523

76-
enum class States { ScreenOnAndStopped, ScreenOnAndMeasuring, ScreenOffAndStopped, ScreenOffAndWaiting, ScreenOffAndMeasuring };
77-
7824
explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor,
7925
Controllers::HeartRateController& controller,
8026
Controllers::Settings& settings);
@@ -84,15 +30,15 @@ namespace Pinetime {
8430

8531
private:
8632
static void Process(void* instance);
87-
void StartMeasurement();
88-
void StopMeasurement();
33+
void StartSensor();
34+
void StopSensor();
8935

9036
void HandleGoToSleep();
9137
void HandleWakeUp();
9238
void HandleStartMeasurement(int* lastBpm);
9339
void HandleStopMeasurement();
9440

95-
void HandleBackgroundWaiting();
41+
void HandleWaiting();
9642
void HandleSensorData(int* lastBpm);
9743

9844
TickType_t GetBackgroundIntervalInTicks();
@@ -105,11 +51,16 @@ namespace Pinetime {
10551

10652
TaskHandle_t taskHandle;
10753
QueueHandle_t messageQueue;
108-
States state = States::ScreenOnAndStopped;
54+
55+
bool isBackgroundMeasuring = false;
56+
bool isScreenOn = true;
57+
bool isMeasurementActivated = false;
58+
10959
Drivers::Hrs3300& heartRateSensor;
11060
Controllers::HeartRateController& controller;
11161
Controllers::Settings& settings;
11262
Controllers::Ppg ppg;
63+
11364
TickType_t measurementStart = 0;
11465
};
11566

0 commit comments

Comments
 (0)