How to reduce the time interval for didRangeBeacons method - ios

I am working on a project involving iBeacons. I am observing that the didRangeBeacons method is called in 1 second interval. Is there any way to reduce this time interval? My project requires low latency proximity detection and I was wondering how this could be achieved.

No, you cannot reduce this interval on iOS because it is baked in to the CoreLocation APIs. You can do so on Android, or you could do something similar with lower-level CoreBluetooth APIs on iOS, but using CoreBluetooth is a bigger roll-your-own project than can be answered here.
While I am unsure of your use case, you should consider that reducing the interval might not help. Beacons only send out advertisements at a certain frequency (typically 1-10Hz). If you are using a beacon transmitting at 10Hz, you could potentially get a detection in 1/10 of a second. But if you need a distance estimate, this fluctuates greatly with each packet, so you really need to average the measurements over many samples anyway.
Also, consider that a CoreBluetooth-based solution would only be able to do faster ranging when the app is in the foreground. Background processes on iOS have a whole different set of delay challenges.
Finally, any CoreBluetooth solution could not work with standard iBeacons because iOS sandboxes the ability to read iBeacon identifiers with anything other than CoreLocation. So you would need to build a custom beacon.

Related

Minimise battery consumption on Beacon Ranging in iOS while using iBeacon

I'm working on a use case that needs continuous callbacks while scanning the beacons.
I've thought of 2 approaches but they both have issues.
Monitoring: Monitoring only gives entry and exit callbacks. There's a limitation of listening to only 20 beacons. Also is there a range that i can define to get entry and exit callbacks? Like say if a an advertising beacon comes in range of 2 meters i get an entry callback and if the device moves out of that range i get an exit callback.
Ranging: Ranging gives continuous callbacks along with a set of other parameters like rssi to calculate distance. The big issue when it comes to ranging though is that it consumes insane amount of battery compared to monitoring. What should be an approach for getting continuous callbacks while optimising battery consumption?
I've tried both the approaches and reached to a dead-end. Hence it may seem like a theoretical question yet any insights to solve the use-case in some manner.
It is not possible to set any kind of rssi or distance filter when using iOS CoreLocation beacon monitoring APIs. Ranging is the only alternative when working with iBeacon.
While battery drain of constant BLE scanning is an issue, you an mitigate this by scanning on a lower duty cycle as needed to meet your requirements. For example, you can scan on a 20% duty cycle (and use 20% as much battery as constant ranging) by ranging for 12 seconds every minute. You can adjust this duty cycle as needed to balance your goals between battery savings and responsiveness. I have worked on projects where I change this duty cycle depending on app state, so the app can be more responsive to beacons when it is important and save battery when responsiveness is less important.
In order to be able to do this at all, you must unlock the ability to have iOS let your app run in the background for an unlimited time period as described in my blog post here:
Add the location background mode to Info.plist
Obtain "always" location permission from the user. It is not sufficient to get "when in use" permission.
Start a background task as described here: http://www.davidgyoungtech.com/2014/11/13/extending-background-ranging-on-ios
Request 3km location updates from CoreLocation. This will keep the app running in the background without extra battery drain from GPS, as 3km accuracy only uses the cell radio You don't need to do anything with these results. You just need to request them to keep the app alive.
Once you do the above, you can call locationManager.startRangingBeacons(...) and locationManager.stopRangingBeacons(...) on a timer to implement whatever duty cycle you want.

Beacons, CoreLocation, BLE, and "Geo-Fencing" - definition of terms?

I was hoping someone could spell out the relationship between iBeacon recognition, CoreLocation and CoreBluetooth, specifically in the context of what iOS considers "geo-fencing".
First off, I understand Apple's documentation on Using Regions to Monitor Boundary Crossings and have seen other discussions around the topic, like iOS - CoreLocation and geofencing while app is closed (especially pertinent to our app since this is a background operation). However, I'm having a hard time finding Apple's explicit definition of geofencing and exactly which frameworks get categorized as such.
Consider:
Beacons are based on BLE and yet they use the CoreLocation framework and not the CoreBluetooth framework. In fact, you do not need to add Bluetooth capabilities to the project settings in order to get them to work.
Detecting beacon regions uses the same object and method calls: to register a region, you call the ‘startMonitoringForRegion’ method of ‘CLLocationManager’ object.
It appears that once we added beacon recognition to our app, users have begun seeing "geo-fencing enabled" messages in their settings.
I thought geo-fencing was purely used in GPS- and Wifi-based location services? Not BLE services? The whole point of BLE beacons is to reduce the drain on the battery that geo-fencing produces.
On a higher level, is there any way to prove demonstrably that using beacon technology produces a much lower battery drain than other location-based geo-fencing? Using "geo-fencing" as an umbrella term for both (if that is indeed what is happening), muddies the waters significantly when making a business case for beacons.

