Using Beacons
Go Up to Using Bluetooth
A beacon is a Bluetooth Low Energy device including some information in its advertising data, specifically in the Manufacturer Specific Data described in "Bluetooth Specification Version 4.1, page 2023" https://www.bluetooth.org/en-us. This information allows any Bluetooth Low Energy device in the surrounding area to identify the device and calculate the distance to it without being paired or establishing a connection.
Contents
Beacon Overview
Platform Support
Platform | Supported |
---|---|
Windows(*) |
10+ |
macOS |
10.7+ |
iOS |
5+ |
Android |
4.3+ |
Beacon Types
Three beacon formats are available: iBeacon, AltBeacon and Eddystone. The RTL API for beacons differentiates them by using the types TBeaconScanMode and TKindofBeacon.
You need to know the format that is using the beacon you want to monitor.
Beacon Format | Description | Mode |
---|---|---|
iBeacon |
Format defined by Apple. The full specifications are available here. |
Standard |
AltBeacon |
Open format. The full specifications are available here. |
Alternative |
Eddystone |
Open format defined by Google. The full specifications are available here. |
Eddystone |
Manufacturer Information
Bluetooth Low Energy devices in advertising mode send the Advertising Data repeatedly over radio in different AD type structures. One of the AD types in the Advertising Data is the Manufacturer Specific Data which is utilized for beacons. Depending on the beacon format, the data included in the Manufacturer Specific Data is different.
The following table shows the data fields that each beacon format can advertise:
Advertised Data | Description | iBeacon | AltBeacon | Eddystone |
---|---|---|---|---|
A unique identifier which identifies a group of beacons, for example, the beacons of a specific company. |
|
|
| |
The Major ID identifies a sub-region within a larger region defined by an UUID. |
|
|
||
The Minor ID specifies further subdivision within a Major ID. |
|
|
||
The TxPower is the measured power in dBm from 1 meter of distance to the beacon. With TxPower and the Received Signal Strength Indicator (RSSI), the approximate distance to a beacon can be calculated. |
|
|
| |
Eddystone frame
The Eddystone frame contains a Service UUID that is known as ServiceData, with ID 0xFEAA
.
The frame accepts three subformats:
- EddystoneUID: The beacon broadcasts an identifier that consists of a Namespace and an Instance.
- EddystoneURL: The beacon broadcasts a URL in a compressed format.
- EddystoneTLM: The beacon broadcasts telemetry information in relation to the beacon status.
For further information, see Eddystone specifications.
How to Use Beacons
The RTL API for beacons allows you to obtain the Distance between the device that is running your application and the surrounding beacons. The RTL API for beacons provides information only for the beacons within a defined region. Region is a group of beacons. You can specify a Region with their UUID, MajorID, MinorID (for iBeacons and AltBeacons) or with their Namespace and Instance (for Eddystone).
Obtaining an instance of TBeaconManager
To use the RTL API for beacons, you must include the System.Beacon unit in your application, and call TBeaconManager.GetBeaconManager for the TBeaconScanMode you want to use to get an instance of TBeaconManager.
For iBeacons:
BeaconManager := TBeaconManager.GetBeaconManager(TBeaconScanMode.Standard);
For AltBeacons:
BeaconManager := TBeaconManager.GetBeaconManager(TBeaconScanMode.Alternative);
For Eddystone:
BeaconManager := TBeaconManager.GetBeaconManager(TBeaconScanMode.Eddystone);
For Extended:
BeaconManager := TBeaconManager.GetBeaconManager(TBeaconScanMode.Extended);
The ScanMode identifies the type of beacon the system should look for: Standard Mode, Alternative Mode, Eddystone Mode or Extended mode. The Extended mode allows you to scan for several kinds of beacons at the same time. TBeaconManager is the main class of the beacon implementation of the RTL API for beacons. TBeaconManager is in charge of registering regions, and manages the events to get the information from beacons. The TBeaconManager instance must be created either for Standard Mode, Alternative Mode or Eddystone Mode.
Registering Regions to be Monitored
Use the TBeaconManager.RegisterBeacons method to register the regions of the beacons you want to monitor. You need to pass a parameter with TBeaconsRegion type in order to specify the information about the beacon and the region.
BeaconManager.RegisterBeacons(ABeaconRegion);
For iBeacons and AltBeacons:
- The TBeaconsRegion type parameter is set as TiBAltBeaconRegion.
- Regions are specified with the parameters UUID, MajorID and MinorID. For registering a region, only the parameter UUID is required. In case you want to be more specific about the region you want to register, you can also use MajorID, MinorID or both.
For Eddystone:
- The TBeaconsRegion type parameter is set as TEddysUIDRegion.
- Regions are specified for the EddystoneUID format, with a Namespace and an Instance. For registering a region, only the parameter Namespace is required. In case you want to be more specific about the region you want to register, you can use both a Namespace and an Instance.
Scanning for Beacons
For registered beacons: The former framework needs that you:
- Register the beacons you want to monitor.
- Start monitoring the registered beacons.
- Stop monitoring the registered beacons.
For non-registered beacons: The new improvement on the scanning performance allows you to scan simultaneously for several kind of beacons that are not registered:
- Set the Extended mode.
- Select the formats you want to monitor with type TKindofBeacon.
- Set the selected beacons to monitor to the ModeExtended property.
- Start monitoring non-registered beacons.
- Stop monitoring non-registered beacons.
Getting information from incoming beacons
To get information about a beacon, ask the main beacon interface (IBeacon) about the kind of beacon that is being monitored. Then, you can use the specific beacon interface: IiBeacon for iBeacon, IAltBeacon for AltBeacon or IEddystoneBeacon for Eddystone.
The way of getting the information about the monitored beacons is through the events associated to the TBeaconManager. Each beacon format provides a specific set of events:
- For iBeacons and AltBeacons:
- OnCalcDistance: Fired immediately before the Distance is calculated.
- OnEnterRegion: Fired the first time a beacon is reachable from a registered region.
- OnExitRegion: Fired when all registered beacons on a region are unreachable.
- Once the event is fired, you can use the information provided by the event.
- Register a region with its specific UUID, MajorID = -1 and MinorID = -1 in order to receive events associated to all the beacons with the same UUID.
- Register a region with its specific UUID and design your app to filter MajorID and MinorID according to your custom values and app requirements.
- For Eddystone:
- OnNewEddystoneURL: Fired every time a new EddystoneURL beacon is found.
- OnNewEddystoneTLM: Fired every time a new EddystoneTLM beacon is found.
- For any beacon format:
- OnCalculateDistances: Fired immediately before the distance to a beacon is calculated.
- OnBeaconEnter: Fired every time a new beacon is reachable.
- OnBeaconsEnterRegion: Fired every time a new beacon is detected within a region. Both, beacon and region information are specified with the TBeaconsRegion type.
- OnBeaconExit: Fired every time a beacon becomes unreachable.
- OnBeaconsExitRegion: Fired every time a beacon registered within a region is lost. Both, beacon and region information are specified with the TBeaconsRegion type.
- OnBeaconProximity: Fired every time the Proximity value changes.
Example
The following code snippet demonstrates how to use an OnBeaconEnter event. To get the required beacon information from this event, take the following steps:
- Ask the main Beacon Interface about the kind of the monitored beacon. To this end use the KindofBeacon property.
- Ask for the specific interface:
- IiBeacon for iBeacon.
- IAltBeacon for AltBeacon.
- IEddystoneBeacon for Eddystone.
- Code for this event.
procedure TForm1.Beacon1BeaconEnter(const Sender: TObject;
const ABeacon: IBeacon; const CurrentBeaconList: TBeaconList);
var
LEddyHandler: IEddystoneBeacon;
LiBeacon: IiBeacon;
LAltBeacon: IAltBeacon;
ST: string;
begin
case ABeacon.KindofBeacon of
TKindofBeacon.iBeacons:
if (Supports(ABeacon, IiBeacon, LiBeacon)) then
ST := ' GUID: ' + LiBeacon.GUID.ToString;
// code
TKindofBeacon.AltBeacons:
if (Supports(ABeacon, IAltBeacon, LAltBeacon)) then
ST := ' GUID: ' + LAltBeacon.GUID.ToString;
// code
TKindofBeacon.Eddystones:
if (Supports(ABeacon, IEddystoneBeacon, LEddyHandler)) then
ST := LEddyHandler.EddystoneUID.NamespaceToString;
// code
end;
Adding Location Services
Location services allow location-based apps to use information from cellular, Wi-Fi, GPS, and beacons to determine your approximate location. For detecting beacons, you must enable the location services.
Android
For Android, you must enable the bluetooth options in Project > Options > Uses Permissions. Users might need some permissions for enabling the application to use location services for beacon detection. To manually request this permission, use the following sample:
// add System.Permissions, FMX.DialogService to uses
{$IFDEF ANDROID}
PermissionsService.RequestPermissions( ['android.permission.ACCESS_FINE_LOCATION'],
procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
begin
if (Length(AGrantResults) <> 1) or (AGrantResults[0] <> TPermissionStatus.Granted) then
TDialogService.ShowMessage('Approval required to use location features')
end
);
{$ENDIF}
iOS
For the iOS platform on Alternative Mode, you do not need to activate Location services. In Standard Mode (iBeacons), the location activation request must be accepted first time the App is launched.
From iOS 8.0, if you use the Standard Mode, some keys for enabling the application to use the location services are needed for beacon detection. The IDE already includes NSLocationAlwaysUsageDescription
and NSLocationWhenInUseUsageDescription
.
The key we need to add manually is:
NSLocationUsageDescription
For the values, we need a text message such as "This app needs access to Location services to monitor beacons." The system shows the text message when it accesses the app configuration.
The key can be added in the IDE, Project > Options > Version Info and then right-click on the grid and Add Key.
Indoor Limitations
The radio signal that beacons broadcast is highly sensitive to noise effects such as diffraction, absorption, multipath reflections, or interferences that come from other devices that emit in the same radio frequency band. In particular, these harmful effects critically affect the signal of the beacon in indoor environments. As a result, the estimates extracted from power measurements, such as Rssi, Distance or Proximity, become considerably unstable and tend to fluctuate. Thus the accuracy of these estimations diminishes.
Signal processing
The RTL provides two different algorithms to make the signal of a beacon and the estimates extracted from that signal more stable:
- RssiToDistance introduces a model to get the distance estimate derived from Rssi measurements. Note that a calibrated power parameter,
ATxPower
, enhances the robustness of the algorithm. - TBeaconManager implements an optional differential filter algorithm. This algorithm stabilizes the Rssi and distance measurements. To enable this algorithm, select the Stabilized calculation mode on the CalcMode property. This mode is especially useful for proximity estimation and movement detection.
Embedding algorithms
You can also embed further signal-processing algorithms, which may be either general-purpose algorithms or algorithms designed by yourself. The following list contains some example filters that you can implement to mitigate noise effects:
- Moving average filter
- Weighted average filer
- Curve fitting filter