Connection parameters are important for BLE (Bluetooth® low energy) applications, since they affect power consumption for both the central and peripheral devices, data transfer speed of the connection, and, in some cases, the stability of the connection.
The connection interval time has an inverse affect on data throughput of the BLE connection, as shown in the following equation.
In other words, in a typical BLE 4.x application, you have 20 bytes per packet, if the central device is an iPhone 7 running iOS10 or above; the maximum packets per interval is 6; and normally a connection interval of 30 ms is attainable.
So, in this case the data throughput is: 8 * 20 * 6 * 1000 / 30 = 32000 bits/sec, or roughly 4 kbytes per second.
Since we mentioned the parameter of “packets per interval”, here is a tip on this factor.
Packets per interval is usually not explicitly explained on a specific smartphone, but this parameter is closely related to the actual Bluetooth/BLE chip that is used in the smartphone and how it handles task scheduling during the test. As a result, when more BLE devices are connected to the same central device, you may very likely have a lower number of packets per interval on the connection with your own device.
Empty packets are sent between the central and peripheral devices when both sides agree on the connection interval. This is done not only when there are actual events and data to be handled over the BLE connection, but also when the connection is idle, just to keep the smartphone displaying a “connected” indicator.
To save power we need to change the connection interval to a much longer period when we know the connection is going to be in idle state for a period of time.
Furthermore, slave latency can be applied to help the peripheral (slave) device to further reduce power consumption. This parameter is helpful to avoid changing connection parameters frequently to achieve both high speed data transfer and low power consumption during idle.
For example, if there is a 30 ms connection interval with a slave latency of 4, the connection is able to handle data transfers with 30 ms connection intervals and when in idle, it sends empty packets to keep the connection only once every 150 ms (on the slave side).
However, on the smartphone (Central/Master) side, the connection events still happen once every 30 ms even when the connection is idle.
In many practical cases, it is both a longer connection interval and a selected slave latency which are applied when the device knows it will enter an idle mode.
The below screenshot shows how much energy is spent for an empty packet for the BLE sub-system of the Apollo2 Blue. Over a connection event active time period, which is approximately a 3 ms period, the device spends on average 1.15 mA current to keep the connection. (3V power supply, TX power = 0 dBm)
The sleep current of the device is ~1 uA.
The average current consumption between 2 actual connection events is:
If we compare 2 example cases:
Connection interval = 30 ms, Slave latency = 1: Average current ~ 57.2 uA
Connection interval = 200 ms, Slave latency = 4: Average current ~ 4.4 uA
Using a standard CR2032 battery with 80% effective coverage (~192 mAh), the difference in battery life is roughly 4.5 months compared to 5 years.
How and When Connection Parameters are Determined
There are a couple tricks used in the example above to show the huge difference in current draw and resulting battery life, but it is true that managing connection parameters are important for the application.
Connection parameters are initially determined when a connection is established between the central and peripheral devices. According to the BLE specification, upon connection establishment, the connection interval shall be set to TGAP (initial_conn_interval), and the recommended value is 30 to 50 ms, with 0 slave latency. And when no further action is pending and TGAP (conn_pause_central) time (1 second recommended) elapses, the central device (smartphone) checks the advertising/scan response data or the peripheral preferred connection parameters characteristic (PPCP) to determine the connection parameter to be used for this connection, which triggers a connection parameter update procedure. On the peripheral side, it can also trigger a connection parameter update procedure after the TGAP (conn_pause_peripheral) time (5 sec recommend) when no further action is pending.
Connection parameters can be changed from the peripheral side during the connection but the negotiation result with the central may not always be successful.
For reference, see below the iOS devices' acceptable connection parameter range in “Bluetooth Accessory Design Guidelines for Apple Products”.
Notice that you may not be able to get a very low connection interval with iOS devices, even though the guide says >= 20 ms, the lowest ever achieved in my experiments is 22.5 ms and in most cases, 30 ms. But for devices with HID services, there is a chance to get lower intervals, down to 11.25 ms. This gives some ideas for what to do to maximize the data throughput with iOS devices.
On the other hand, here is a note for getting such a low connection interval on our BLE devices.
The default minimum sleep time configuration of our BLE part is 15 ms, which means that if the part knows the next event is going to happen within 15 ms, it will not go to sleep so that it will avoid wake-up overhead. That is, if a connection interval is lower than 15 ms, the BLE part is going to stay awake and it will consume ~500 uA at 3V.
Therefore, in an application case, one could include a HID service and request a very short connection interval to maximize the data throughput. After the job is done, the connection interval can be set back to a longer value to put the BLE part back to sleep again.
Below is a snapshot from the BLE part's configuration editor tool.
How to Handle Connection Parameters in the Ambiqsuite Cordio BLE Stack
In the Cordio BLE stack, to trigger a connection update request, one can simply call the DM (GAP) API: DmConnUpdate();
The interface requests parameters are:
dmConnId_t connId: Connection ID of the current channel.
hciConnSpec_t *pConnSpec: connection parameter specification.
In this data structure:
uint16_t connIntervalMin; /*!< Minimum connection interval. In 1.25 ms unit*/
uint16_t connIntervalMax; /*!< Maximum connection interval. In 1.25 ms unit */
uint16_t connLatency; /*!< Slave latency. */
uint16_t supTimeout; /*!< Supervision timeout. In 10 ms unit */
uint16_t minCeLen; /*!< Minimum CE length. Set to 0 */
uint16_t maxCeLen; /*!< Maximum CE length. Set to 0 */
After the request is sent, a connection update response will be received. This event is going to be indicated by DM_CONN_UPDATE_IND. The application can monitor this event and check the status and message along with the event.
The message contains a pointer with a type of hciLeConnUpdateCmplEvt_t* to the responded connection parameter. The application can store these parameters to record the status of the current connection.
In this data structure:
wsfMsgHdr_t hdr; /*!< event handler message structure */
uint8_t status; /*!< response status, 0x00 == success */
uint16_t handle; /*!< event handle id*/
uint16_t connInterval; /*!< current connection interval*/
uint16_t connLatency; /*!< current slave latency*/
uint16_t supTimeout; /*!< current supervision timeout*/
If the status is not = success, the application can perform a retry operation with relaxed parameters until it gets a successful response.
Specification of the Bluetooth System:
Bluetooth Accessory Design Guidelines for Apple Products:
Google I/O 2013 Best Practices for Bluetooth Development
ARM Cordio BLE stack:
Maximizing BLE Throughput on iOS and Android: