Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 53 additions & 11 deletions src/heartratetask/HeartRateTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
using namespace Pinetime::Applications;

HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller)
: heartRateSensor {heartRateSensor}, controller {controller}, ppg{} {
: heartRateSensor {heartRateSensor}, controller {controller}, ppg {} {
}

void HeartRateTask::Start() {
messageQueue = xQueueCreate(10, 1);
controller.SetHeartRateTask(this);
lastRegularMeasurementTick = xTaskGetTickCount();

if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
Expand All @@ -27,42 +28,73 @@ void HeartRateTask::Work() {
while (true) {
Messages msg;
uint32_t delay;
if (state == States::Running) {
if (measurementStarted)
if (state == States::Running || regularMeasurementStarted) {
if (measurementStarted) {
delay = 40;
else
} else {
delay = 100;
} else
}
} else {
delay = portMAX_DELAY;

}
if (xQueueReceive(messageQueue, &msg, delay)) {
switch (msg) {
case Messages::GoToSleep:
// we don't want the regular measurement to stop if the watch goes to sleep, although we do want it to stop if it was
// started by a user, to save power
if (regularMeasurementStarted) {
break;
}
StopMeasurement();
state = States::Idle;
break;
case Messages::WakeUp:
state = States::Running;
if (measurementStarted) {
// if the user started a measurement it was paused by GoToSleep so needs to be started again. If there is a regular Measurement
// it was never stopped and must not be started again (as that would all currently collected data)
if (userStartedMeasurement && !regularMeasurementStarted) {
lastBpm = 0;
StartMeasurement();
}
break;
case Messages::StartMeasurement:
if (measurementStarted)
if (measurementStarted) {
// the user started a measurement
userStartedMeasurement = true;
break;
}
lastBpm = 0;
StartMeasurement();
measurementStarted = true;
break;
case Messages::StopMeasurement:
if (!measurementStarted)
break;
StopMeasurement();
if (measurementStarted) {
StopMeasurement();
}

// if the user stops a measurement manually the regular measurement is cancelled as well
// keeping the sensor on even after pressing the stop button could be confusing (although it turns on a tenth of a second later
// again anyway)
measurementStarted = false;
userStartedMeasurement = false;
regularMeasurementStarted = false;
break;
}
}
// compare if a Measurement should be started
if (
// if the variable is set to zero the feature is disabled and no measurement is supposed to be started
regularMeasurmentWait != 0 &&
// check if enough seconds have passed since the last measurement
((xTaskGetTickCount() - lastRegularMeasurementTick) / configTICK_RATE_HZ) > regularMeasurmentWait && !regularMeasurementStarted) {
regularMeasurementStarted = true;
// if there currently is a measurement it must not be started again, as that would invalidate all currently collected data
if (!measurementStarted) {
lastBpm = 0;
StartMeasurement();
measurementStarted = true;
}
}

if (measurementStarted) {
ppg.Preprocess(static_cast<float>(heartRateSensor.ReadHrs()));
Expand All @@ -72,7 +104,17 @@ void HeartRateTask::Work() {
controller.Update(Controllers::HeartRateController::States::NotEnoughData, 0);
if (bpm != 0) {
lastBpm = bpm;
// this method handles a ble service as well, so nothing has to be done with the collected heart rate
controller.Update(Controllers::HeartRateController::States::Running, lastBpm);
if (regularMeasurementStarted) {
regularMeasurementStarted = false;
lastRegularMeasurementTick = xTaskGetTickCount();
// we only want to turn the sensor off, if the user isn't currently manually measuring the heart rate
if (!userStartedMeasurement) {
StopMeasurement();
measurementStarted = false;
}
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/heartratetask/HeartRateTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@ namespace Pinetime {
Drivers::Hrs3300& heartRateSensor;
Controllers::HeartRateController& controller;
Controllers::Ppg ppg;
// did the user manually start a measurement?
bool userStartedMeasurement = false;
// is there any measurement started?
bool measurementStarted = false;
// is there a regular measurement running atm?
bool regularMeasurementStarted = false;
// last time a measurement was done (in tickks)
uint32_t lastRegularMeasurementTick;
// time to wait between measurements (in seconds)
const uint8_t regularMeasurmentWait = 60;
};

}
Expand Down