pebble/devsite/source/_guides/events-and-services/hrm.md
2025-02-24 18:58:29 -08:00

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
HealthService
title url
HRM Watchface https://github.com/pebble-examples/watchface-tutorial-hrm
title url
HRM Activity https://github.com/pebble-examples/hrm-activity-example
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

{% markdown {} %} Before your application is able to access the heart rate information, you will need to add `heath` to the `capabilities` array in your applications `package.json` file.
{
  ...
  "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.