📜 ⬆️ ⬇️

Make iBeacon and Eddystone Beacon "on the knee"


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, // Company ID 0x02, 0x15, // Beacon Type // Proximity UUID 0x21, 0x8A, 0xF6, 0x52, 0x73, 0xE3, 0x40, 0xB3, 0xB4, 0x1C, 0x19, 0x53, 0x24, 0x2C, 0x72, 0xf4, 0x00, 0xbb, // Major 0x00, 0x45, // Minor 0xc5 // Measured Power }; 

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; /* establish peripheral database */ if (at_ble_primary_service_define(&service_uuid, &service, NULL, 0, chars, 2) != AT_BLE_SUCCESS) DBG_LOG("Failed to define the primary service"); /* set beacon advertisement data */ 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"); /* BLE start advertisement */ 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 Format
URL 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, //  0x16, 0xaa, 0xfe, // 16-bit Eddystone UUID 0x10, // Frame Type: 0x10  URL 0xf0, // TX Power 0x00, // URL Scheme: http://www. 'g', 'e', 'e', 'k', 't', 'i', 'm', 'e', 's', 0x00, // .com/ }; 

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.

Source: https://habr.com/ru/post/273865/


All Articles