9.4 KiB
title | description | guide_group | order | related_docs | related_examples | platform_choice | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Heart Rate Monitor | Information on using the HealthService API to obtain information from the Heart Rate Monitor. | events-and-services | 6 |
|
|
true |
The Pebble Time 2 and Pebble 2 (excluding SE model)
{% guide_link tools-and-resources/hardware-information "devices" %} include a
heart rate monitor. This guide will demonstrate how to use the HealthService
API to retrieve information about the user's current, and historical heart
rates.
If you aren't already familiar with the HealthService
, we recommended that
you read the {% guide_link events-and-services/health "Health guide" %}
before proceeding.
Enable Health Data
{
...
"pebble": {
...
"capabilities": [ "health" ],
...
}
}
{% endmarkdown %}
^CP^ Before your application is able to access heart rate information, you will
need to enable the USES HEALTH
option in your project settings on
[CloudPebble]({{ site.data.links.cloudpebble }}).
Data Quality
Heart rate sensors aren't perfect, and their readings can be affected by improper positioning, environmental factors and excessive movement. The raw data from the HRM sensor contains a metric to indicate the quality of the readings it receives.
The HRM API provides a raw BPM reading (HealthMetricHeartRateRawBPM
) and a
filtered reading (HealthMetricHeartRateBPM
). This filtered value minimizes
the effect of hand movement and improper sensor placement, by removing the bad
quality readings. This filtered data makes it easy for developers to integrate
in their applications, without needing to filter the data themselves.
Obtaining the Current Heart Rate
To obtain the current heart rate, you should first check whether the
HealthMetricHeartRateBPM
is available by using the
health_service_metric_accessible
method.
Then you can obtain the current heart rate using the
health_service_peek_current_value
method:
HealthServiceAccessibilityMask hr = health_service_metric_accessible(HealthMetricHeartRateBPM, time(NULL), time(NULL));
if (hr & HealthServiceAccessibilityMaskAvailable) {
HealthValue val = health_service_peek_current_value(HealthMetricHeartRateBPM);
if(val > 0) {
// Display HRM value
static char s_hrm_buffer[8];
snprintf(s_hrm_buffer, sizeof(s_hrm_buffer), "%lu BPM", (uint32_t)val);
text_layer_set_text(s_hrm_layer, s_hrm_buffer);
}
}
Note
due to the sampling rate and our data filters, this value could be several minutes old. Use
HealthMetricHeartRateRawBPM
for the raw, unfiltered value.
Subscribing to Heart Rate Updates
The user's heart rate can also be monitored via an event subscription, in a
similar way to the other health metrics. If you wanted your watchface to update
the displayed heart rate every time the HRM takes a new reading, you could use
the health_service_events_subscribe
method.
static void prv_on_health_data(HealthEventType type, void *context) {
// If the update was from the Heart Rate Monitor, query it
if (type == HealthEventHeartRateUpdate) {
HealthValue value = health_service_peek_current_value(HealthMetricHeartRateBPM);
// Display the heart rate
}
}
static void prv_init(void) {
// Subscribe to health event handler
health_service_events_subscribe(prv_on_health_data, NULL);
// ...
}
Note
sensor sampling rate.
Heart Rate Sample Periods
The default sample period is 10 minutes, but the system automatically controls the HRM sample rate based on the level of user activity. It increases the sampling rate during intense activity and reduces it again during inactivity. This aims to provide the optimal battery usage.
Battery Considerations
Like all active sensors, accelerometer, backlight etc, the HRM sensor will have a negative affect on battery life. It's important to consider this when using the APIs within your application.
By default the system will automatically control the heart rate sampling period for the optimal balance between update frequency and battery usage. In addition, the APIs have been designed to allow developers to retrieve values for the most common use cases with minimal impact on battery life.
Altering the Sampling Period
Developers can request a specific sampling rate using the
health_service_set_heart_rate_sample_period
method. The system will use this
value as a suggestion, but does not guarantee that value will be used. The
actual sampling period may be greater or less due to other apps that require
input from the sensor, or data quality issues.
The shortest period you can currently specify is 1
second, and the longest
period you can specify is 600
seconds (10 minutes).
In this example, we will sample the heart rate monitor every second:
// Set the heart rate monitor to sample every second
bool success = health_service_set_heart_rate_sample_period(1);
Note
only that the sensor will capture more samples.
Resetting the Sampling Period
Developers must reset the heart rate sampling period when their application exits. Failing to do so may result in the heart rate monitor continuing at the increased rate for a period of time, even after your application closes. This is fundamentally different to other Pebble sensors and was designed so that applications which a reliant upon high sampling rates can be temporarily interupted for notifications, or music, without affecting the sensor data.
// Reset the heart rate sampling period to automatic
health_service_set_heart_rate_sample_period(0);
Obtaining Historical Data
If your application is using heart rate information, it may also want to obtain
historical data to compare it against. In this section we'll look at how you can
use the health_service_aggregate
functions to obtain relevant historic data.
Before requesting historic/aggregate data for a specific time period, you
should ensure that it is available using the
health_service_metric_accessible
method.
Then we'll use the health_service_aggregate_averaged
method to
obtain the average daily heart rate over the last 7 days.
// Obtain history for last 7 days
time_t end_time = time(NULL);
time_t start_time = end_time - (7 * SECONDS_PER_DAY);
HealthServiceAccessibilityMask hr = health_service_metric_accessible(HealthMetricHeartRateBPM, start_time, end_time);
if (hr & HealthServiceAccessibilityMaskAvailable) {
uint32_t weekly_avg_hr = health_service_aggregate_averaged(HealthMetricHeartRateBPM,
start_time, end_time,
HealthAggregationAvg, HealthServiceTimeScopeDaily);
}
You can also query the average min
and max
heart rates, but only within the
past two hours (maximum). This limitation is due to very limited storage
capacity on the device, but the implementation may change in the future.
// Obtain history for last 1 hour
time_t end_time = time(NULL);
time_t start_time = end_time - SECONDS_PER_HOUR;
HealthServiceAccessibilityMask hr = health_service_metric_accessible(HealthMetricHeartRateBPM, start_time, end_time);
if (hr & HealthServiceAccessibilityMaskAvailable) {
uint32_t min_hr = health_service_aggregate_averaged(HealthMetricHeartRateBPM,
start_time, end_time,
HealthAggregationMin, HealthServiceTimeScopeOnce);
uint32_t max_hr = health_service_aggregate_averaged(HealthMetricHeartRateBPM,
start_time, end_time,
HealthAggregationMax, HealthServiceTimeScopeOnce);
}
Read Per-Minute History
The HealthMinuteData
structure contains multiple types of activity-related
data that are recorded in a minute-by-minute fashion. Although this structure
now contains HRM readings, it does not contain information about the quality of
those readings.
Note
{% guide_link events-and-services/health#read-per-minute-history "Health Guide" %} for futher information.
Next Steps
This guide covered the basics of how to interact with realtime and historic
heart information. We encourage you to further explore the HealthService
documentation, and integrate it into your next project.