Beacon demo for the BLE API using the nRF51822 native mode drivers

Dependencies:   BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1

Introduction

Bluetooth Low Energy Beacons are a service that allow for highly localized positioning. The Beacon service is particularly useful for indoor positioning, low power positioning and location aware software. A particular use of the Beacon service is iBeacon. The iBeacon standard is a Apple specific implementation of Beacons.

The Basics

The Beacon service is a BLE Service that operates in advertising mode only. A Beacon service advertises 4 things:

  • A company ID
  • A unique UUID (unique to a retailer)
  • A Major number (ex a store number)
  • A Minor number (ex a location in the store)
  • Signal Strength at transmitter (requires calibration per each device)

These pieces of information are all you need for a Beacon service to work. The majority of the heavy lifting is done by the smart phone application that reads these four fields and then uses a web app or a database of some sort to turn these numbers into valuable information about what you are near and how near you are to it.

The signal strength field is compared to the actual signal strength at the receiver to determine how close the beacon is to the phone. The number used is the calibrated signal strength 1 meter from the device. By doing this 1 meter increments can be used to measure distance from the Beacon. The distances usually get broken down into 3 ranges:

  • Immediate: Within a few centimeters
  • Near: Within a couple of meters
  • Far: Greater than 10 meters away

Company ID's are used to make beacon UUID's unique to companies. Some example company UUID's are:

  • 0x004C - Apple Inc.
  • 0x0059 - Nordic Semiconductor
  • 0x0078 - Nike
  • ​0x015D - Estimote
  • ​0x0171 - Amazon Fulfillment Service
  • 0xFFFF - reserved for internal testing before release

Here is the Bluetooth SIG's full list of Company ID's.

Example : Coffee Shop X

For example, if a smartphone app reads a BLE Beacon with UUID = 0x1234546... , Major Number=5, Minor number = 3, it would check that against a database. From that database it would find out that UUID 0x123456... is owned by Coffee Shop X, that Major number 5 belongs to the store on main street and that Minor number 3 belongs to the coffee rack in that store. Then the application could check to see if there are any deals for the Coffee Shop X on Main Street on Coffee today. If there are any deals the phone could then alert the user and display a coupon code.

Example : museum

The Beacon service also provides a way for the phone to tell how close it is to the beacon. This can be useful for location aware applications, such as in a museum. For example, the smartphone reads a BLE Beacon with UUID = 0x98765....., Major Number=1, minor number = 0. The smartphone then looks this up in a database and find the UUID is for the Natural Science Museum, Major Number 1 = the Art Gallery room 1, and the minor number 0 = an abstract painting of a duck. If we assume all the paintings are spread out at 10feet each, then the application can sense when you are within 3 feet of the painting (based on signal strength of the Beacon) and give the user information about the painting they are approaching.

Technical Details

An iBeacon is just a normal Bluetooth LE device broadcasting advertisements with special data shoved into the Manufacturer Specific Data field.

The iBeacon prefix is little more than metadata about the advertisement packet.

BytesDatadescription
0,1,20x020106This sets the flags for General Discoverable and BR/EDR not supported
3,40x1AFFThis says the length of the Manufacturer specific data field will be 26 bytes
0,10x4C00Company ID
20x02ID
30x15length of remaining data in bytes (16B UUID+ 2B major, 2B minor, 1B Txpower)

Note that bytes 0-4 are set implicitly by the API by declaring the advertising data to be LE General Discoverable and BR/EDR not supported. The remaining fields that make up an iBeacon advertisement packet can be clearly seen in the image below.

http://www.havlena.net/wp-content/uploads/ibeacon-packet.png

For a more depth explanation please see these well done explanations:

