
iBeacon and Eddystone are Apple and Google services, respectively, using BLE (Bluetooth Low Energy) for local indoor positioning. The basic principle of both services is the same, only the format of the transmitted data is different. The lighthouse (transmitter) periodically, with an interval from fractions of a second to several seconds, transmits packets of the Bluetooth LE standard, which contain, in addition to the header, additional information. The technology is not designed to accurately determine the position in the room, but only to fix the moment of approaching for some close distance to the lighthouse.
A classic example of the use of lighthouses - museums. Coming to the museum, you install a special application on your smartphone and go to inspect the exhibition. Approaching the exhibit (lighthouse) at a distance, the smartphone captures this and displays the tour information.
A lot of ready-made lighthouses can be found on sale, but today we will assemble a prototype of our own lighthouse (both iBeacon and Eddystone) on the SAML21 microcontroller and BTLC1000 BLE module from Atmel.
Iron
Bluetooth will be implemented on the basis of the
ATBTLC1000-XPRO expansion
card with this module. As the host, we use the
ATSAML21J18B microcontroller installed on the
ATSAML21-XPRO-B debug board

Generating an example for iBeacon
To do this, go to the
Atmel | Start - Web code configurator for Atmel microcontrollers. In one of our past articles we already wrote about using this tool. On the main page, click the
Browse All Examples button and in the window that opens, select the
SAM L21 Xplained Pro debugging board, and in the search
box type ibeacon . Select the example of
BLE Simple-BTLC1000 and click the button
Open Selected Project :

')
The resulting default configuration corresponds to the hardware and nothing needs to be changed here. Just in case, you can compare the result with a screenshot and click the
EXPORT PROJECT button in the upper right corner of the screen:

Put a tick in front of the
Makefile (standalone) item, rename the project and press the
DOWNLOAD PACK button:

As a result, the file with the
* .atzip extension is
downloaded . In principle, this is a regular archive in which the project for Atmel Studio is stored. Open the file (it should be associated with the studio) and wait until the project starts. In the opened dialog, if you wish, change the project name and path to the project folder and click OK:

We are waiting until the project is formed.
Trial run
In principle, the out-of-the-box example already works like an iBeacon. We try to compile the project with the F7 button.
If the compilation was successful, you can upload the project to the microcontroller for the first tests. I recommend to pre-launch a terminal program for monitoring debazhny information. The built-in EDBG debugger is defined in the system, including as a virtual COM port to which one of the microcontroller
secoms is connected.
We launch our favorite terminalku, set the speed 115200 and tick DTR.
Click the F5 button to fill the firmware. If you fill in for the first time, a message will appear asking you to select the programmer to be used:

In the dialog box, specify our debugger:

Press F5 again and wait until the controller is programmed and the program starts to run. If everything is done correctly, you should see the following information in terminal:

Now we run on the phone any application that works with beacons (for example,
iBeacon & Eddystone Scanner for Android) and we should see our tag.

Let's a little understand the format of the transmitted data. And he, according to the old tradition of Apple, is very simple. The beacon from the payload transmits the following data:
UUID. 128-bit unique identifier of a group of beacons, determining their type or belonging to the same organization
Major. 16-bit unsigned value with which you can group beacons with the same UUID
Minor. 16-bit unsigned value with which you can group beacons with the same UUID and Major
Measured Power (signal level at 1 m from the transmitter). 8-bit signed integer - the value of the received signal level indication (RSSI), calibrated at a distance of 1 m from the receiver, which is used to determine the proximity to the receiver (mobile device). Measured in dBm.
In the main
simple_btlc1000.c file
, an array of
adv_data is defined , into which this data is placed. In addition, there is additional service information, the decoding of which can be found in the document
Proximity Beacon
Specification at
developer.apple.com/ibeacon .
static uint8_t adv_data[] = { 0x1a, 0xff, 0x4c, 0x00,
The main magic occurs in the function
beacon_init () , which is called immediately before the main loop in main. In it, using the
at_ble_adv_data_set API function
, we tell the module which data we want to transfer (the same array
adv_data ), and then use the at_ble_adv_start function to start the transfer process itself with the frequency of their transfer (BEACON_ADV_INTERVAL).
Function code beacon_init () static void beacon_init(void) { static at_ble_handle_t service; if (at_ble_primary_service_define(&service_uuid, &service, NULL, 0, chars, 2) != AT_BLE_SUCCESS) DBG_LOG("Failed to define the primary service"); if(at_ble_adv_data_set(adv_data, sizeof(adv_data), scan_rsp_data, sizeof(scan_rsp_data)) != AT_BLE_SUCCESS) DBG_LOG("BLE Beacon advertisement data set failed"); if(at_ble_adv_start(AT_BLE_ADV_TYPE_UNDIRECTED, AT_BLE_ADV_GEN_DISCOVERABLE, NULL, AT_BLE_ADV_FP_ANY, BEACON_ADV_INTERVAL, BEACON_ADV_TIMEOUT, BEACON_ABSOLUTE_INTERVAL_ADV) != AT_BLE_SUCCESS) { DBG_LOG("BLE Beacon advertisement failed"); ble_device_disconnected_ind(); } else { DBG_LOG("Advertisement started"); ble_device_connected_ind(); } }
Redesigning the project for Eddystone beacons from Google
To do this, you only need to do one thing - change the data array to be transferred to the
at_ble_adv_data_set function. Let's get a separate array and fill it. You can read about the package format
here . Unlike iBeacon, Eddystone can currently transfer 3 types of packets. The type identifier is transmitted in one of the sending bytes:

We will pass the link.
The format of the link itself can be found on
this page.
Link Transfer FormatURL Scheme Prefix
Eddystone-url http url encoding
Note: domain .ru in the list of supported no. I really wanted the link to be live, so I’ll write to geektimes.com, because it has a redirect to geektimes.ru, but habrahabr.com is not redirected to the domain .ru in the same way.As a result, we get the following package for Eddystone:
static uint8_t eddystone_data[] = { 0x03, 0x03, 0xaa, 0xfe, 0x10,
Do not forget to specify a new package in the API:
at_ble_adv_data_set(eddystone_data, sizeof(eddystone_data), scan_rsp_data, sizeof(scan_rsp_data)) != AT_BLE_SUCCESS)
Compile, fill, see the result.

That's all, to new meetings. Now in the vast Habr.