IOS: iBeacon scanning frequency when phone is locked?

If an iBeacon starts emitting (100ms), how long should it takes before a locked iPhone detects it? Let's say the iPhone is very close to the emitting iBeacon but my app is not even running in the background.
In other words, what is the LBE scanning frequency when an iPhone is locked?
We have done a lot of research on this subject at Radius Networks. The answers are complicated, but the executive summary is that their are two tiers of detection:
Hardware Accelerated: The first beacon apps to register the first 30 beacon regions on the phone get hardware accelerated detection. Thisey get background detection within 5 seconds about 90% of the time.
Software Scanned: Subsequently registered beacon regions get detections as software allows. If no other apps are ranging, this is on a fixed 15 minute interval. Statistics say that the average detection time would be 7.5 minutes for these regions. The maximum time is 15 minutes.
Unfortunately, there is no known way to tell which tier your app will get. Plan accordingly.
Read more here:
http://developer.radiusnetworks.com/2015/04/21/max-beacon-regions-ios.html
http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html
The documentation doesn't seem to be really specific about the scanning times, and I feel like most of the information one can find is going to be anecdotal.
From my personal research and experience, beacon scanning when the app is backgrounded or inactive is variable on the iPhone's battery level and various other factors. For the most part, in most cases, I've determined that region detection should occur within a few seconds.
With that said, I've noticed that it happens a little faster when the phone is in use, taken out of the pocket, etc. This could be due to the fact that as the phone is moving, scanning is increased to bring the user up to speed and prepare apps for use.

Use Core Bluetooth instead of iBeacon - Any Downsides?

I am working on a project where I first wanted to advertise a device as an iBeacon and make it possible to connect to that device via Core Bluetooth at the same time. Besides the fact that this is not easily doable (a device cannot advertise as an iBeacon and CB device at the same time), I noticed that the iBeacon part seems unnecessary - discovering peripherals with Core Bluetooth seems to be basically the same as discovering iBeacons.
My first Question: Am I right in assuming this? Or does iBeacon provide anything that central/peripherals in CB do not? Especially in regard to background advertisement/searching?
The only issue I can see right now is that the CLBeacon gives me both an rssi and an accuracy (and from this, the approximated proximity is calculated). With Core Bluetooth, centralManager:didDiscoverPeripheral:advertisementData:RSSI: gives me only an RSSI. Is there any way to retrieve the accuracy here so I can calculate a proximity? This is important for me and I guess relying on RSSI only for the proximity will give me less accurate results?
My second Question: Can I get the accuracy that I get with iBeacon in Core Bluetooth or a similar measure to calculate the proximity?
You can calculate your own distance estimate with RSSI using an algorithm like the one I posted here:
https://stackoverflow.com/a/20434019/1461050
The trick is that you will need as many RSSI measurements as possible averaged over a time window of 20 seconds or so to reduce the noise on the estimate.
The main advantages of using CoreLocation APIs to detect standard iBeacons vs. using CoreBluetooth to detect custom beacons are:
A variety of cheap off-the shelf hardware is available for the iBeacon standard.
CoreLocation can scan for iBeacons in the background (likely using hardware assist on iPhone 5+) in a way that can automatically launch your app relatively quickly, even if the user did not manually launch it since boot. As of iOS 7.1, even if the user kills the app from the task switcher, CoreLocation can re-launch it into the background if an iBeacon is detected. I do not believe all this is possible with CoreBluetooth.
The iBeacon transmission allows you to easily read the UUID/major/minor identifier combination in iOS without pairing. This 20 bytes of data (with the major and minor fields able to be set to arbitrary values) is more than you can get from a 16 byte Bluetooth Service UUID.
You don't have to roll your own software for distance estimation.

