HeartRateService
People practicing physical activities use heart rate monitors to track their pulse in real time and improve their physical performances.
The Bluetooth Heart Rate Service defines how data from a heart rate sensor should be exposed through a BLE link. The standard nature of the service allows seamless operations between collectors - usually smartphone applications - and heart rate monitors conforming to the service.
The HeartRateService class implements the Bluetooth Heart Rate service as defined by the Bluetooth body. Makers of BLE enabled fitness devices can use it to expose interoperably heart rate sensor data.
Note: The Bluetooth Heart Rate Service is part of the Bluetooth Heart Rate Profile, which defines behaviors that a Bluetooth heart rate sensor expects. You must ensure that your application conforms to the heart rate profile to guarantee interoperability of your heart rate sensors.
HeartRateService class reference
Data Structures | |
struct | HeartRateValueBytes |
Public Types |
Public Member Functions | |
HeartRateService (BLE &_ble, uint16_t hrmCounter, BodySensorLocation location) | |
Construct and initialize a heart rate service. More... | |
void | updateHeartRate (uint16_t hrmCounter) |
Update the heart rate that the service exposes. More... |
Protected Member Functions | |
void | setupService (void) |
Construct and add to the GattServer the heart rate service. More... |
HeartRateService example
/* mbed Microcontroller Library
* Copyright (c) 2006-2015 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
#include "ble/gap/Gap.h"
#include "ble/services/HeartRateService.h"
#include "pretty_printer.h"
const static char DEVICE_NAME[] = "Heartrate";
static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);
class HeartrateDemo : ble::Gap::EventHandler {
public:
HeartrateDemo(BLE &ble, events::EventQueue &event_queue) :
_ble(ble),
_event_queue(event_queue),
_led1(LED1, 1),
_connected(false),
_hr_uuid(GattService::UUID_HEART_RATE_SERVICE),
_hr_counter(100),
_hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER),
_adv_data_builder(_adv_buffer) { }
void start() {
_ble.gap().setEventHandler(this);
_ble.init(this, &HeartrateDemo::on_init_complete);
_event_queue.call_every(500, this, &HeartrateDemo::blink);
_event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value);
_event_queue.dispatch_forever();
}
private:
/** Callback triggered when the ble initialization process has finished */
void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
if (params->error != BLE_ERROR_NONE) {
printf("Ble initialization failed.");
return;
}
print_mac_address();
start_advertising();
}
void start_advertising() {
/* Create advertising parameters and payload */
ble::AdvertisingParameters adv_parameters(
ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
ble::adv_interval_t(ble::millisecond_t(1000))
);
_adv_data_builder.setFlags();
_adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR);
_adv_data_builder.setLocalServiceList(mbed::make_Span(&_hr_uuid, 1));
_adv_data_builder.setName(DEVICE_NAME);
/* Setup advertising */
ble_error_t error = _ble.gap().setAdvertisingParameters(
ble::LEGACY_ADVERTISING_HANDLE,
adv_parameters
);
if (error) {
printf("_ble.gap().setAdvertisingParameters() failed\r\n");
return;
}
error = _ble.gap().setAdvertisingPayload(
ble::LEGACY_ADVERTISING_HANDLE,
_adv_data_builder.getAdvertisingData()
);
if (error) {
printf("_ble.gap().setAdvertisingPayload() failed\r\n");
return;
}
/* Start advertising */
error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
if (error) {
printf("_ble.gap().startAdvertising() failed\r\n");
return;
}
}
void update_sensor_value() {
if (_connected) {
// Do blocking calls or whatever is necessary for sensor polling.
// In our case, we simply update the HRM measurement.
_hr_counter++;
// 100 <= HRM bps <=175
if (_hr_counter == 175) {
_hr_counter = 100;
}
_hr_service.updateHeartRate(_hr_counter);
}
}
void blink(void) {
_led1 = !_led1;
}
private:
/* Event handler */
void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
_ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
_connected = false;
}
virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) {
if (event.getStatus() == BLE_ERROR_NONE) {
_connected = true;
}
}
private:
BLE &_ble;
events::EventQueue &_event_queue;
DigitalOut _led1;
bool _connected;
UUID _hr_uuid;
uint8_t _hr_counter;
HeartRateService _hr_service;
uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
ble::AdvertisingDataBuilder _adv_data_builder;
};
/** Schedule processing of events from the BLE middleware in the event queue. */
void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
}
int main()
{
BLE &ble = BLE::Instance();
ble.onEventsToProcess(schedule_ble_events);
HeartrateDemo demo(ble, event_queue);
demo.start();
return 0;
}
Related content
- Bluetooth Heart Rate Service specification.
- Bluetooth Heart Rate Profile specification.