diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 2f689b9b9f..5f6219f2fe 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -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); @@ -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(heartRateSensor.ReadHrs())); @@ -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; + } + } } } } diff --git a/src/heartratetask/HeartRateTask.h b/src/heartratetask/HeartRateTask.h index 0796dc74dd..5a6a57be44 100644 --- a/src/heartratetask/HeartRateTask.h +++ b/src/heartratetask/HeartRateTask.h @@ -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; }; }