Introduction

The BLEFriend makes it easy to get any USB enabled device talking to your BLE enabled phone or tablet using a standard USB CDC connection.

Please note that there are three versions of this board. An older v1.0 blue PCB which uses 16KB SRAM parts and can run firmware 0.5.0 and lower. A newer v2.0 black PCB that uses the latest 32KB parts and can run old firmware plus version 0.6.2 and higher, based on the FTDI bridge and with an SWD connector. A cost-optimized v3.0 board that uses a CP2104 USB chip and drops the SWD connector. v3.0 can run all of the same firmware as v2.0, and is the latest board available.

In it's simplest form, it works on the same principle as a common USB/Serial adapter (the FTDI Friend, for example!). Any data that you enter via your favorite terminal emulator on your development machine will be transferred over the air to the connected phone or tablet, and vice versa.

Why Not Just Use a BLE USB Dongle?

Good question! You can get a Bluetooth 4.0 USB dongle from the store already, and it's a useful tool to have (particularly on the Raspberry Pi or BBB), but that won't solve some problems out of the box.

To start with, Bluez (Linux) has a decent learning curve (and doesn't run on OS X if you're a Mac user). Windows 7 doesn't even support Bluetooth Low Energy, and on OS X you'll have to sort through the native Bluetooth APIs and development tools that require an annual paid license and specific license terms to access. There isn't a standard, open source, cross-platform way to talk BLE today.

With the BLEFriend, you can be up and running in under and hour on just about anything with a USB port, with easy migration across platforms and operating systems. It's not perfect (it's currently a peripheral mode only solution), but it's the easiest way you'll find to get any USB device talking to your iOS or Android device.

So it's a Fancy Pants Wireless UART Adapter?

The board is capable of much more than simulating a basic UART bridge (and this is still early days for the Bluefruit LE board family)!  Thanks to an easy to learn AT command set, you can also create you own basic GATT Services and Characteristics, simulate Beacons, and change the way that the device advertises itself for other Bluetooth Low Energy devices to see.

To make sure that your device stays up to date and can benefit from the latest Bluefruit LE firmware from Adafruit, you can also update the firmware on your BLEFriend over the air using any supported iOS or Android device.

You can even pick up a sniffer edition of the board that comes pre-flashed with special firmware that turns your BLEFriend into a low cost Bluetooth Low Energy sniffer, capturing data and pushing it out to Wireshark.  We currently offer this as a seperate product, though, since the firmware isn't compatible with the over the air bootloader used on the standard products, but we'll address this in the future with a tutorial for J-Link owners, allowing you to switch between modes using your SWD debugger.

Why Use Adafruit's Module?

There are plenty of BLE modules out there, with varying quality on the HW design as well as the firmware.  We always try to keep the bar as high as possible at Adafruit, and one of the biggest advantages of the BLEFriend and the entire Bluefruit LE family is that we wrote all of the firmware running on the devices ourelves from scratch.

We control every line of code that runs on our modules ... and so we aren't at the mercy of any third party vendors who may or may not be interested in keeping their code up to date or catering to our customer's needs.

Because we control everything about the product, we add features that are important to our customers, benefit from being able to use the latest Bluetooth specifications, can solve any issues that do come up without having to persuade a half-hearted firmware engineer on the other side of the planet, and we can even change Bluetooth SoCs entirely if the need ever arises!

Getting Started

If you just want to get up and running quickly, this is the right guide for you, and the QuickStart section should have you up and running in no time.

If you're new to Bluetooth Low Energy, and want to get a high level overview of how data is organized and how devices communicate with each other, you might want to have a look at our Introduction to Bluetooth Low Energy learning guide, or buy Getting Started with Bluetooth Low Energy from the store.*

* Full disclosure: co-written by me :)

QuickStart Guide

The BLEFriend board is designed to be easy to use and get started with.

In most circumstance, the only thing you'll need is an FTDI driver, and a terminal emulator to start working with BLE from your development machine.

This guide will explain some of the different operating modes that the BLEFriend board can be configure to operate in, how to setup your terminal emulator to start talking to the BLEFriend, and a basic example of sending bi-directional data between the BLEFriend and a BLE-enabled phone or tablet.

The BLEFriend is (of course) capable of much more than basic UART data exchanges! You can use it to create custom GATT services and characteristics. You can emulate a Beacon for indoor navigation purposes. You can update the firmware on your device over the air, or even develop your own firmware thanks to the SWD pins on the bottom of the PCB if you possess a HW debugger like the Segger J-Link.

Depending on the version of the board you have or whether or not you have access to a J-Link, you can even use the BLEFriend as a powerful Bluetooth Low Energy sniffer to debug or reverse engineer existing BLE devices, and write your own custom applications or drivers for existing HW!

Have a look through this quick start guide to familiarise yourself with the basics, though, and you should be able to quickly move on to more advanced topics in no time!

Command Mode

By placing the BLEFriend module in 'Command' mode (set the mode selection switch to CMD) you can enter a variety of Hayes AT style commands to configure the device or retrieve basic information about the module of BLE connection.

You can determine if you are in Command Mode by looking at the mode LED.  It should blink three times followed by a three second pause, as shown below:

Hayes/AT Commands

When operating in command mode, the Bluefruit LE Pro modules use a Hayes AT-style command set to configure the device.

The advantage of an AT style command set is that it's easy to use in machine to machine communication, while still being somewhat user friendly for humans.

Test Command Mode '=?'

'Test' mode is used to check whether or not the specified command exists on the system or not.  

Certain firmware versions or configurations may or may not include a specific command, and you can determine if the command is present by taking the command name and appending '=?' to it, as shown below

Download: file
AT+BLESTARTADV=?

If the command is present, the device will reply with 'OK'.  If the command is not present, the device will reply with 'ERROR'.

Download: file
AT+BLESTARTADV=?
OK\r\n
AT+MISSINGCMD=?
ERROR\r\n

Write Command Mode '=xxx'

'Write' mode is used to assign specific value(s) to the command, such as changing the radio's transmit power level using the command we used above.

To write a value to the command, simple append an '=' sign to the command followed by any paramater(s) you wish to write (other than a lone '?' character which will be interpretted as tet mode):

Download: file
AT+BLEPOWERLEVEL=-8

If the write was successful, you will generally get an 'OK' response on a new line, as shown below:

Download: file
AT+BLEPOWERLEVEL=-8
OK\r\n

If there was a problem with the command (such as an invalid parameter) you will get an 'ERROR' response on a new line, as shown below:

Download: file
AT+BLEPOWERLEVEL=3
ERROR\r\n

Note: This particular error was generated because '3' is not a valid value for the AT+BLEPOWERLEVEL command.  Entering '-4', '0' or '4' would succeed since these are all valid values for this command.

Execute Mode

'Execute' mode will cause the specific command to 'run', if possible, and will be used when the command name is entered with no additional parameters.

Download: file
AT+FACTORYRESET

You might use execute mode to perform a factory reset, for example, by executing the AT+FACTORYRESET command as follows:

Download: file
AT+FACTORYRESET
OK\r\n

NOTE: Many commands that are means to be read will perform the same action whether they are sent to the command parser in 'execute' or 'read' mode. For example, the following commands will produce identical results:

Download: file
AT+BLEGETPOWERLEVEL
-4\r\n
OK\r\n
AT+BLEGETPOWERLEVEL?
-4\r\n
OK\r\n

If the command doesn't support execute mode, the response will normally be 'ERROR' on a new line.

Read Command Mode '?'

'Read' mode is used to read the current value of a command. 

Not every command supports read mode, but you generally use this to retrieve information like the current transmit power level for the radio by appending a '?' to the command, as shown below:

Download: file
AT+BLEPOWERLEVEL?

If the command doesn't support read mode or if there was a problem with the request, you will normally get an 'ERROR' response.

If the command read was successful, you will normally get the read results followed by 'OK' on a new line, as shown below:

Download: file
AT+BLEPOWERLEVEL?
-4\r\n
OK\r\n

Note: For simple commands, 'Read' mode and 'Execute' mode behave identically.

Command Examples

The following code snippets can be used when operating in Command Mode to perform specific tasks.

Heart Rate Monitor Service

The command list below will add a Heart Rate service to the BLEFriend's attribute table, with two characteristics:

Download: file
# Perform a factory reset to make sure we get a clean start
AT+FACTORYRESET
OK
  
# Add the Heart Rate service entry
AT+GATTADDSERVICE=UUID=0x180D
1
OK

# Add the Heart Rate Measurement characteristic
AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=3, VALUE=00-40
1
OK

# Add the Body Sensor Location characteristic
AT+GATTADDCHAR=UUID=0x2A38, PROPERTIES=0x02, MIN_LEN=1, VALUE=3
2
OK

# Create a custom advertising packet that includes the Heart Rate service UUID
AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18
OK

# Reset the device to start advertising with the custom payload
ATZ
OK

# Update the value of the heart rate measurement (set it to 0x004A)
AT+GATTCHAR=1,00-4A
OK

Python Script

The following code performs the same function, but has been placed inside a Python wrapper using PySerial to show how you can script actions for the AT parser.

Download: file
import io
import sys
import serial
import random
from time import sleep

filename = "hrm.py"
ser = None
serio = None
verbose = True  # Set this to True to see all of the incoming serial data


def usage():
    """Displays information on the command-line parameters for this script"""
    print "Usage: " + filename + " <serialPort>\n"
    print "For example:\n"
    print "  Windows : " + filename + " COM14"
    print "  OS X    : " + filename + " /dev/tty.usbserial-DN009WNO"
    print "  Linux   : " + filename + " /dev/ttyACM0"
    return


def checkargs():
    """Validates the command-line arguments for this script"""
    if len(sys.argv) < 2:
        print "ERROR: Missing serialPort"
        usage()
        sys.exit(-1)
    if len(sys.argv) > 2:
        print "ERROR: Too many arguments (expected 1)."
        usage()
        sys.exit(-2)


def errorhandler(err, exitonerror=True):
    """Display an error message and exit gracefully on "ERROR\r\n" responses"""
    print "ERROR: " + err.message
    if exitonerror:
        ser.close()
        sys.exit(-3)


def atcommand(command, delayms=0):
    """Executes the supplied AT command and waits for a valid response"""
    serio.write(unicode(command + "\n"))
    if delayms:
        sleep(delayms/1000)
    rx = None
    while rx != "OK\r\n" and rx != "ERROR\r\n":
        rx = serio.readline(2000)
        if verbose:
            print unicode(rx.rstrip("\r\n"))
    # Check the return value
    if rx == "ERROR\r\n":
        raise ValueError("AT Parser reported an error on '" + command.rstrip() + "'")


if __name__ == '__main__':
    # Make sure we received a single argument (comPort)
    checkargs()

    # This will automatically open the serial port (no need for ser.open)
    ser = serial.Serial(port=sys.argv[1], baudrate=9600, rtscts=True)
    serio = io.TextIOWrapper(io.BufferedRWPair(ser, ser, 1),
                             newline='\r\n',
                             line_buffering=True)

    # Add the HRM service and characteristic definitions
    try:
        atcommand("AT+FACTORYRESET", 1000)  # Wait 1s for this to complete
        atcommand("AT+GATTCLEAR")
        atcommand("AT+GATTADDSERVICE=UUID=0x180D")
        atcommand("AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=3, VALUE=00-40")
        atcommand("AT+GATTADDCHAR=UUID=0x2A38, PROPERTIES=0x02, MIN_LEN=1, VALUE=3")
        atcommand("AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18")
        # Perform a system reset and wait 1s to come back online
        atcommand("ATZ", 1000)
        # Update the value every second
        while True:
            atcommand("AT+GATTCHAR=1,00-%02X" % random.randint(50, 100), 1000)
    except ValueError as err:
        # One of the commands above returned "ERROR\n"
        errorhandler(err)
    except KeyboardInterrupt:
        # Close gracefully on CTRL+C
        ser.close()
        sys.exit()

The results of this script can be seen below in the 'HRM' app of Nordic's nRF Toolbox application:

Please note that nRF Toolbox will only display HRM data if the value changes, so you will need to update the Heart Rate Measurement characteristic at least once after opening the HRM app and connecting to the BLEFriend

Field Updates

The BLEFriend module includes a special 'DFU' bootloader that allows you to update the firmware over the air using a compatible device (such as a recent iPhone or iPod or a BLE-enabled Android device running Android 4.3 or later).

The benefit of this bootloader is that you can reprogram the flash contents of the MCU without having to purchase a HW debugger, using nothing but your tablet or phone to update the flash memory contents of the BLEFriend.

You can update the Firmware over the air but not over the USB/UART connection!

Requirements

