I am looking at speeding up the connection time between my iOS application and the peripheral.
I have looked up Apples Documentation on the subject: https://developer.apple.com/library/content/qa/qa1931/_index.html
Originally (prior to reading the doc above) I had the advertising interval set to 2 seconds to, what I had thought would be, a good compromise between power consumption and connection time. Having read the documentation further I have changed the interval to 1285 ms.
#define ADVERTISING_INTERVAL 2056 ble_obj.setAdvertisingInterval(ADVERTISING_INTERVAL);
The device is always discovered quickly by the app but the problem comes when trying to connect.
However, I have seen no increase in speed in connection time between my application and the peripheral device. Connections between the devices can take anything from 3-4 seconds up to 30+ seconds.
Is there something I am missing? Either on the peripheral or the central side?
Peripheral BT chip is the Nordic Semiconductor NRF51822.
On examining the devices advertisement packet on the Nordic Semiconductor app I can see that the advertisement interval normally varies from 1275 ms to about 1295 ms (as expected? due to the random time added to the advertisement packet)
NOTE
Have also tried with an advertising interval of 152.5 ms and am still not seeing any major improvement in connection speed. I am , obviously, seeing a marked improvement in speed of discovery
What you observe is normal. Don't expect fast connection setup with an advertising interval of more than a second.
Core Bluetooth uses a high duty scan window/interval for the initiation the first seconds. If it doesn't connect then it continues to scan with much more power restrictive parameters.
Related
I use an iPhone as a peripheral to communicate with a micro controller (BLE chip in question is the BGM113). After connecting from the MCU, the MCU sends a couple of read and write requests for characteristics serially. Each request takes only a few ms in the MCU. On the iPhone side, responding to each request also only takes a few ms in the relevant methods (peripheralManager:didReceiveWriteRequests: and peripheralManager:didReceiveReadRequest:).
Still, I have roughly 500ms delay between each request. I have a support request running with the bluetooth chip manufacturer to clarify, but my gut feeling tells me that the fruity company is to blame...
Can anyone confirm such delays when reading or writing characteristics?
(more details: all characteristics are in the same service, read and write may happen on the same characteristic serially, there are several characteristics that I operate on.)
Your delay will be between 1 and 2 times the connection interval, so you set the connection interval to match your maximum delay requirement. Note that the energy consumption for the radio is linear to the inverse of the connection interval though.
since Android 5.0 start to support the peripheral device which allow apps to broadcast advertisements. In my app case, I need broadcast every 20ms to 30ms,but I can't find anyway to change the advertising interval. And the default advertising interval is between 20ms to 600ms, which totally can't accept in my case.
You can't have control over the exact millisecond frequency, but you can experiment with using different settings from https://developer.android.com/reference/android/bluetooth/le/AdvertiseSettings.html such as https://developer.android.com/reference/android/bluetooth/le/AdvertiseSettings.html#ADVERTISE_MODE_LOW_LATENCY.
LOW_LATENCY is the best available that sends a packet about 100mS interval.
If you need a "fast" packet transfer, the workaround option is to create multiple advertisers. And if you create 5 such parallel advertisers, eventually it will reach at around 20-30 mS. Yes, it is possible, but remember, you are flooding the environment with a huge data with 5X times.
After spending hours around the web, I cannot find any documentation about the background BLE scanning rules used by IOS.
As it is not possible to set the scan window on IOS, I am looking for the rules defined by Apple when IOS is scanning in background.
Context
I am working on a wearable peripheral which can be disconnected sometimes when it is out of reach with the phone. The goal is to reconnect quickly (less than 5s) when the peripheral is close enough to the phone. The peripheral has battery constraints so I cannot advertise every 20ms forever, so I am looking for a clever way to reconnect my peripheral to the phone.
If I know how the background scanning mode is working, I would be able to define a smart advertising interval in order to save battery.
Use case
If my peripheral advertises every 1285ms, how long does it will take to be discovered by my IOS application in background mode for 10 minutes?
Not sure exactly what your question is.
I suppose you have read Apple's "Bluetooth Accessory Design Guidelines for Apple Products"?
https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf
In it, they state:
3.5 Advertising Interval
The advertising interval of the accessory should be carefully
considered, because it affects the time to discovery and connect
performance. For a battery-powered accessory, its battery resources
should also be considered.
To be discovered by the Apple product, the accessory should first use
the recommended advertising interval of 20 ms for at least 30 seconds.
If it is not discovered within the initial 30 seconds, Apple
recommends using one of the following longer intervals to increase
chances of discovery by the Apple product:
152.5 ms
211.25 ms
318.75 ms
417.5 ms
546.25 ms
760 ms
852.5 ms
1022.5 ms
1285 ms
Note: Longer advertising intervals usually result in longer discovery and connect times.
Upon discovering the BLE device, iOS will notify apps that are looking for it (based on the advertised service UUID), which will then be able to connect to it.
Apple recommend a 100 ms interval for iBeacons.
This (pretty old, from 2012) discussion states that:
the median discovery time when the phone is in standby is about 60
times the advertising interval. The 95-percentile discovery time when
the phone is in standby mode is about 300 times the advertising
interval
This (slightly more recent, but from Dec 2013) answer states that:
While scanning in the foreground will likely immediately discover a
device advertising next to it, discovery in the background can take up
to ~60 times longer.
There's a problem when (average) advertising interval is near to an integer multiple of the scan interval, then chances are that discovery-time can rise infinitely (, i.e. scanner will never see the advertising, as ADV always occurs outside the scan window).
Probably the ADV-interval list from Apple's design guideline shows optimum values, but it does not tell how to determine discovery-times. That's a mess!
I'd even go further and say: If the Smartphone (Apple or any other) manufacturer does not exactly specify the scan parameters (interval, window, and eventually filter settings) for each power mode, then you're lost and cannot correctly estimate discovery performance.
I'm developing an iOS app that connects to a certain type of BLE device, but I'm writing the code in a room that has 20+ such devices sitting around, powered up. I consistently find that in the morning, I can connect to my personal device just fine, but as the day wears on, it becomes impossible to connect to my device, as if the 20+ other devices have woken up somehow and are blocking my signal. No one is using most of these devices; they're just sitting on tables. Is this a known bug? Is Apple working on it?
Are all the devices Advertising?
If they are advertising with say 20ms then it could be difficult to hear all. There are "only" 3 advertising channels to share between all devices. The connection happens on the same channels (the peripheral listens after it's own advertising to hear if someone want to connect).
It has nothing to do with Apple CoreBluetooth. In my experience CoreBluetooth can handle around 20 devices after connection has succeeded and the activity has moved to the traffic channels.
1) Try using a slower advertising interval. This should work okay if your app is in the foreground.
2) Use a BLE sniffer (TI USB dongle is fine) and see if connections fail on protocol level, then it is not CoreBluetooth's fault.
3) Only advertise with fast interval when needed or you really really need a fast discovery.
As a rule of thumb apple needs up to 55 advertisements in background mode to see a device when it's the only one visible. So if you really need around 1.1second discovery then you might need 20ms advertisement interval, else use 100ms or even more (see Apple advertising interval guidelines for the exact number that will optimise discovery)
100ms gives so much more capacity and not too bad discovery.
1-2s gives a much longer battery lifetime and will be found in 1-2 minutes if your app is in the background. This would be quite fine for eyeBeacons in malls or the like while you might want 100-200ms in smaller areas.
I want to know in regards to iOS what is the typical advertising rate for peripherals running in the background. I know that it will vary depending on what you are doing in the foreground , but I do not know to what degree. I have read it changes only by 10's of ms but then i have also read it can change by up to 4 seconds between advertisement packets. I can fit all of my data needed into 1 packet. I would like to know between advertising this one packet in the background and nominal iphone usage how likely is it that my advertising rate will still be in the ms range?
Also i have read that i can change this interval programatically, but the examples are only for 30 seconds. (im guessing due to limited discoverability mode?) Is there a way I could keep recalling this advertising boost? OR Maybe I could start as a central scanning in the background instead and when i scan a certain packet i could switch to peripheral mode (since you can only do one or the other in the background) and my advertising boost could happen then. Then when that thirty second boost is over i could switch back to central mode until i scan that certain packet again right? This way i would only have a small window of poor advertising rate every 30 seconds. Is that probable?