How to limit the advertising range of a beacon?

Is it possible to limit the ranging of the beacon, so that only devices within a certain close range(or proximity) can identify and connect to the beacon? Lets say for example the devices outside 0.5 meter zone shouldn't be able to see or connect to the beacon. I am using a iOS device as a beacon. In the Apple's CoreLocation API, there is a method called peripheralDataWithMeasuredPower in the CLBeaconRegion class which says:
peripheralDataWithMeasuredPower:
Retrieves data that can be used to advertise the current device as a beacon.
(NSMutableDictionary *)peripheralDataWithMeasuredPower:(NSNumber *)measuredPower
Parameters:
measuredPower:
The received signal strength indicator (RSSI) value (measured in decibels) for the device. This value represents the measured strength of the beacon from one meter away and is used during ranging. Specify nil to use the default value for the device.
Can this be used to limit the range of beacon? If yes, I am unable to understand how to decide the value to set for measurePower parameter? What are they trying to say by ...value represents the measured strength of the beacon from one meter away..?
Please forgive if this is a very basic question. I've recently started iOS development and will appreciate your help. Thanks.
Unfortunately, there is no easy way to adjust the range of an iBeacon without special hardware.
The power field that you mention is simply a calibration value transmitted by an iBeacon. It doesn't affect the actual physical radio range of the iBeacon. If the transmitter can be seen by an iPhone 50 meters away, altering the power field value will not change this at all. The only thing it does is change is the calibration constant which is an input to the distance estimation algorithm (used for the accuracy and proximity fields) inside the iOS software. Altering the power field will affect the estimated distance returned by the API, but it won't change the actual distance at which the iBeacon is first detected.
Altering the transmit power of a standard bluetooth iBeacon is practically impossible. In theory you can use metal shielding to construct a "faraday cage" around the transmitter to mute its power, but my experience is that it isn't very effective and it is highly susceptible to tiny imperfections in the shielding. If you want to change the transmit power you have to have somebody build you custom hardware.
The software alternative is to use the ranging API to track an iBeacon while it is visible, and only perform an action when the estimated distance is close enough, say 0.5 meters as you suggest. This works great -- only in the foreground.
If you require actually waking up your app in the background at a close range, this won't work. The best you can do is have the monitoring API wake up your app when the iBeacon is first detected, and then send a notification to the user and start ranging. If the user elects to bring the app to the foreground (at 50 meters) you can keep monitoring and then perform your desired action at 0.5 meters. If the user does not elect to bring the app to the foreground, iOS will only give you about 5 seconds of time to continue ranging before it suspends your app. It is very unlikely that the distance will change from 50 meters to 0.5 meters in this time.
With most BLE chips I've investigated, there are usually at least four settings for transmission power level that can be used to limit the advertising range.
The Texas Instruments CC2541 (as used in their SensorTag development device) and CC2540 have +4, 0, -6, and -23 as their power level options. However, changing that in the SensorTag does require a recompile of the firmware. As-is, the provided firmware mentions the power level in only one place, but that is just a value that is broadcasted to inform any central listener how loud the beacon is—so that the central device can better calculate an estimated range based on received signal strength (RSSI). An additional line must be added to the firmware to actually change the transmission power. For example:
HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_0_DBM );
Based on this, there should be two places on an iOS device where you can set the power level: one that just informs the listeners what the level is, and one where the BLE chip's true transmission power is actually changed. However, expect these values to be restricted to only a few enumerated choices which may or may not meet your real-world range needs.
(The SensorTag's -23 setting would probably do well for a 0.5 meter detection range. But if you want the SensorTag to always be advertising, it will require an additional firmware change.)
Have you looked to see if the proximity property was helpful? From the apple docs:
CLProximity
Constants that reflect the relative distance to a beacon.
typedef {
CLProximityUnknown,
CLProximityImmediate,
CLProximityNear,
CLProximityFar
} CLProximity;
I would also experiment trying to combine the the proximity with accuracy and rssi.
It's gonna vary from beacon to beacon. If you use beacons from Radius Networks, they have a transmit power setting that lets you essentially limit the ability of the beacon radio to broadcast to long ranges. I don't know if other brands have it, but most do not from what I've seen.

Resources