In order to perform over the air field updates of the firmware on the nRF51822 based Bluefruit LE modules, you will need access to the following resources:

  • A Bluetooth Low Energy enabled iOS device (iPad 3rd generation or later, iPhone 5 or later, or a recent iPod Touch) or a BLE enabled Android device (running Android 4.3 or higher, for example the Nexus 4, Nexus 5, and the Nexus 7 2013)
  • The Bluefruit LE Connect app for Android (for Android devices)
  • The Bluefruit LE Connect app for iOS (for iOS devices)

To update using your Android or iOS device, continue on to the appropriate page in this guide.

While the DFU (Device Firmware Update) code running on the modules has several safety feature (CRC packet checks, caching and testing the entire firmware image before writing it, etc.) this procedure isn't without risk, however small. There is a small possibility you can brick your device in DFU mode, requiring access to a HW debugger like the J-Link to recover it.

Forcing DFU Mode

Performing firmware updates from within the Bluefruit LE Connect app will automatically cause the board to reset into DFU mode, but there may be situations where you need to force the device into DFU mode as well.

To force the device into DFU mode (to enable firmare updates on devices that are locked up from a bad Arduino sketch, for example) press and hold the DFU button when inserting the device if a button is available, or by setting hte DFU pin to GND when powering the device up (depending on the exact board you are using).

DFU Mode Confirmation

You will know that you are in DFU mode because the MODE LED will blink at a constant rate:

DFU Timeout

By default, the DFU code has a 5-minute timeout.  After 5 minutes in DFU mode, the device will revert back to the normal user code if any user code is present on the device.  To return back to DFU mode, you will need to hold down the DFU button and reset the device via a power cycle.

Once you're in DFU mode, continue on to the iOS or Android pages ahead.

Firmware Images

Bluefruit LE Connect will automatically download the appropriate firmware image for you, but if you need direct access to them the latest Bluefruit LE firmware images are always available in our Github repo at https://github.com/adafruit/Adafruit_BluefruitLE_Firmware

BLE Sniffer

Using a special firmware image provided by Nordic Semiconductors and the open source network analysis tool Wireshark, the BLEFriend can be converted into a low cost Bluetooth Low Energy sniffer.

Since nRF-Sniffer is a passive solution that is simply scanning packets over the air, there is the possibility of missing packets using this tool (or any other passive sniffing solution). In order to capture as many packets as possible, be sure to run the sniffer on a USB bus that isn't busy and avoid running it in a virtual machine since this can introduce significant latency over USB.

Select the Sniffer Target

The nRF-Sniffer can only sniff one device at a time, so the first step is getting the sniffer running and then selecting the device that you want to debug.

Start nRF-Sniffer by running the ble-sniffer_win executable (for example: ble-sniffer_win_1.0.1_1111_Sniffer.exe).

This will try to detect the device running the nRF-Sniffer firmware over a UART COM port.

If the board isn't detected right away type 'f' to erase any previous com port settings, or try removing and then re-inserting the sniffer while the console application is running.

Once the sniffer is found, you should see a list of all BLE devices that were detected in listening range:

In this particular case, we'll select device number 2, which is a BLEFriend running the standard UART firmware.

Type the device number you want to sniffer (in this case '2'), and you should see the device highlighted in the list, similar to the image below:

At this point you can type 'w', which will try to open wireshark and start pushing data out via a dedicate pipe created by the nRF-Sniffer utility.

Working with Wireshark

Once Wireshark has loaded, you should see the advertising packets streaming out from the selected BLE device at a regular intercal, as shown in the image below:

One of the key benefits of WireShark as an analysis tool is that it understands the raw packet formats and provides human-readable displays of the raw packet data.

The main way to interact with BLE data packets is to select one of the packets in the main window, and then expand the Bluetooth Low Energy Link Layer treeview item in the middle of the UI, as shown below:

Clicking on the Advertising Data entry in the treeview will highlight the relevant section of the raw payload at the bottom of the screen, but also provides human readable information about the payload that can save you a lot of time trying to debug or reverse engineer a device.

We can see, for example, that the device is advertising itself as a Bluetooth Low Energy only device ('BR/EDR Not Supported'), with a TX Power Level of 0dBm, and a single service is being advertised using a 128-bit UUID (the UART service in this case).

Capturing Exchanges Between Two Devices

If you wish to sniff data being exchanged between two BLE devices, you will need to establish a connection between the original device we selected above and a second BLE device (such as an iPhone or an Android tablet with BLE capabilities).

