Heart Rate monitor example for the Nucleo board and the Bluetooth Low Energy Nucleo board.

Dependencies:   Nucleo_BLE_API Nucleo_BLE_BlueNRG mbed

Warning: Deprecated!

Supported drivers and applications can be found at this link.

Getting Started with BlueNRG Shield

This example demonstrates how to use the Nucleo BlueNRG shield with the STM32F411 Nucleo board to obtain heart rate information:

First, attach the BlueNRG shield to the Nucleo board as shown here: /media/uploads/sjallouli/bluenrg_shield.jpg

Next, connect the STM32F411 Nucleo board to your PC with a USB cable.

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

/media/uploads/sjallouli/import_step1.jpg

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

/media/uploads/sjallouli/import_step2.jpg

Compile and load the image onto the F411 Nucleo board

Note

Refer to Getting Started with mbed and the STM32F411 Nucleo Board to learn how to compile and load a program onto the Nucleo board

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

Note

Refer to Creating Console Output for setting a terminal emulator

You should now see the various Bluetooth stack staus displayed on your console output. /media/uploads/sjallouli/concole_output.jpg

Test your application with iPhone

  • Use Alpwise i-BLE
  • On the Alpwise app select BlueNRG_HRM /media/uploads/sjallouli/img_0171.png
  • Select Heart Rate /media/uploads/sjallouli/img_0172.png /media/uploads/sjallouli/img_0173.png
Committer:
sjallouli
Date:
Fri Dec 19 19:39:57 2014 +0000
Revision:
0:5aa20a65f094
BLE_HeartRate example for the Nucleo board and Bluetooth Low Energy Nucleo shield

Who changed what in which revision?

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