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.
Table of Contents
Bluetooth* LE (BLE) communication use is exploding both in commercial products and hobby applications, mainly due to its low-cost and low-power requirements. This makes it an excellent choice when you want to communicate from your Android* phone or tablet to your Intel® Edison or Intel® Galileo projects.
The goal of this document is to show you how to write code and connect the hardware to establish BLE communication between an Intel Edison and a Bluetooth 4.0-equipped Android device, using free software tools and low-cost, off-the-shelf hardware.
Bluetooth Low Energy, Bluetooth LE, or just BLE (also known as Bluetooth Smart) is a wireless personal area network technology designed and marketed by the Bluetooth Special Interest Group. It is targeted for applications in the healthcare, fitness, security, automation, and home entertainment industries.
Bluetooth LE was originally introduced under the name Wibree by Nokia in 2006. It was added to the Bluetooth standard in 2010 with Bluetooth version 4.0.
BLE allows devices to use significantly less power than standard Bluetooth connections, while still offering most of the connectivity of regular Bluetooth, and with approximately half of the range (about 15 meters / 50 feet). Battery powered devices using Bluetooth LE can run for years without recharging or battery replacement. Beacon devices like those from Estimote are already claiming battery life of three (3) years (www.estimote.com).
We’ll be focusing on the Intel Edison, but most of this content also applies to the Intel Galileo. For our IoT project, the physical sensors and controls we’ll be using come from Seeed Studio’s Grove system. Specifically, we’ll be using:
- Intel Galileo with Arduino breakout board
- Seeed Grove – Starter Kit Plus Intel® IoT Edition For Galileo GEN 2
- Seeed Grove BLE
- An Android device running Android 4.3 or higher (I used the Lenovo TAB S8-50)
- A PC running Windows* 7 or 8 for development (I used the Dell XPS12)
A couple of notes about the hardware:
- The Grove Starter Kit is labelled that it’s designed for the Intel Galileo, but it works well with the Edison. You could also purchase the Grove components individually but the kit will likely be more economical.
- I used my Lenovo Android Tablet during development but any Android device running at least Android 4.3 with Bluetooth 4.0 support should work.
- I used my Dell XPS12 for writing the code for the Intel Edison and the Android project (and this article). Development can also be done on Mac* or Linux* systems.
I used several free software tools. To walk through this example, you’ll need to download and install them as needed:
All of the above software is available for Windows, Mac, and Linux, but I’ll be covering installation on Windows specifically.
The Intel® Edison is the first in the proposed series of low-cost, general-purpose compute platforms. It’s designed to allow for quick and easy prototyping of IoT projects while providing a product-ready path for commercialization.
The Intel® Edison uses a 22nm Intel® SoC that includes a dual-core Intel® Atom™ CPU running at 500MHz. It supports 40 GPIOs and includes 1GB LPDDR3 RAM, 4 GB EMMC for storage, and dual-band Wi-Fi* and Bluetooth in a tiny form factor.
Under the hood, the Edison runs a full Linux kernel, and to get the most performance out of the Edison, you’ll want to write hardware-level Linux code.
But the Edison Linux also contains an Arduino implementation as a Linux program. Simply put, this means you can write familiar Arduino sketches and run them on the Galileo. And that’s exactly what we’ll do.
Learn more about the Intel Edison here: http://www.intel.com/content/www/us/en/do-it-yourself/edison.html
The Arduino breakout board for the Intel Galileo serves two purposes. First, it provides a larger prototyping platform for easy access to the IO pins. And second, it provides an Arduino-compatible hardware platform, meaning we can use standard Arduino shields with the Intel Edison (just like the Intel Galileo). Figure 1 shows the Edison mounted to the Arduino breakout board.
Figure 1. Intel® Edison mounted to the Arduino breakout board
The kit’s full name is "Grove Starter Kit Plus - Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit" and was originally designed for the Intel Galileo 2nd generation board. Fortunately, it’s fully compatible with Intel Edison via the Arduino breakout board.
The kit (shown in Figure 2) is designed to simplify working and prototyping with sensors, actuators, and shields. It contains an Arduino-compatible shield with standardized four (4) pin connectors. These connectors feed to the IO ports that connect with the included cables that also easily attach to the sensors and controls in the kit. This means you can build projects without needing to mess with small wires and pull-up/pull-down resistors, or worry about polarity.
Learn more or purchase the kit here: http://www.seeedstudio.com/depot/Grove-starter-kit-plus-Intel-IoT-Edition-for-Intel-Galileo-Gen-2-p-1978.html
The creator of the Grove Kit, Seeed Studios, has a number of useful resources online.
Specifically, I recommend cloning or downloading the Sketchbook Starter repo here: http://Github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
And bookmark the Grove Wiki page here: http://www.seeedstudio.com/wiki/index.php?title=Main_Page#Grove
Figure 2. Grove Starter Kit Plus - Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit
We’re going to use the Grove Bluetooth Low Energy v1 module, which isn’t included in the starter kit, but is pin compatible with the Grove shield and connector cables. It’s also a relatively low cost BLE add-on, and at the time of writing was the cheapest option I found.
The Grove BLE v1 is based on the industry standard Texas Instruments CC2540. A number of other devices use this chip. If you have another TI CC2540 BLE module, such as the RedBear BLE Mini, you should be able to adapt the sample code with minimal effort.
Learn about the Grove BLE v1 here: http://www.seeedstudio.com/wiki/index.php?title=Grove_BLE_v1&uselang=en
Note, the Intel® Edison does include an onboard wireless module supporting Wi-Fi and Bluetooth 4.0/BLE; however, the Grove BLE module is going to greatly simplify the hardware and software setup. Using the Grove BLE (Figure 3) also means these projects can be easily adapted to the Intel Galileo.
Figure 3. Grove BLE V1 module
BLE support was added to Android in version 4.3 (API level 18). You need a device running 4.3 or higher to communicate over BLE.
Learn more about Android BLE here: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html
If you’re new to Android development, you need to enable the developer options on your phone or tablet before you can use it to run and debug your software. Open the settings app, scroll to the bottom, select "About device," and click the build number seven (7) times to unlock the developer options.
Developer Options is now displayed under settings; be sure to check "USB debugging."
Learn more about Android Developer Options here: http://developer.android.com/tools/device.html
You need to download the specially prepared version of the Arduino IDE in order to deploy Sketches to the Intel Edison or Galileo. At the time of writing the current version is 1.5.3 and is available here:
https://communities.intel.com/docs/DOC-22226
You also need to download and install the Intel Edison drivers from the link above. It should be the last link on the page listed under "Driver Software." At the time of writing it’s version 1.0.0.
There’s an excellent Getting Started Guide if you need further instructions:
https://communities.intel.com/docs/DOC-23147
Android Studio is a new Java* IDE for Android development based on IntelliJ IDEA* (https://www.jetbrains.com/idea/). It’s currently in Beta, but it’s stable and fairly feature complete. If you’re comfortable using Eclipse* for Java Android development or IntellliJ IDEA, you should have no problem following the walk-through using either one.
Android Studio simplifies the installation process by including the Android SDK. Simply download, extract the contents of the zip file, and run studio.exe in the bin folder.
Learn more about Android Studio here: https://developer.android.com/sdk/installing/studio.html
You may need to download additional SDK packages. To do so, click "SDK Manager" on the toolbar in Android Studio. Configuring Android SDKs is beyond our scope here, but you can get additional information here:
https://developer.android.com/sdk/installing/adding-packages.html
If you previously installed the Android SDKs, you can configure Android Studio and point it to the correct path, as shown in Figure 4
In Android Studio, click on Configure -> Project Defaults -> Project Structure and set the path.
Figure 4. Setting the SDK path in Android* Studio
Before starting the walk-through below, please make sure you’re able to run the Blink example sketch. It’s included in the Arduino IDE download package in the examples -> 01.Basics -> Blink folder.
For more information see the Edison Getting Started guide:
https://communities.intel.com/community/makers/edison/getting-started
Once you’ve installed Android Studio, make sure you’re able to create a new project and run it on your Android device.
- Connect your Android device to your PC
- Open Android Studio
- Select "New Project…"
- Select a name and location and click "Next" 3 times (API 15/Blank Activity)
- Click Finish and wait for the project to be created (this may take 20+ sec)
- Push the green Play icon on the toolbar
- Select your device and press "OK"
If everything went correctly, you should see "Hello world!" on your Android screen (Figure 5).
Figure 5. Android* Studio Hello World app
BLE works by providing short bursts of data as needed, and then powers down. This is partially how Bluetooth LE uses so little energy. Instead of the traditional pairing approach of regular Bluetooth, BLE devices link only when there’s a need to send or receive information.
BLE is strongly structured in how it communicates. Devices expose services to send and receive the data, and these services have what are called Characteristics that define what data can be shared. To get further details, Characteristics can have Descriptors that help define the data. For example, you could have a service labelled "Heart Rate Monitor" that included characteristics such as "heart rate measurement."
Most Bluetooth LE APIs allow searching for local devices and discovering services, characteristics, and descriptors on these devices.
Here’s a brief summary of the key BLE terms and concepts you should understand before starting a BLE project:
The GATT profile is a general specification for sending and receiving short pieces of data known as "attributes" over Bluetooth Low Energy link. All current LE application profiles are based on GATT. The Bluetooth Special Interest Group (SIG) (https://www.bluetooth.org) has pre-defined a number of profiles for BLE devices. These profiles are specifications that describe how a device can be used.
The Attribute Protocol (ATT) is what GATT is built on. The ATT is an optimized protocol designed specifically for BLE devices. ATT communication sends as few bytes of data as possible. Each attribute has a Universally Unique Identifier (UUID), which is a standardized, 128-bit string ID used to uniquely identify information. The attributes transported by ATT are formatted as characteristics and services (defined below).
A characteristic contains a single value and 0 or more descriptors (below) to describe the characteristic's value.
Descriptors are defined attributes that describe a characteristic’s value. These might be human-readable descriptions, specify units or measure, or define an acceptable range of values.
Services are collections of characteristics. You can find a list of existing GATT-based profiles here: https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
The remainder of this document assumes you have a development system set up and configured for both Intel Edison and Android development. Make sure you’ve completed the following steps and review the preceding content if needed.
- Install Intel Arduino IDE
- Install Intel Edison drivers
- Install Android Studio
- Install Android SDK
- Deploy and run Blink demo on the Intel Edison
- Deploy and run the empty Hello world Android project
You can download the completed project from GitHub here:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Android/BLEConnect
But I suggest making your own project and bringing the code in line-by-line by referencing the link above.
Open Android Studio (or your IDE of choice), create a new blank Android application, and name it BLEConnect. Make sure to set the Minimum SDK to at least API 18. Otherwise you won’t be able to use the BLE APIs.
Figure 6. Creating a new Android application
Next add the required permissions by opening the AndroidManifest.xml, and adding the following above the <application>
tag:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
To keep things simple, we’ll just use the default layout, but we’ll need to set an ID for our TextView. Open layout -> activity_main.xml, select the TextView, and set the id to mainText
so we can reference it in our code.
Figure 7. Set the resource id for the TextView
MainActivity
For this project, the remainder of the code goes in the MainActivity. If you’re adding the code line by line, notice that Android Studio automatically detects missing imports and prompts you to add them.
The sample code does the following:
- Checks for BLE support on the Android device
- Searches for BLE devices nearby
- Identifies and connects to the Grove BLE module
- Searches the available services for the known communication service
- Finds the transmit characteristic on the communication service
- Sends a message by writing a value to the characteristic
I won’t cover every line of code here, but we’ll look at the core concepts.
Class Level Variables and Static Values
We’ll store a number of values as we connect to the BLE module, search for services, and send our message. We’ll also add some known static values for the Grove BLE v1 (TI CC2540). You may need to change these if you’re using a different module. Specifically, I recommend defining the transmit and receive characteristics, for example:
CHARACTERISTIC_TX = "0000ffe1-0000-1000-8000-00805f9b34fb"
CHARACTERISTIC_RX = "0000ffe1-0000-1000-8000-00805f9b34fb"
Status helper Method
For simplicity, we show our progress on the TextView we labelled earlier. The code includes a simple helper method called statusUpdate
that we use to write status messages to both the screen and the console. It also marshals back to the UI thread so we can safely call it from any thread.
Connect to the BLE Device
To get a reference to the Bluetooth Manager we first check if BLE is available on our device, call getSystemService
to get a reference to the Bluetooth Manager (BluetoothManager
), and then call the getAdapter()
method to get our reference to the BluetoothAdapter
object. Alternatively, you can use the static helper method getDefaultAdapter
directly from the Bluetooth Manager class.
Search for Nearby BLE Devices
To search for devices, we use a timer to search for a set period of time. We call startLeScan
on our Bluetooth manager object and pass in a callback object to get notified when devices are found.
The API continuously scans for devices and as a result, we’ll likely get multiple notifications in the LeScanCallback
for each device, so we check to make sure the device entry is unique before saving it off. We also check the device names for our module and save off a reference. For this example we don’t actually need to save the devices to the list.
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord)
{
…
}
Find the Communication Service
Most BLE devices expose one or more services for communication/ interaction. The TI CC2540 chip in our Grove BLE has a key service with the ID "0000ffe0-0000-1000-8000-00805f9b34fb". Next we’ll find and save a reference to that service.
First we need to connect to the device. To get notified when we’re connected or when services have been found, we need a BluetoothGattCallback
object and we override onConnectionStateChanged
and onServicesDiscovered
.
Notice in the onConnectionStateChanged
method, when we’re notified of a connection we call mBluetoothGatt.discoverServices()
to search for services. Once we identify the service we want, we can go ahead and send a message.
@Override
public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState)
{
…
}
@Override
public void onServicesDiscovered (BluetoothGatt gatt, int status)
{
…
}
A number of other methods can be overridden. See the documentation here:
https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html
Sending a Message
In the example code there’s a sendMessage
method. We identify the characteristic we want by its UDID and call setValue
on the characteristic. Finally, we call writeCharacteristic
on our BluetoothGatt reference, passing in the characteristic as a value to send the data.
There are several overloads of setValue
, and there’s actually an easier overload to send strings, but since most BLE communication sends commands as bytes, this is a more useful example.
Now it’s time to set up the Intel Edison.
Start by assembling the basic hardware. If you haven’t already, mount the Intel Edison to the Arduino breakout board.
Next, mount the Grove shield by aligning the pins on the bottom of the shield to the Arduino breakout board. Then connect the Grove BLE v1 to the serial UART port.
Figure 8. Intel® Edison on with the Grove Shield and BLE module connected
We’re going to be doing some simple serial communication between our Android device and the Intel Edison. But we also want to see what’s being sent and received so we’ll use the Arduino IDE’s built-in Serial Monitor.
You can see a completed version of the sketch here:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Sketches/SimpleSerial
Open the Intel Arduino IDE and create a new sketch. Let’s save it and give it the name "SimpleSerial." Unlike some other Arduino compatible boards, the Intel Edison has two serial ports we can use. This is very useful because it allows us to communicate from our PC to the Edison while Edison sends and receives data through the Grove BLE. The primary serial UART is accessed through the microUSB connected to your PC, and we use the UART connector on the Grove shield that’s connected to the BLE module.
Our sketch automatically runs once it’s deployed to the Intel Edison. It first runs the setup()
function, and then consecutively calls the loop()
function indefinitely. This allows us to read and respond to input from the serial connections.
The Grove BLE’s default communication speed is 9600 baud so let’s start with that. We need to configure both serial ports to use this speed. We also need to send a couple of AT commands to the Grove BLE to reset it and get it into a fresh state. You can see all of this in the sketch’s setup()
function.
Notice that we’re first configuring "Serial," which is the microUSB port UART, and then "Serial1," which is the UART connected to the Grove BLE.
All we do in this sketch is read data from either serial port and send it to the other. To do this, we’ll call the read()
function on the serial ports, which gives us a single character and then print()
on the other serial port.
The Edison loops quickly enough that we’ll have no problem keeping up with 9600 baud.
Now click the verify button on the Arduino IDE (the checkmark) and fix any typos. Once it’s verified, make sure your Intel Edison is connected to the PC and upload the sketch (right arrow). Once the transfer is complete, the sketch starts looping, and we’re ready to connect from the Android app. Now open the Serial Monitor on the Arduino IDE (magnifying glass on the top right) so we can send and receive data.
Once the sketch is running on the Intel Edison, run the Android BLEConnect app. You should see the message "Hello Grove BLE" appear in the serial monitor.
If it doesn’t work, it’s most likely an issue with the Android app. Check the status display, which should tell you where it failed.
There’s a sketch in the GitHub repo that also displays the message on the Grove LCD. Make sure your Grove shield is set to 5V and connect the LCD display to any of the I2C connections.
Figure 9. BLEConnect running on an Android* phone
Figure 10. Adruino IDE Serial Monitor receiving BLEConnect message
Creating a more complex project means putting some architecture into both the Android code and the sketch. I’d recommend moving most of the Android BLE code into a service to abstract it from the UI and make it easier to use across multiple activities and multiple projects. When creating more advanced sketches, you’ll want to start using the Arduino Time Library, which enables you to simulate running multiple loops while still receiving data (http://playground.arduino.cc/Code/Time). I’ll be adding examples of this to the GitHub repository (https://github.com/adrianstevens/Edison_to_Android_BLE), and I’ll discuss these concepts in a future article.