Heart Rate Monitor example for the BLE API using ST BlueNRG native drivers

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Getting started with X-NUCLEO-IDB05A1

This example demonstrates how to use the X-NUCLEO-IDB05A1 component with one of the STM32 Nucleo platforms tested with the to obtain heart rate information:

First, attach the X-NUCLEO-IDB05A1 to the STM32 Nucleo platform as shown here: /media/uploads/apalmieri/nucleoble.jpg

Next, connect the STM32 Nucleo platform to your PC with a USB-mini USB cable.

Now return to the BLE_HeartRate_IDB0XA1 project homepage and import the project into your mbed compiler:

/media/uploads/apalmieri/homepage.jpg

Click “Import” button on the pop up window shown below

/media/uploads/apalmieri/import.jpg

Compile and load the image onto the STM32 Nucleo platform

Upon a successful compilation, a binary image will be created and a dialog box will ask you where to save it.

/media/uploads/apalmieri/xsaveimage.jpg

Now you can load the compiled code onto your Nucleo platform by saving the newly created binary file to your STM32 Nucleo drive.

Open a terminal window to display the status of your Bluetooth stack. For this example, set the terminal BAUD rate to 9600

Note

Included within the USB interface of the STM32 Nucleo platform is a Virtual COM port that can be used to send back messages to your PC within your embedded code.
You need a terminal emulator installed on your PC to perform serial communications with your STM32 Nucleo platform. If you do not have a terminal emulation program on your PC we recommend you download and install one of the following terminal emulation programs:

Upon a successful serial connection, you should now see the various Bluetooth stack status displayed on your console output.

/media/uploads/apalmieri/xteraterm.png

Test your application with an Android or iOS device

/media/uploads/apalmieri/1.splashscreen_800x1280.png

  • On the STM32 BLE Profiles app select HeartRateSensor

/media/uploads/apalmieri/2.scanningdevice_800x1280.png

  • Select Heart Rate

/media/uploads/apalmieri/3.profileselection_800x1280.png /media/uploads/apalmieri/7.heartrate_800x1280.png