Committer:
rgrover1
Date:
Fri Nov 28 14:17:32 2014 +0000
Revision:
48:2f0f293a4966
Parent:
47:447eb23e67e2
Child:
50:7bc38f01d2d3
updating to 0.2.5 of the BLE_API

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ktownsend 0:7613d21e5974 1 /* mbed Microcontroller Library
ktownsend 0:7613d21e5974 2 * Copyright (c) 2006-2013 ARM Limited
ktownsend 0:7613d21e5974 3 *
ktownsend 0:7613d21e5974 4 * Licensed under the Apache License, Version 2.0 (the "License");
ktownsend 0:7613d21e5974 5 * you may not use this file except in compliance with the License.
ktownsend 0:7613d21e5974 6 * You may obtain a copy of the License at
ktownsend 0:7613d21e5974 7 *
ktownsend 0:7613d21e5974 8 * http://www.apache.org/licenses/LICENSE-2.0
ktownsend 0:7613d21e5974 9 *
ktownsend 0:7613d21e5974 10 * Unless required by applicable law or agreed to in writing, software
ktownsend 0:7613d21e5974 11 * distributed under the License is distributed on an "AS IS" BASIS,
ktownsend 0:7613d21e5974 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ktownsend 0:7613d21e5974 13 * See the License for the specific language governing permissions and
ktownsend 0:7613d21e5974 14 * limitations under the License.
ktownsend 0:7613d21e5974 15 */
ktownsend 0:7613d21e5974 16
ktownsend 0:7613d21e5974 17 #include "mbed.h"
Rohit Grover 32:7b7093b653a8 18 #include "BLEDevice.h"
ktownsend 0:7613d21e5974 19
Rohit Grover 32:7b7093b653a8 20 BLEDevice ble;
Rohit Grover 31:93e50a3c3dc6 21
Rohit Grover 10:391c1acf4b9d 22 /*
Rohit Grover 10:391c1acf4b9d 23 * For this demo application, populate the beacon advertisement payload
Rohit Grover 15:4e1b36b73213 24 * with 2 AD structures: FLAG and MSD (manufacturer specific data).
Rohit Grover 10:391c1acf4b9d 25 *
Rohit Grover 10:391c1acf4b9d 26 * Reference:
Rohit Grover 10:391c1acf4b9d 27 * Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
Rohit Grover 10:391c1acf4b9d 28 */
ktownsend 0:7613d21e5974 29
Rohit Grover 14:dfdf0c8b1c09 30 /*
Rohit Grover 15:4e1b36b73213 31 * The Beacon payload (encapsulated within the MSD advertising data structure)
Rohit Grover 15:4e1b36b73213 32 * has the following composition:
rgrover1 44:71ff94cd9c1d 33 * 128-Bit UUID = 01 12 23 34 45 56 67 78 89 9A AB BC CD DE EF F0
Rohit Grover 10:391c1acf4b9d 34 * Major/Minor = 0000 / 0000
Rohit Grover 10:391c1acf4b9d 35 * Tx Power = C8
Rohit Grover 10:391c1acf4b9d 36 */
rgrover1 41:51f585d14675 37 const uint8_t beaconPayload[] = {
rgrover1 43:b5dc3241fc91 38 0x4C, 0x00,
rgrover1 43:b5dc3241fc91 39 0x02,
rgrover1 43:b5dc3241fc91 40 0x15,
rgrover1 44:71ff94cd9c1d 41 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
rgrover1 44:71ff94cd9c1d 42 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
rgrover1 43:b5dc3241fc91 43 0x00, 0x00,
rgrover1 43:b5dc3241fc91 44 0x00, 0x00,
rgrover1 48:2f0f293a4966 45 0xC8
Rohit Grover 10:391c1acf4b9d 46 };
Rohit Grover 10:391c1acf4b9d 47
ktownsend 0:7613d21e5974 48 int main(void)
ktownsend 0:7613d21e5974 49 {
Rohit Grover 11:6774f4827024 50 ble.init();
ktownsend 0:7613d21e5974 51
Rohit Grover 37:205deeded79d 52 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
Rohit Grover 27:8d4f5bda1191 53 ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload));
ktownsend 0:7613d21e5974 54
Rohit Grover 20:5e84b5b253a5 55 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
rgrover1 48:2f0f293a4966 56 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));
Rohit Grover 19:869d8c7306b4 57 ble.startAdvertising();
ktownsend 0:7613d21e5974 58
Rohit Grover 21:a61af863b273 59 for (;;) {
Rohit Grover 31:93e50a3c3dc6 60 ble.waitForEvent();
ktownsend 0:7613d21e5974 61 }
Rohit Grover 10:391c1acf4b9d 62 }