The nRF-Sniffer firmware is capable is listening the all of the exchanges that happen between these devices, but can not connect with a BLE peripheral or central device itself (it's a purely passive device).

Scan Response Packets

If you open up nRF UART on an Android or iOS device, and click the Connect button, the phone or tablet will start scanning for devices in range.  One of the side effects of this scanning process is that you may spot a new packet in Wireshark on an irregular basis, the 'SCAN_REQ' and 'SCAN_RSP' packets:

The Scan Response is an optional second advertising packet that some Bluetooth Low Energy periperhals use to provide additional information during the advertising phase.  The normal mandatory advertising packet is limited to 31 bytes, so the Bluetooth SIG includes the possibility to request a second advertising payload via the Scan Request.

You can see both of these transactions in the image above, and the Device Name that is included in the Scan Response payload (since the 128-bit UART Service UUID takes up most of the free space in the main advertising packet).

For more information on Scan Responses and the advertising process in Bluetooth Low Energy see our Introduction to Bluetooth Low Energy Guide.

Connection Request

Once we click on the UART device in nRF UART, the two device will attempt to connect to each other by means of a Connection Request, which is initiated by the central device (the phone or tablet).

We can see this CONNECT_REQ in the timeline in the image below:

Write Request

Once the connection has been established, we can see that the nRF UART application tries to write data to the BLEFriend via a Write Request to handle '0x001E' (which is the location of an entry in the attribute table since everything in BLE is made up of attributes).

What this write request is trying to do is enable the 'notify' bit on the UART service's TX characteristic  (0x001E is the handle for the CCCD or 'Client Characteristic Configuration Descriptor'). This bit enables an 'interrupt' of sorts to tell the BLEFriend that we want to be alerted every time there is new data available on the characteristic that transmits data from the BLEFriend to the phone or tablet.

Regular Data Requests

At this point you will start to see a lot of regular Empty PDU requests.  This is part of the way that Bluetooth Low Energy works.

Similar to USB, all BLE transaction are initiated by the bus 'Master', which is the central device (the tablet or phone).

In order to receive data from the bus slave (the peripheral device, or the BLEFriend in this particular case) the central device sends a 'ping' of sorts to the peripheral at a delay known as the 'connection interval' (not to be confused with the one-time connection highlighted earlier in this tutorial).

We can see pairs of transaction that happen at a reasonably consistent interval, but no data is exchanged since the BLEFriend (the peripheral) is saying 'sorry, I don't have any data for you':

Notify Event Data

To see an actual data transaction, we simply need to enter some text in our terminal emulator SW which will cause the BLEFriend to send the data to nRF UART using the UART service.

Entering the string 'This is a test' in the terminal emulator, we can see the first packet being sent below (only the 'T' character is transmitted because the packets are sent out faster than we enter the characters into the terminal emulator):

What this 4-byte 'Bluetooth Attribute Protocol' packet is actually saying is that attribute 0x001C (the location of the TX characteristic in the attribute table) has been updated, and the new value is '0x54', which corresponds to the letter 'T'.

Scrolling a bit further down we can see an example where more than one character was sent in a single transction ('te' in this case):

The results of this transaction in the nRF UART application can be seen below:

Closing Wireshark and nRF-Sniffer

When you're done debugging, you can save the session to a file for later analysis, or just close Wireshark right away and then close the nRF-Sniffer console window to end the debug session.

Moving Forward

A sniffer is an incredibly powerful and valuable tool debugging your own hardware, reverse engineering existing BLE peripherals, or just to learn the ins and outs of how Bluetooth Low Energy actually works on the a packet by packet level.

You won't learn everything there is to know about BLE in a day, but a good book on BLE, a copy of the Bluetooth 4.1 Core Specification and a sniffer will go a long way to teaching you most of the important things there is to know about BLE in the real world.

GATT Service Details

Data in Bluetooth Low Energy is organized around units called 'GATT Services' and 'GATT Characteristics'.  To expose data to another device, you must instantiate at least one service on your device.

Adafruit's Bluefruit LE Pro modules support some 'standard' services, described below (more may be added in the future).

UART Service

The UART Service is the standard means of sending and receiving data between connected devices, and simulates a familiar two-line UART interface (one line to transmit data, another to receive it).

The service is described in detail on the dedicated UART Service page.

Software Resources

To help you get your Bluefruit LE module talking to other Central devices, we've put together a number of open source tools for most of the major platforms supporting Bluetooth Low Energy.

Bluefruit LE Client Apps and Libraries

Adafruit has put together the following mobile or desktop apps and libraries to make it as easy as possible to get your Bluefruit LE module talking to your mobile device or laptop, with full source available where possible:

Bluefruit LE Connect (Android/Java)

Bluetooth Low Energy support was added to Android starting with Android 4.3 (though it was only really stable starting with 4.4), and we've already released Bluefruit LE Connect to the Play Store.

The full source code for Bluefruit LE Connect for Android is also available on Github to help you get started with your own Android apps.  You'll need a recent version of Android Studio to use this project.

Bluefruit LE Connect  (iOS/Swift)

Apple was very early to adopt Bluetooth Low Energy, and we also have an iOS version of the Bluefruit LE Connect app available in Apple's app store.

The full swift source code for Bluefruit LE Connect for iOS is also available on Github. You'll need XCode and access to Apple's developper program to use this project:

Version 2.x of the app is a complete rewrite that includes iOS, OS X GUI and OS X command-line tools in a single codebase.

Bluefruit LE Connect for OS X (Swift)

This OS X desktop application is based on the same V2.x codebase as the iOS app, and gives you access to BLE UART, basic Pin I/O and OTA DFU firmware updates from the convenience of your laptop or mac.

This is a great choice for logging sensor data locally and exporting it as a CSV, JSON or XML file for parsing in another application, and uses the native hardware on your computer so no BLE dongle is required on any recent mac.

The full source is also available on Github.

Bluefruit LE Command Line Updater for OS X (Swift)

This experimental command line tool is unsupported and provided purely as a proof of concept, but can be used to allow firmware updates for Bluefruit devices from the command line.

This utility performs automatic firmware updates similar to the way that the GUI application does, by checking the firmware version on your Bluefruit device (via the Device Information Service), and comparing this against the firmware versions available online, downloading files in the background if appropriate.

Simply install the pre-compiled tool via the DMG file and place it somewhere in the system path, or run the file locally via './bluefruit' to see the help menu:

Download: file
$ ./bluefruit
bluefruit v0.3
Usage:
	bluefruit <command> [options...]

Commands:
	Scan peripherals:   scan
	Automatic update:   update [--enable-beta] [--uuid <uuid>]
	Custom firmware:    dfu --hex <filename> [--init <filename>] [--uuid <uuid>]
	Show this screen:   --help
	Show version:       --version

Options:
	--uuid <uuid>    If present the peripheral with that uuid is used. If not present a list of peripherals is displayed
	--enable-beta    If not present only stable versions are used

Short syntax:
	-u = --uuid, -b = --enable-beta, -h = --hex, -i = --init, -v = --version, -? = --help

Deprecated: Bluefruit Buddy (OS X)

This native OS X application is a basic proof of concept app that allows you to connect to your Bluefruit LE module using most recent macbooks or iMacs. You can get basic information about the modules and use the UART service to send and receive data.

The full source for the application is available in the github repo at Adafruit_BluefruitLE_OSX.

ABLE (Cross Platform/Node+Electron)

ABLE (Adafruit Bluefruit LE Desktop) is a cross-platform desktop application based on Sandeep Misty's noble library and the Electron project from Github (used by Atom).

It runs on OS X, Windows 7+ and select flavours of Linux (Ubuntu tested locally).  Windows 7 support is particularly interesting since Windows 7 has no native support for Bluetooth Low Energy but the noble library talks directly to supported Bluetooth 4.0 USB dongles to emulate BLE on the system (though at this stage it's still in early BETA and drops the connection and takes more care to work with).

This app allows you to collect sensor data or perform many of the same functionality offered by the mobile Bluefruit LE Connect apps, but on the desktop.

The app is still in BETA, but full source is available in addition to the easy to use pre-compiled binaries.

Bluefruit LE Python Wrapper

As a proof of concept, we've played around a bit with getting Python working with the native Bluetooth APIs on OS X and the latest version of Bluez on certain Linux targets.

There are currently example sketches showing how to retreive BLE UART data as well as some basic details from the Device Information Service (DIS).

This isn't an actively support project and was more of an experiment, but if you have a recent Macbook or a Raspberry Pi and know Python, you might want to look at Adafruit_Python_BluefruitLE in our github account.

Debug Tools

If your sense of adventure gets the better of you, and your Bluefruit LE module goes off into the weeds, the following tools might be useful to get it back from unknown lands.

These debug tools are provided purely as a convenience for advanced users for device recovery purposes, and are not recommended unless you're OK with potentially bricking your board. Use them at your own risk.

AdaLink (Python)

This command line tool is a python-based wrapper for programming ARM MCUs using either a Segger J-Link or an STLink/V2. You can use it to reflash your Bluefruit LE module using the latest firmware from the Bluefruit LE firmware repo.

Details on how to use the tool are available in the readme.md file on the main Adafruit_Adalink repo on Github.

Completely reprogramming a Bluefruit LE module with AdaLink would require four files, and would look something like this (using a JLink):

Download: file
adalink nrf51822 --programmer jlink --wipe
  --program-hex "Adafruit_BluefruitLE_Firmware/softdevice/s110_nrf51_8.0.0_softdevice.hex" 
  --program-hex "Adafruit_BluefruitLE_Firmware/bootloader/bootloader_0002.hex"
  --program-hex "Adafruit_BluefruitLE_Firmware/0.6.7/blefriend32/blefriend32_s110_xxac_0_6_7_150917_blefriend32.hex"
  --program-hex "Adafruit_BluefruitLE_Firmware/0.6.7/blefriend32/blefriend32_s110_xxac_0_6_7_150917_blefriend32_signature.hex"

You can also use the AdaLink tool to get some basic information about your module, such as which SoftDevice is currently programmed or the IC revision (16KB SRAM or 32KB SRAM) via the --info command:

Download: file
$ adalink nrf51822 -p jlink --info
Hardware ID : QFACA10 (32KB)
Segger ID   : nRF51822_xxAC
SD Version  : S110 8.0.0
Device Addr : **:**:**:**:**:**
Device ID   : ****************

Adafruit nRF51822 Flasher (Python)

Adafruit's nRF51822 Flasher is an internal Python tool we use in production to flash boards as they go through the test procedures and off the assembly line, or just testing against different firmware releases when debugging.

It relies on AdaLink or OpenOCD beneath the surface (see above), but you can use this command line tool to flash your nRF51822 with a specific SoftDevice, Bootloader and Bluefruit firmware combination.

It currently supports using either a Segger J-Link or STLink/V2 via AdaLink, or GPIO on a Raspberry Pi if you don't have access to a traditional ARM SWD debugger.  (A pre-built version of OpenOCD for the RPi is included in the repo since building it from scratch takes a long time on the original RPi.)

We don't provide active support for this tool since it's purely an internal project, but made it public just in case it might help an adventurous customer debrick a board on their own.

Download: file
$ python flash.py --jtag=jlink --board=blefriend32 --softdevice=8.0.0 --bootloader=2 --firmware=0.6.7
jtag       	: jlink
softdevice 	: 8.0.0
bootloader 	: 2
board      	: blefriend32
firmware   	: 0.6.7
Writing Softdevice + DFU bootloader + Application to flash memory
adalink -v nrf51822 --programmer jlink --wipe --program-hex "Adafruit_BluefruitLE_Firmware/softdevice/s110_nrf51_8.0.0_softdevice.hex" --program-hex "Adafruit_BluefruitLE_Firmware/bootloader/bootloader_0002.hex" --program-hex "Adafruit_BluefruitLE_Firmware/0.6.7/blefriend32/blefriend32_s110_xxac_0_6_7_150917_blefriend32.hex" --program-hex "Adafruit_BluefruitLE_Firmware/0.6.7/blefriend32/blefriend32_s110_xxac_0_6_7_150917_blefriend32_signature.hex"
...

Device Recovery

Sometimes, bad things unfortunately happen. Thankfully, 99% of the time it's purely a SW issue and the Bluefruit devices have a robust bootloader with some fail safes that can almost always recover your device.

How to Recover a Bluefruit Board

1. Force DFU Mode at Startup

The first step is to force your board into a special bootloader mode, which will prevent any faulty user sketches or corrupted config data from causing problems.

  • Connect the DFU pin to GND with a jumper cable, or if your board has a DFU button hold the button down when adding power to your board (connecting the USB cable, etc.)
  • Once the device is powered, you should see a faster DFU MODE blinky pattern that lets you know you are in bootloader mode.
  • Now remove the jumper cable between DFU and GND (to prevent going into DFU mode when you reset)
Remove the jumper cable between DFU and GND once you are in DFU mode so that you exit it during the next reset!

2. Update the Bluefruit Firmware

Next, update your device to the latest Bluefruit firmware using the Bluefruit LE Connect app. We regularly fix bugs, and it's always a good idea to be on the latest release.

You can perform a firmware update in DFU mode, although the Bluefruit board may appear as DfuTarg in the Bluefruit LE Connect app, and you will will need to select the right firmware 'family' for you board.

Because bootloader mode is a fail safe mode and has a small subset of Bluefruit's features, we can't tell the Bluefruit LE Connect app very many details about our HW. As such, you will need to indicate which firmware type to flash ... specifically, whether to flash the UART of SPI based firmware. Be sure to select the right one, based on your product and the table below:

BLEFRIEND32 Firmware (UART, 32KB SRAM)

BLESPIFRIEND Firmware (SPI)

3. Flash a Test Sketch

Once the core Bluefruit firmware has been updated, flash a test sketch to the device from the Arduino IDE, such as the following blinky code:

Download: file
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

4. Perform a Factory Reset

Once the core Bluefruit firmware has been updated, the final step is to perform a factory reset.

  • With the board still powered up, connect the DFU pin to GND
  • Leave the pin set to GND (or hold the DFU button down) for >5 seconds until the BLUE status LED starts to blink
  • Remove the DFU jumper cable or release the DFU button

This will cause a factory reset which will wipe all config data, and should restore your board, getting you back to a normal state in most situations!

Still Having Problems?

Hop on over to our support forums clearly explaining your problem along with the following information, and, we'll be happy to help:

  • You product name and ideally the product ID
  • The Bluefruit firmware version you are using (available at the top of the Serial Monitor output on most example sketches)
  • The Operating System your are using
  • The Arduino IDE version you are using

Providing the above information in your first post will skip a round of two of back and forth and you'll get an answer from us quicker, saving everyone time and effort!

Be sure to see the FAQ section of this learning guide as well, which has answer to many common problems!

Can I talk to Classic Bluetooth devices with a Bluefruit LE modules?

No.  Bluetooth Low Energy and 'Classic' Bluetooth are both part of the same Bluetooth Core Specification -- defined and maintained by the Bluetooth SIG -- but they are completely different protocols operating with different physical constraints and requirements.  The two protocols can't talk to each other directly.

Can my Bluefruit LE module connect to other Bluefruit LE peripherals

No, the Bluefruit LE firmware from Adafruit is currently peripheral only, and doesn't run in Central mode, which would cause the module to behave similar to your mobile phone or BLE enabled laptop.

If you required Central support, you should look at the newer nRF52832 based products like the Adafruit Feather nRF52 Bluefruit LE, which contains a SoftDevice which is capable of running in either Central or Peripheral mode. The nRF518322 based products (such as the one used in this learning guide) are not capable of running in Central mode because it isn't supported by the SoftDevice they use, and it isn't possible to update the SoftDevice safely without special hardware.

I just got my Bluefruit board and  when I run a sketch it hangs forever on the 'Connecting...' stage!

There are several possible explanations here, but the first thing to try is to:

  1. Disconnect and close the Bluefruit LE Connect app if it's open
  2. Disable BLE on your mobile device
  3. Restart your Bluefruit sketch and HW
  4. Turn BLE back on again (on the mobile device)
  5. Open the Bluefruit LE Connect mobile app again and try to connect again

If problems persist, try performing a Factory Reset of your device (see the appropriate learning guide for details on how to do this since it varies from one board to another).

Why are none of my changes persisting when I reset with the sample sketches?

In order to ensure that the Bluefruit LE modules are in a known state for the Adafruit demo sketches, most of them perform a factory reset at the start of the sketch.

This is useful to ensure that the sketch functions properly, but has the side effect of erasing any custom user data in NVM and setting everything back to factory defaults every time your board comes out of reset and the sketch runs.

To disable factory reset, open the demo sketch and find the FACTORYRESET_ENABLE flag and set this to '0', which will prevent the factory reset from happening at startup.

If you don't see the 'FACTORYRESET_ENABLE' flag in your .ino sketch file, you probably have an older version of the sketches and may need to update to the latest version via the Arduino library manager.

Do I need CTS and RTS on my UART based Bluefruit LE Module?

Using CTS and RTS isn't strictly necessary when using HW serial, but they should both be used with SW serial, or any time that a lot of data is being transmitted.

The reason behind the need for CTS and RTS is that the UART block on the nRF51822 isn't very robust, and early versions of the chip had an extremely small FIFO meaning that the UART peripheral was quickly overwhelmed.

Using CTS and RTS significantly improves the reliability of the UART connection since these two pins tell the device on the other end when they need to wait while the existing buffered data is processed.

To enable CTS and RTS support, go into the BluefruitConfig.h file in your sketch folder and simply assign an appropriate pin to the macros dedicated to those functions (they may be set to -1 if they aren't currently being used).

Enabling both of these pins should solve any data reliability issues you are having with large commands, or when transmitting a number of commands in a row.

How can I update to the latest Bluefruit LE Firmware?

The easiest way to keep your Bluefruit LE modules up to date is with our Bluefruit LE Connect app for Android or Bluefruit LE Connect for iOS.  Both of these apps include a firmware update feature that allows you to automatically download the latest firmware and flash your Bluefruit LE device in as safe and painless a manner as possible. You can also roll back to older versions of the Bluefruit LE firmware using these apps if you need to do some testing on a previous version.

Which firmware version supports 'xxx'?

We regularly release Bluefruit LE firmware images with bug fixes and new features. Each AT command in this learning guide lists the minimum firmware version required to use that command, but for a higher level overview of the changes from one firmware version to the next, consult the firmware history page.

Does my Bluefruit LE device support ANCS?

ANCS is on the roadmap for us (most likely in the 0.7.x release family), but we don't currently support it since there are some unusual edge cases when implementing it as a service.

My Bluefruit LE device is stuck in DFU mode ... what can I do?

If your device is stuck in DFU mode for some reason and the firmware was corrupted, you have several options.

First, try a factory reset by holding down the DFU button for about 10 seconds until the CONN LED starts flashing, then release the DFU button to perform a factory reset. 

If this doesn't work, you may need to reflash your firmware starting from DFU mode, which can be done in one of the following ways:

Bluefruit LE Connect (Android)

  • Place the module in DFU mode (constant LED blinky)
  • Open Bluefruit LE Connect
  • Connect to the 'DfuTarg' device
  • Once connected, you will see a screen with some basic device information. Click the '...' in the top-right corner and select Firmware Updates
  • Click the Use Custom Firmware button
  • Select the appropriate .hex and .init files (copied from the Bluefruit LE Firmware repo) ... for the BLEFRIEND32 firmware version 0.6.7, this would be:
    • Hex File: blefriend32_s110_xxac_0_6_7_150917_blefriend32.hex
    • Init File: blefriend32_s110_xxac_0_6_7_150917_blefriend32_init.dat
  • Click Start Update

Unfortunately, the iOS app doesn't yet support custom firmware updates from DFU mode yet, but we will get this into the next release.

Nordic nRF Toolbox

You can also use Nordic's nRF Toolbox application to update the firmware using the OTA bootloader.

On Android:

  • Open nRF Toolbox (using the latest version)
  • Click the DFU icon
  • Click the Select File button
  • Select Application from the radio button list, then click OK
  • Find the appropriate .hex file (ex. 'blefriend32_s110_xxac_0_6_7_150917_blefriend32.hex')
  • When asked about the 'Init packet', indicate Yes, and select the appropriate *_init.dat file (for example: 'blefriend32_s110_xxac_0_6_7_150917_blefriend32_init.dat').
  • Click the Select Device button at the bottom of the main screen and find the DfuTarg device, clicking on it
  • Click the Upload button, which should now be enabled on the home screen
  • This will begin the DFU update process which should cause the firmware to be updated or restored on your Bluefruit LE module

On iOS:

  • Create a .zip file containing the .hex file and init.dat file that you will use for the firmware update.  For example:
    • Rename 'blefriend32_s110_xxac_0_6_7_150917_blefriend32.hex' to application.hex
    • Rename 'blefriend32_s110_xxac_0_6_7_150917_blefriend32_init.dat' to application.dat
  • Upload the .zip file containing the application.hex and application.dat files to your iPhone using uTunes, as described here
  • Open the nRF Toolbox app (using the latest version)
  • Click the DFU icon
  • Click the Select File text label
  • Switch to User Files to see the .zip file you uploaded above
  • Select the .zip file (ex. blefriend32_065.zip)
  • On the main screen select Select File Type
  • Select application
  • On the main screen select SELECT DEVICE
  • Select DfuTarg
  • Click the Upload button which should now be enabled
  • This will begin the DFU process and your Bluefruit LE module will reset when the update is complete
  • If you get the normal 2 or 3 pulse blinky pattern, the update worked!

Adafruit_nRF51822_Flasher

As a last resort, if you have access to a Raspberry Pi, a Segger J-Link or a STLink/V2, you can also try manually reflashing the entire device, as described in the FAQ above, with further details on the Software Resources page.

How do I reflash my Bluefruit LE module over SWD?

Reflashing Bluefruit LE modules over SWD (ex. switching to the sniffer firmware and back) is at your own risk and can lead to a bricked device, and we can't offer any support for this operation!  You're on your own here, and there are unfortunately 1,000,000 things that can go wrong, which is why we offer two separate Bluefruit LE Friend boards -- the sniffer and the normal Bluefruit LE Friend board with the non-sniffer firmware, which provides a bootloader with fail safe features that prevents you from ever bricking boards via OTA updates.

AdaLink (SWD/JTAG Debugger Wrapper)

Transitioning between the two board types (sniffer and Bluefruit LE module) is unfortunately not a risk-free operation, and requires external hardware, software and know-how to get right, which is why it isn't covered by our support team.

That said ... if you're determined to go down that lonely road, and you have a Segger J-Link (which is what we use internally for production and development), or have already erased your Bluefruit LE device, you should have a look at AdaLink, which is the tool we use internally to flash the four files required to restore a Bluefruit LE module. (Note: recent version of AdaLink also support the cheaper STLink/V2, though the J-Link is generally more robust if you are going to purchase a debugger for long term use.)

The mandatory Intel Hex files are available in the Bluefruit LE Firmware repo. You will need to flash: 

  • An appropriate bootloader image
  • An appropriate SoftDevice image
  • The Bluefruit LE firmware image
  • The matching signature file containing a CRC check so that the bootloader accepts the firmware image above (located in the same folder as the firmware image)

The appropriate files are generally listed in the version control .xml file in the firmware repository.

If you are trying to flash the sniffer firmware (at your own risk!), you only need to flash a single .hex file, which you can find here. The sniffer doesn't require a SoftDevice image, and doesn't use the fail-safe bootloader -- which is why changing is a one way and risky operation if you don't have a supported SWD debugger.

Adafruit_nF51822_Flasher

We also have an internal python tool available that sits one level higher than AdaLink (referenced above), and makes it easier to flash specific versions of the official firmware to a Bluefruit LE module.  For details, see the Adafruit_nRF51822_Flasher repo.

Can I access BETA firmware releases?

The latest versions of the Bluefruit LE Connect applications for iOS and Android allow you to optionally update your Bluefruit LE modules with pre-release or BETA firmware.  

This functionality is primarilly provided as a debug and testing mechanism for support issues in the forum, and should only be used when trying to identify and resolve specific issues with your modules!

Enabling BETA Releases on iOS

  • Make sure you have at least version 1.7.1 of Bluefruit LE Connect
  • Go to the Settings page
  • Scroll to the bottom of the Settings page until you find Bluefruit LE
  • Click on the Bluefruit LE icon and enable the Show beta releases switch
  • You should be able to see any BETA releases available in the firmware repo now when you use Bluefruit LE Connect

Enabling BETA Releases on Android

  • Make sure you have the latest version of Bluefruit LE Connect
  • Open the Bluefruit LE Connect application
  • Click the "..." icon in the top-right corner of the app's home screen
  • Select Settings
  • Scroll down to the Software Updates section and enable Show beta releases
  • You should be able to see any BETA releases available in the firmware repo now when you use Bluefruit LE Connect

Why can't I see my Bluefruit LE device after upgrading to Android 6.0?

In Android 6.0 there were some important security changes that affect Bluetooth Low Energy devices.  If location services are unavailable (meaning the GPS is turned off) you won't be able to see Bluetooth Low Energy devices advertising either. See this issue for details.

Be sure to enable location services on your Android 6.0 device when using Bluefruit LE Connect or other Bluetooth Low Energy applications with your Bluefruit LE modules.

What is the theoretical speed limit for BLE?

This depends on a variety of factors, and is determined by the capabilities of the central device (the mobile phone, etc.) as much as the peripheral.

Taking the HW limits on the nR51822 into account (max 6 packets per connection interval, and a minimum connection interval of 7.5ms) you end up with the following theoretical limits on various mobile operating systems:

  • iPhone 5/6 + IOS 8.0/8.1
    6 packets * 20 bytes * 1/0.030 s = 4 kB/s = 32 kbps
  • iPhone 5/6 + IOS 8.2/8.3
    3 packets * 20 bytes * 1/0.030 s = 2 kB/s = 16 kbps
  • iPhone 5/6 + IOS 8.x with nRF8001
    1 packet * 20 bytes * 1/0.030 s = 0.67 kB/s = 5.3 kbps
  • Nexus 4
    4 packets * 20 bytes * 1/0.0075 s = 10.6 kB/s = 84 kbps
  • Nordic Master Emulator Firmware (MEFW) with nRF51822 0.9.0
    1 packet * 20 bytes * 1/0.0075 = 2.67 kB/s = 21.33 kbps
  • Nordic Master Emulator Firmware (MEFW) with nRF51822 0.11.0
    6 packets * 20 bytes * 1/0.0075 = 16 kB/s = 128 kbps

There are also some limits imposed by the Bluefruit LE firmware, but we are actively working to significantly improve the throughput in the upcoming 0.7.0 release, which will be available Q2 2016.  The above figures are useful as a theoretical maximum to decide if BLE is appropriate for you project or not.

UPDATE: For more specific details on the limitations of various Android versions and phones, see this helpful post from Nordic Semiconductors.

Can my Bluefruit board detect other Bluefruit boards or Central devices?

No. All of our Bluefruit LE modules currently operate in peripheral mode, which means they can only advertise their own existence via the advertising payload. The central device (usually your phone or laptop) is responsible for listening for these advertising packets, starting the connection process, and inititating any transactions between the devices.  There is no way for a Bluefruit module to detect other Bluefruit modules or central devices in range, they can only send their own advertising data out and wait for a connection request to come in.

How can I determine the distance between my Bluefruit module and my phone in m/ft?

The short answer is: you can't.

RF devices normally measure signal strength using RSSI, which stands for Received Signal Strength Indicator, which is measured in dBm.  The closer the devices are the strong the RSSI value generally is (-90dBm is much weaker than -60dBm, for example), but there is no reliable relationship between RSSI values in dBm and distance in the real world.  If there is a wall between devices, RSSI will fall.  If there is a lot of interference on the same 2.4GHz band, RSSI will fall. Depending on the device, if you simply change the antenna orientation, RSSI will fall.  You can read the RSSI value between two connected devices with the AT+BLEGETRSSI command, but there are no meaningful and repeatable conclusions that can be drawn from this value about distance other than perhaps 'farther' or 'closer' in a very loose sense of the terms.

How far away from my phone can I have my Bluefruit LE module?

This depends on a number of factors beyond the module itself such as antenna orientation, the antenna design on the phone, transmit power on the sending node, competing traffic in the same 2.4GHz bandwidth, obstacles between end points, etc.

It could be as low as a couple meters up to about 10 meters line of sight, but generally Bluetooth Low Energy is designed for very short range and will work best in the 5-6 meter or less range for reliable communication, assuming normal Bluefruit firmware settings.

How many GATT services and characteristics can I create?

For firmware 0.7.0 and higher, the following limitations are present:

  • Maximum number of services: 10
  • Maximum number of characteristics: 30
  • Maximum buffer size for each characteristic: 32 bytes
  • Maximum number of CCCDs: 16

Is it possible to modify or disable the built in GATT services and characteristics (DIS, DFU, etc.)?

No, unfortunately you can't. We rely on the Device Information Service (DIS) contents to know which firmware and bootloader version you are running, and wouldn't be able to provide firmware updates without being able to trust this information, which i why it's both mandatory and read only.

Similarly, the DFU service is mandatory to maintain over the air updates and disabling it would create more problems that it's presence would cause.

How can I use BlueZ and gatttool with Bluefruit modules?

BlueZ has a bit of a learning curve associated with it, but you can find some notes below on one option to send and receive data using the BLE UART Service built into all of our Bluefruit LE modules and boards.

These commands may change with different versions of BlueZ. Version 5.21 was used below.

Download: file
# Initialise the USB dongle
$ sudo hciconfig hci0 up

# Scan for the UART BLE device
$ sudo hcitool lescan
  D6:4E:06:4F:72:86 UART

# Start gatttool, pointing to the UART device found above
$ sudo gatttool -b D6:4E:06:4F:72:86 -I -t random --sec-level=high

  [D6:4E:06:4F:72:86][LE]> connect
  Attempting to connect to D6:4E:06:4F:72:86
  Connection successful
  
# Scan for primary GATT Services
  [D6:4E:06:4F:72:86][LE]> primary
  attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
  attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb
  attr handle: 0x0009, end grp handle: 0x000e uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
  attr handle: 0x000f, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb

# Get the handles for the entries in the UART service (handle 0x0009)
  [D6:4E:06:4F:72:86][LE]> char-desc
  handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
  handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
  handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
  handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
  handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb
  handle: 0x0009, uuid: 00002800-0000-1000-8000-00805f9b34fb
  handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x000b, uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
  handle: 0x000c, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x000d, uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e
  handle: 0x000e, uuid: 00002902-0000-1000-8000-00805f9b34fb
  handle: 0x000f, uuid: 00002800-0000-1000-8000-00805f9b34fb
  handle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb
  handle: 0x0011, uuid: 00002a27-0000-1000-8000-00805f9b34fb

# 6e400002 (handle 0x000b) = TX characteristic
# 6e400003 (handle 0x000d) = RX characteristic

# Optional (but maybe helpful) ... scan for CCCD entries
  [D6:4E:06:4F:72:86][LE]> char-read-uuid 2902
  handle: 0x000e 	 value: 00 00 
  
# Enable notifications on the RX characteristic (CCCD handle = 0x000e)
# 0100 = get notifications
# 0200 = get indications
# 0300 = get notifications + indications
# 0000 = disable notifications + indications
  [D6:4E:06:4F:72:86][LE]> char-write-req 0x000e 0100
  Characteristic value was written successfully

# Just to make sure it was updated
  [D6:4E:06:4F:72:86][LE]> char-read-hnd 0x000e
  Characteristic value/descriptor: 01 00 
  
# Writing "test" in the Serial Monitor of the Arduino sketch should
# cause this output not that notifications are enabled:
  Notification handle = 0x000d value: 74 65 73 74 

# Write something to the TX characteristic (handle = 0x000b)
# This should cause E F G H to appear in the Serial Monitor
  [D6:4E:06:4F:72:86][LE]> char-write-cmd 0x000b 45         
  [D6:4E:06:4F:72:86][LE]> char-write-cmd 0x000b 46
  [D6:4E:06:4F:72:86][LE]> char-write-cmd 0x000b 47
  [D6:4E:06:4F:72:86][LE]> char-write-cmd 0x000b 48

# To send multiple bytes
  [D6:4E:06:4F:72:86][LE]> char-write-cmd 0x000B 707172737475
  
# If you are running the callbackEcho sketch and notifications
# are enabled you should get this response after the above cmd:
  Notification handle = 0x000d value: 70 71 72 73 74 75 

--------------

# If you just want to enable constant listening, enter the following command from the CLI:
$ sudo gatttool -b D6:4E:06:4F:72:86 -t random --char-write-req -a 0x000e -n 0100 --listen

# This should give us the following output as data is written on the Uno,
# though we can't send anything back:
  Characteristic value was written successfully
  Notification handle = 0x000d value: 74 65 73 74 
  Notification handle = 0x000d value: 6d 6f 72 65 20 74 65 73 74 

Can I use the IRQ pin to wake my MCU up from sleep when BLE UART data is available?

No, on SPI-based boards the IRQ pin is used to indicate that an SDEP response is available to an SDEP command. For example, when you sent the `AT+BLEUARTRX` command as an SDEP message, the Bluefruit firmware running on the nRF51822 will parse the message, prepare an SDEP response, and trigger the IRQ pin to tell the MCU that the response is ready. This is completely independant from the BLE UART service, which doesn't have interrupt capability at present.

Can I also update the sketch running on the device using Bluefruit LE Connect?

No, only the core firmware can be updated over the air. Sketches need to be loaded using the Arduino IDE and serial bootloader.

This guide was first published on Nov 19, 2014. It was last updated on Nov 19, 2014.