Get access to the new Intel® IoT Developer Kit, a complete hardware and software solution that allows developers to create exciting new solutions with the Intel® Galileo and Intel® Edison boards. Visit the Intel® Developer Zone for IoT.
Introduction
Bluetooth* Low Energy (Bluetooth LE or BLE) is a low-power, short-range wireless communication technology that is ideal for use on the Internet of Things (IoT). BLE is designed for small and distinct data transfer, providing a fast connection between client and server and a simple user interface, which makes it ideal for control and monitoring applications. Arduino 101* includes on-board Bluetooth LE to enable developers to interact with Bluetooth-enabled devices such as phones and tablets. We will discuss how to create a BLEservice and communicate with an Android device. We also set up a BLE blood pressure monitoring system to demonstrate the BLE capabilities of the Arduino 101*.
Hardware Components
The hardware components used in this project are listed below:
This project will use the angle rotary sensor from the Grove kit, as shown with the other components in Figure 1.
For details on installing the Intel® Curie Boards and setting up the software development environment for the Arduino 101* platform, go to https://software.intel.com/en-us/articles/fun-with-the-arduino-101-genuino-101.
Figure 1: Arduino 101* with rotary angle sensor.
Central and Peripheral Devices
Bluetooth LE supports two major roles for networked devices: central and peripheral.
Central: A Bluetooth device such as smart phone, tablet, or PC that initiates an outgoing connection request to an advertising peripheral device. Once connected to the peripheral, the central device can exchange data, read values from the peripheral device, and execute commands on the peripheral devices.
Peripheral: A BLE device that accepts an incoming connection request after advertising. It gathers and publishes data for other devices to consume.
The central device communicates with peripherals through advertising packages. Peripheral devices send out the advertisements, and the central device scans for advertisements.
Figure 2: Central and peripheral device communication.
Generic Attribute Profile (GATT)
The Arduino 101* Bluetooth LE is based on the Generic Attribute Profile (GATT) architecture. GATT defines a hierarchical data structure that is exposed to connected Bluetooth LE devices. The GATT profile is a way of specifying small transmission data over the BLE link. These small data transmissions over a BLE link are called attributes. The GATT is built on top of the Attribute Protocol (ATT). The ATT transports the attributes and the attributes are formatted as characteristics and services. To learn more about the Bluetooth LE and GATT, see https://www.bluetooth.com/what-is-bluetooth-technology/bluetooth-technology-basics/low-energy and https://www.bluetooth.com/specifications/gatt.
Peripheral Data Structure
In the GATT architecture, data is organized into services and characteristics. A Service is a set of features that encapsulate the behavior of the peripheral device. Characteristics are defined attributes of the service that provide additional information about it. For example, the characteristics of the blood pressure service are blood pressure measurement, intermediate cuff pressure, and blood pressure feature.
Figure 3: Bluetooth service and characteristics relationship.
Creating a Blood Pressure BLE Service
To create a BLE service, you’ll need to know the service number and a corresponding characteristic number. On the Bluetooth page, choose GATT Specifications -> Services for the full list of GATT-based services.
Figure 4: Bluetooth GATT Specification pull down menu.
Select the blood pressure service and get the service number for the BLEService constructor.
Figure 5: Bluetooth services.
On the Bluetooth page, select GATT Specifications -> Characteristics to access the blood pressure characteristics number.
Figure 6: Bluetooth characteristics.
Next, include the Arduino 101* CurieBLE library components to enable communication and interaction with other Bluetooth* devices. You can find the open-source CurieBLE library at https://github.com/01org/corelibs-arduino101.
#include <CurieBLE.h>
BLEPeripheral blePeripheral; BLEService bloodPressureService("1810"); BLECharacteristic bloodPressureChar("2A35", BLERead | BLENotify, 2);
Set a local name for the peripheral BLE device. When the phone (central device) connects to this peripheral Bluetooth* device, the local name will appear on the phone to identify the connected peripheral.
blePeripheral.setLocalName("BloodPressureSketch");
blePeripheral.setAdvertisedServiceUuid(bloodPressureService.uuid()); blePeripheral.addAttribute(bloodPressureService); blePeripheral.addAttribute(bloodPressureChar);
Connect the blood pressure device to analog pin A0 of the Arduino 101* platform. For this example, use the angle rotary sensor to simulate the blood pressure device.
int pressure = analogRead(A0);
int bloodPressure = map(pressure, 0, 1023, 0, 100);
Update the blood pressure measurement characteristic. This updated blood pressure value will be seen by the central device. For example, if the phone is connected to the peripheral blood pressure device, the phone can read the updated blood pressure value through an Android app.
bloodPressureChar.setValue(bloodPressureCharArray, 2);
Android Device Communicates with Arduino Sensor
The peripheral communicates with the central Android device through Bluetooth* advertising. In advertising, the peripheral device broadcasts packages to every device around it. The central device scans and connects to the peripheral device to receive data and get more information. Follow the steps below to enable communication between the Android device and Arduino sensor.
- Enabled Bluetooth on the Android device.
- There are many free BLE Android apps available on Google Play. Search for BLE on Google Play and install a BLE Android app on the Android device.
- Start the BLE Android app.
- Scan and connect to the BloodPressureSketch peripheral.
- Read or write the blood pressure value.
Figure 7 shows an example of an Android device scan for the BloodPressureSketch peripheral.
Figure 7: Android device scans for BLE service.
Turn the rotary angle sensor to see the blood pressure value change on the screen of Android device.
Develop an Android Application
Visit http://developer.android.com/guide/topics/connectivity/bluetooth-le.html for detailed information on developing your own Android app that communicates with the peripheral through the Arduino 101* platform. If you are new to Android, go to https://developer.android.com/training/basics/firstapp/index.html for instructions on creating an Android project and building your first Android app.
Example Arduino IDE Sketch
Code sample 1, below, provides sample code for blood pressure measurement. Open the serial console to see the resulting output.
#include <CurieBLE.h>
BLEPeripheral blePeripheral; BLEService bloodPressureService("1810");
BLECharacteristic bloodPressureChar("2A35", BLERead | BLENotify, 2);
int oldBloodPressure = 0; long previousMillis = 0;
void setup() {
Serial.begin(9600); pinMode(13, OUTPUT);
blePeripheral.setLocalName("BloodPressureSketch");
blePeripheral.setAdvertisedServiceUuid(bloodPressureService.uuid()); blePeripheral.addAttribute(bloodPressureService); blePeripheral.addAttribute(bloodPressureChar);
const unsigned char charArray[2] = { 0, (unsigned char)0 };
bloodPressureChar.setValue(charArray, 2);
blePeripheral.begin();
Serial.println("Bluetooth device active, waiting for connections...");
}
void loop() {
BLECentral central = blePeripheral.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
digitalWrite(13, HIGH);
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updateBloodPressure();
}
}
digitalWrite(13, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
void updateBloodPressure() {
int pressure = analogRead(A0);
int bloodPressure = map(pressure, 0, 1023, 0, 100);
if (bloodPressure != oldBloodPressure) {
Serial.print("The current blood pressure is: ");
Serial.println(bloodPressure);
const unsigned char bloodPressureCharArray[2] = { 0, (unsigned char)bloodPressure };
bloodPressureChar.setValue(bloodPressureCharArray, 2);
oldBloodPressure = bloodPressure;
}
}
Code Sample 1: Blood pressure sample code for Arduino IDE.
Summary
This document summarized how the Arduino 101* platform communicates with an Android device and described the steps for creating the BLE Service. See https://www.arduino.cc/en/Reference/CurieBLE for more examples of using BLE in the Arduino IDE. If you are interested in the Arduino 101* platform, browse to http://www.intel.com/buy/us/en/product/emergingtechnologies/intel-arduino-101-497161 for more information.
Helpful References
About the Author
Nancy Le is a software engineer at Intel Corporation in the Software and Services Group working on Intel® Atom™ processor scale-enabling project