Arduino 101 CurieBLE Heart Rate Monitor

This tutorial demonstrates the Arduino 101 onboard Bluetooth® Low Energy capabilities.

This tutorial demonstrates the Arduino 101's onboard Bluetooth® Low Energy capabilities. The sketch implements the standard Bluetooth® Low Energy "Heart Rate Monitor" service. The Heart Rate service takes values from a heart rate sensor (in this tutorial emulated by an analog sensor) and sends them over Bluetooth® Low Energy to your smartphone/device to create a graph of the data using the app nRF Toolbox for Bluetooth® Low Energy.

Hardware Required

  • Arduino 101

  • An Android or iOS device running the nRF Toolbox for Bluetooth® Low Energy App

  • A Potentiometer or other analog sensor

The Circuit

gen101hrm fzz

image developed using Fritzing.

Instructions

Set up the Arduino software as described in Getting Started with Arduino 101.

  1. Download the nRF Toolbox for Bluetooth® Low Energy app for Android or for iOS free of charge.

  2. Wire up the potentiometer (or other analog sensor) to your Arduino 101 as shown in "the circuit" above.

  3. Connect the Arduino 101 to your computer.

  4. Launch the Arduino software and select Arduino 101 from the Tools > Board menu.

  5. Upload the CurieBLEHeartRateMonitor example (found in File > Examples > CurieIMU). (The full code for the example is shown below.)

  6. Launch the app. You should be presented with the home screen as depicted below.

homeNRF

  • Click the heart icon in the centre of the screen, after which you will see a graph showing Beats per Minute over Time. This will not show any data until connected with your Arduino.

  • Press the connect button below the graph you should see the device "HeartRateSketch" (or whatever name you set).

  • Click on the name of your device, and the data from the potentiometer should immediately start entering the graph as depicted below. Of course, the potentiometer only emulates a heart rate to demonstrate the usage of the service.

graphNRF

Where to Go from Here

The Bluetooth® Low Energy includes many other services with which you can experiment, such as Alert Notificaion Service, Environmental Sensing, and AutomationIO, in which you can expose all of your Arduino's inputs and control its outputs. This tutorial uses nRF Toolbox, which allows the use of 9 services. For more advanced capabilities, other discluded services, as well the CurieImu library's LED examples, we recommend using LightBlue for iOS or nRF Control Panel for Android.

Code

1/*
2
3 Copyright (c) 2015 Intel Corporation. All rights reserved.
4
5 This library is free software; you can redistribute it and/or
6
7 modify it under the terms of the GNU Lesser General Public
8
9 License as published by the Free Software Foundation; either
10
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
19 Lesser General Public License for more details.
20
21 You should have received a copy of the GNU Lesser General Public
22
23 License along with this library; if not, write to the Free Software
24
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26
27*/
28
29/*
30
31 This sketch example partially implements the standard Bluetooth® Low-Energy Heart Rate service.
32
33 For more information: https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
34
35*/
36
37#include <CurieBLE.h>
38
39BLEPeripheral blePeripheral; // Bluetooth® Low Energy Peripheral Device (the board you're programming)
40
41BLEService heartRateService("180D"); // Bluetooth® Low Energy Heart Rate Service
42
43// BLE Heart Rate Measurement Characteristic"
44
45BLECharacteristic heartRateChar("2A37", // standard 16-bit characteristic UUID
46
47 BLERead | BLENotify, 2); // remote clients will be able to get notifications if this characteristic changes
48
49 // the characteristic is 2 bytes long as the first field needs to be "Flags" as per Bluetooth® Low Energy specifications
50
51 // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
52
53int oldHeartRate = 0; // last heart rate reading from analog input
54long previousMillis = 0; // last time the heart rate was checked, in ms
55
56void setup() {
57
58 Serial.begin(9600); // initialize serial communication
59
60 pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected
61
62 /* Set a local name for the Bluetooth® Low Energy device
63
64 This name will appear in advertising packets
65
66 and can be used by remote devices to identify this Bluetooth® Low Energy device
67
68 The name can be changed but maybe be truncated based on space left in advertisement packet */
69
70 blePeripheral.setLocalName("HeartRateSketch");
71
72 blePeripheral.setAdvertisedServiceUuid(heartRateService.uuid()); // add the service UUID
73
74 blePeripheral.addAttribute(heartRateService); // Add the BLE Heart Rate service
75
76 blePeripheral.addAttribute(heartRateChar); // add the Heart Rate Measurement characteristic
77
78 /* Now activate the BLE device. It will start continuously transmitting BLE
79
80 advertising packets and will be visible to remote BLE central devices
81
82 until it receives a new connection */
83
84 blePeripheral.begin();
85
86 Serial.println("Bluetooth® device active, waiting for connections...");
87}
88
89void loop() {
90
91 // listen for BLE peripherals to connect:
92
93 BLECentral central = blePeripheral.central();
94
95 // if a central is connected to peripheral:
96
97 if (central) {
98
99 Serial.print("Connected to central: ");
100
101 // print the central's MAC address:
102
103 Serial.println(central.address());
104
105 // turn on the LED to indicate the connection:
106
107 digitalWrite(13, HIGH);
108
109 // check the heart rate measurement every 200ms
110
111 // as long as the central is still connected:
112
113 while (central.connected()) {
114
115 long currentMillis = millis();
116
117 // if 200ms have passed, check the heart rate measurement:
118
119 if (currentMillis - previousMillis >= 200) {
120
121 previousMillis = currentMillis;
122
123 updateHeartRate();
124
125 }
126
127 }
128
129 // when the central disconnects, turn off the LED:
130
131 digitalWrite(13, LOW);
132
133 Serial.print("Disconnected from central: ");
134
135 Serial.println(central.address());
136
137 }
138}
139
140void updateHeartRate() {
141
142 /* Read the current voltage level on the A0 analog input pin.
143
144 This is used here to simulate the heart rate's measurement.
145
146 */
147
148 int heartRateMeasurement = analogRead(A0);
149
150 int heartRate = map(heartRateMeasurement, 0, 1023, 0, 100);
151
152 if (heartRate != oldHeartRate) { // if the heart rate has changed
153
154 Serial.print("Heart Rate is now: "); // print it
155
156 Serial.println(heartRate);
157
158 const unsigned char heartRateCharArray[2] = { 0, (char)heartRate };
159
160 heartRateChar.setValue(heartRateCharArray, 2); // and update the heart rate measurement characteristic
161
162 oldHeartRate = heartRate; // save the level for next comparison
163
164 }
165}

Contribute to Arduino

Join the community and suggest improvements to this article via GitHub. Make sure to read out contribution policy before making your pull request.

Missing something?

Check out our store and get what you need to follow this tutorial.

Suggest Changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.