Welcome to the next installment of our big blog series on building real-time iBeacon and beacon technology! In other words, we're building smarter beacons, enhancing the capabilities of beacon technology with bidirectional, two-way communication. Check out the beacon series overview here.
Tessel Beacon Tutorial Overview
In this installment, we're going to build beacon technology using the Tessel board platform. Specifically, we'll be using the Tessel board as both an detector beacon (part two), and a emitter beacon (part three). Throughout the series, we'll be using the Tessel BLE Module, in addition to our standard Tessel board.
This will be an overview of techniques to use, we will also provide you with two example apps that aim at enhancing the capabilities of beacons.
In this article, we will mostly focus on the structure of a beacon advertisement, how to advertise it and how to detect a beacon. In Part Two, we'll build the detector (listener), and in Part Three, we'll build the Tessel ibeacon emitter (publisher).
What is Tessel?
Tessel is a small, powerful microcontroller that runs JavaScript. Since each Tessel contains a built-in wifi chip, internet-enabled JavaScript programs can be run directly from the device, even if it is not connected to a computer. This combination of WiFi and JavaScript means that Tessel works great with PubNub!
What a Beacon Advertisement Looks Like
According to the Bluetooth v4 specification, a beacon advertises a data package called the Scan Response Data. This Data can be up to 31 bytes. If we create a smaller scan response, the remaining bytes will be filled with as many 0s.
The scan response is divided into what are called AD structures. They are sequences of bytes of various size, with a predefined structure that goes as follows:
- The first byte represents the number of bytes left to the end of the AD structure. This allows a receiver of this structure to know when it ends and when a new AD structure starts.
- The second byte is the ID of an AD structure type.
- The rest of the bytes are data that is structured in a predefined way depending on what AD type was defined by the previous byte.
That’s all there is to it. It's just a succession of AD structures. Most beacon protocols, if not all, have only 2 AD structures which are as follows.
The first one has 3 bytes:
- The first byte will be:
0x02
because we only count the following bytes. - The second byte is:
0x01
which indicates we have a “Flag” AD type. - The last byte represents theses flags. These flags express whether the emitting device is, in “Limited Discoverable Mode”, “General Discoverable Mode”, etc… The byte is computed the following way:
The 5 flags are represented by the first 5 bits of a byte. The value of these bits defines whether the flag is ON or OFF. The binary number is then written as a hexadecimal value which will be advertised. An example may clear things up:
The resulting binary value hence becomes: b00011010
Converted into a hex, we get: 0x1A
That’s all there is to the first AD structure! Let’s look into the second one, which contains most of the information we need!
The second structure can be a different size according to the protocol. We will take the example of AltBeacon, which really is nearly identical to others.
- First byte is
0x1B
(27 in hexadecimal) which means we are taking all of the last available byte of our 31 byte scan response. - The next byte is always
0xFF
which means we have a “Manufacturer Specific” type of AD structure. - As a result, the 2 following bytes represent the company identifier as defined on bluetooth.org. For our tessel’s BLE module, the manufacturer is “bluegiga” whose company ID is 71. In hexadecimal value, this is equal 0x0047. The ID, written as little endian takes up the 2 bytes. Here it will be
0x047 0x00
in this order. - The rest is Manufacturer specific data! This is what changes the most between protocols.
For the AltBeacon protocol, the 2 first bytes of the manufacturer specific data are 0xBE 0xAC
and are used to recognize that we have a beacon. I personally really like that they decided to use the first 4 letters of beacon! Easy to remember. The next 16 bytes are a UUID representing the advertiser’s organizational unit, the 4 next bytes can be subdivided anyway you want. We are going to divide in 2.
We’ll have 2 bytes long number, similar to the major and minor in iBeacon. The following byte must be set according to your hardware, and the last byte can be left to 0, or you can decide to give it any meaning you want.
The byte which depends on the hardware represents the intensity of the signal at a meter away from your device. It is the two’s complement of the value in dB. The value of the intensity depends on a lot of factors, it often isn’t very precise. For my tessel board, -70dB seems like a correct estimation. This means the two’s complement will be -70 + 256 = 186
, so in hexadecimal value our byte becomes 0xBA
.
Computing the distance to a Beacon
One of the great strengths of beacon protocols is that they give you an approximate value of the distance that separates you to the emitting device.
This is always achieved by comparing the reference RSSI which is transmitted with the beacon scan response to the RSSI your phone detects. The algorithm to compute this value is often property of the beacon protocol owners (Estimote or iBeacon). However, AltBeacon being an open project, we will be using their algorithm, available here and here.
We are going to use this algorithm in our example code to compute the distance. Note that regardless of the protocol, the computed value on the distance is not reliable and can’t be used to detect the exact location of the user. More info on that in Apple’s docs.
Implement the code in JavaScript for Tessel
We will break down the tricky parts for you. If you need a guide to get started with Tessel BLE click here.
You will also have to set up the wifi on the Tessel with tessel wifi -n {wifi_name} -p {password}
.
Emitting
To advertise data on the Tessel is very easy: import the ble module, build the callback for when your module is ready and use the start advertising method with your data. The tricky part is just to build the data. If you understood the first part of this article you are ready to go.
Quick example:
Where you replace “UUID bytes”, “major”, and “minor” with the hexadecimals you want to emit. It’s as easy as that!
If you want a fully functional example, check out our full tutorial on building a Tessel emitter and Tessel detector, which will be published over the next two days.
Detecting
Just as easy. Make sure you select only beacons! Note that the scan record detected by the tessel only returns the data from the second AD structure, without the bytes for the length and the type of add!
What do you think? No need for any complicated SDKs! There is more to it, like obtaining the UUID, major, minor, and computing the distance.
Time for Part Two: Building the Tessel iBeacon Detector (Listener), the app that receives data from the beacon emitter and triggers an action.