Committer:
apalmieri
Date:
Tue Sep 29 09:11:55 2015 +0000
Revision:
1:11cd427bbc8b
Parent:
0:eb7f02ad28a7
Child:
2:bc0c0d442a24
Do not use LED when compiling for 'IDB0XA1_D13_PATCH'

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:eb7f02ad28a7 1 /* mbed Microcontroller Library
screamer 0:eb7f02ad28a7 2 * Copyright (c) 2006-2015 ARM Limited
screamer 0:eb7f02ad28a7 3 *
screamer 0:eb7f02ad28a7 4 * Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:eb7f02ad28a7 5 * you may not use this file except in compliance with the License.
screamer 0:eb7f02ad28a7 6 * You may obtain a copy of the License at
screamer 0:eb7f02ad28a7 7 *
screamer 0:eb7f02ad28a7 8 * http://www.apache.org/licenses/LICENSE-2.0
screamer 0:eb7f02ad28a7 9 *
screamer 0:eb7f02ad28a7 10 * Unless required by applicable law or agreed to in writing, software
screamer 0:eb7f02ad28a7 11 * distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:eb7f02ad28a7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:eb7f02ad28a7 13 * See the License for the specific language governing permissions and
screamer 0:eb7f02ad28a7 14 * limitations under the License.
screamer 0:eb7f02ad28a7 15 */
screamer 0:eb7f02ad28a7 16
screamer 0:eb7f02ad28a7 17 #include "mbed.h"
screamer 0:eb7f02ad28a7 18 #include "ble/BLE.h"
screamer 0:eb7f02ad28a7 19 #include "ble/services/HeartRateService.h"
screamer 0:eb7f02ad28a7 20 #include "ble/services/BatteryService.h"
screamer 0:eb7f02ad28a7 21 #include "ble/services/DeviceInformationService.h"
screamer 0:eb7f02ad28a7 22
screamer 0:eb7f02ad28a7 23 BLE ble;
apalmieri 1:11cd427bbc8b 24
apalmieri 1:11cd427bbc8b 25 #if !defined(IDB0XA1_D13_PATCH)
screamer 0:eb7f02ad28a7 26 DigitalOut led1(LED1);
apalmieri 1:11cd427bbc8b 27 #endif
screamer 0:eb7f02ad28a7 28
screamer 0:eb7f02ad28a7 29 const static char DEVICE_NAME[] = "HRM1";
screamer 0:eb7f02ad28a7 30 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
screamer 0:eb7f02ad28a7 31 GattService::UUID_DEVICE_INFORMATION_SERVICE};
screamer 0:eb7f02ad28a7 32 static volatile bool triggerSensorPolling = false;
screamer 0:eb7f02ad28a7 33
screamer 0:eb7f02ad28a7 34 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
screamer 0:eb7f02ad28a7 35 {
screamer 0:eb7f02ad28a7 36 ble.gap().startAdvertising(); // restart advertising
screamer 0:eb7f02ad28a7 37 }
screamer 0:eb7f02ad28a7 38
screamer 0:eb7f02ad28a7 39 void periodicCallback(void)
screamer 0:eb7f02ad28a7 40 {
apalmieri 1:11cd427bbc8b 41
apalmieri 1:11cd427bbc8b 42 #if !defined(IDB0XA1_D13_PATCH)
screamer 0:eb7f02ad28a7 43 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
apalmieri 1:11cd427bbc8b 44 #endif
screamer 0:eb7f02ad28a7 45 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
screamer 0:eb7f02ad28a7 46 * heavy-weight sensor polling from the main thread. */
screamer 0:eb7f02ad28a7 47 triggerSensorPolling = true;
screamer 0:eb7f02ad28a7 48 }
screamer 0:eb7f02ad28a7 49
screamer 0:eb7f02ad28a7 50 int main(void)
screamer 0:eb7f02ad28a7 51 {
apalmieri 1:11cd427bbc8b 52
apalmieri 1:11cd427bbc8b 53 #if !defined(IDB0XA1_D13_PATCH)
screamer 0:eb7f02ad28a7 54 led1 = 1;
apalmieri 1:11cd427bbc8b 55 #endif
screamer 0:eb7f02ad28a7 56 Ticker ticker;
screamer 0:eb7f02ad28a7 57 ticker.attach(periodicCallback, 1); // blink LED every second
screamer 0:eb7f02ad28a7 58
screamer 0:eb7f02ad28a7 59 ble.init();
screamer 0:eb7f02ad28a7 60 ble.gap().onDisconnection(disconnectionCallback);
screamer 0:eb7f02ad28a7 61
screamer 0:eb7f02ad28a7 62 /* Setup primary service. */
screamer 0:eb7f02ad28a7 63 uint8_t hrmCounter = 100; // init HRM to 100bps
screamer 0:eb7f02ad28a7 64 HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
screamer 0:eb7f02ad28a7 65
screamer 0:eb7f02ad28a7 66 /* Setup auxiliary service. */
screamer 0:eb7f02ad28a7 67 DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
screamer 0:eb7f02ad28a7 68
screamer 0:eb7f02ad28a7 69 /* Setup advertising. */
screamer 0:eb7f02ad28a7 70 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
screamer 0:eb7f02ad28a7 71 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
screamer 0:eb7f02ad28a7 72 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
screamer 0:eb7f02ad28a7 73 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
screamer 0:eb7f02ad28a7 74 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
screamer 0:eb7f02ad28a7 75 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
screamer 0:eb7f02ad28a7 76 ble.gap().startAdvertising();
screamer 0:eb7f02ad28a7 77
screamer 0:eb7f02ad28a7 78 // infinite loop
screamer 0:eb7f02ad28a7 79 while (1) {
screamer 0:eb7f02ad28a7 80 // check for trigger from periodicCallback()
screamer 0:eb7f02ad28a7 81 if (triggerSensorPolling && ble.getGapState().connected) {
screamer 0:eb7f02ad28a7 82 triggerSensorPolling = false;
screamer 0:eb7f02ad28a7 83
screamer 0:eb7f02ad28a7 84 // Do blocking calls or whatever is necessary for sensor polling.
screamer 0:eb7f02ad28a7 85 // In our case, we simply update the HRM measurement.
screamer 0:eb7f02ad28a7 86 hrmCounter++;
screamer 0:eb7f02ad28a7 87
screamer 0:eb7f02ad28a7 88 // 100 <= HRM bps <=175
screamer 0:eb7f02ad28a7 89 if (hrmCounter == 175) {
screamer 0:eb7f02ad28a7 90 hrmCounter = 100;
screamer 0:eb7f02ad28a7 91 }
screamer 0:eb7f02ad28a7 92
screamer 0:eb7f02ad28a7 93 // update bps
screamer 0:eb7f02ad28a7 94 hrService.updateHeartRate(hrmCounter);
screamer 0:eb7f02ad28a7 95 } else {
screamer 0:eb7f02ad28a7 96 ble.waitForEvent(); // low power wait for event
screamer 0:eb7f02ad28a7 97 }
screamer 0:eb7f02ad28a7 98 }
screamer 0:eb7f02ad28a7 99 }