Optimizing Current Consumption in Bluetooth Low Energy Devices#
Introduction#
Current consumption or, more generally, energy usage is a major concern in battery-powered products. Optimizing current consumption extends battery life and, as a result, makes better products. This document discusses how to optimize the current consumption.
Description#
The two main factors affecting current consumption in a Bluetooth Low Energy (BLE) device are the amount of power transmitted and the total amount of time that the radio is active (TX and RX).
The amount of transmit power required depends on the range required between master and slave. Range is greatly affected by the environment such as obstacles and the amount of 2.4 GHz traffic present. The first tip is not to transmit more power than required.
The amount of time that a radio is active is determined by how often the radio must transmit or receive and the length of time required to transmit or receive. The first, and probably most obvious, tip is to keep characteristics small. Don’t use a 32 bit integer if 8 bits will do.
In general, the power consumption of a BLE device can be adjusted by fine-tuning parameters and configurations related to advertising and connection states, coordinating timer wakeup with any other system wakeups using special stack feature-Lazy timer.
Advertising#
Advertising Interval#
Advertising interval is adjustable, from 20 ms to 10.24 s (non-connectable: minimum is 100 ms). This can be
Increasing advertising interval from 100 ms to 1 s drops the average current consumption by 93%.
TX Power Level#
The transmit power is adjustable, from -26 dBm to +8 dBm (default is 8 dBm). 0 dBm is enough to cover about 10 to 15 m range, based on tests made with iBeacon example and Android phone. The transmission power can easily be changed in applications using the API call to cmd_system_set_tx_power()
.
Changing the TX power from 8 dBm to 0 dBm can reduce the current consumption by more than 120% using 100 ms advertising interval, and 105% using 1 s advertising interval.
Advertising Mode (Connectable / Non-Connectable)#
Non-connectable mode supports only the TX operation, whereas connectable mode of advertising supports both TX and RX operations.
Deep Sleep Modes#
If sleep is enabled (as in most of the examples), the stack can enter EM2 mode automatically between advertising events.
In some cases, going to EM3 and EM4 between advertising may be possible to save energy. This, however, only applies to non-connectable advertisements. For more information, see Using Energy Modes with Bluetooth Stack
Connection#
Connection Interval#
As with advertising, the connection interval has a direct impact on the current consumption. The connection interval can be adjusted between 7.5 ms and 4 s and is an easy way to trade-off between latency/throughput and average current consumption.
The following graph shows the average current required to keep the connection up, with different connection intervals (at 0 dBm TX power). The RF duty cycle is calculated based on the 1.5 ms activity in each interval.
Slave Latency#
Slave latency ensures that the peripheral (slave) device can skip N connection intervals if it does not have anything to transmit. Note, however, that the central (master) device still needs to poll the peripheral at every connection interval.
With a connection interval of 75 ms, in the above graphs, changing the slave latency value to 5 can drop down the average current consumption from 230 uA to 140 uA (40% saving).
TX Power Level#
The same TX power level setting (cmd_system_set_tx_power()
) applies to advertisements and connections.
PHY (1M / 2M Coded PHY )#
Bluetooth 5 5 introduced 2M PHY for faster throughput and higher energy efficiency. This can lower the average current by reducing the air time of the radio and allowing the MCU to sleep more. The following graph compares the current consumption for a short packet transmission over 1M (left) and 2M (right) PHYs connections with a connection interval of 25 ms, in both cases. Going from 1M to 2M PHY, the energy consumption is reduced by 15%. For larger data transmissions the gain can be even higher.
Stack Features#
In addition to the settings and configurations for advertising and connections, it is possible to minimize power consumption by using the Lazy-timer. Lazy timer allows coordinating MCU wakeups with RF activity. For more information about the lazy soft timer, see Using the Lazy Soft Timer.
Setting up#
This simple example demonstrates the impact of advertising and connection parameters on the power consumption of a BLE device. Follow the instructions below and verify the result by using the Energy Profile perspective in SimplicityStudio.
Create a new
SOC - Empty
project in SimplicityStudio.Open
app.c
file and replace thesystem_boot
event handler with the following code.case gecko_evt_system_boot_id: bootMessage(&(evt->data.evt_system_boot)); printLog("Low power test started\n\r\n"); /* set transmit power */ gecko_cmd_system_set_tx_power(0); gecko_cmd_le_gap_set_advertise_timing(0, 160, 160, 0, 0); /* Start general advertising and enable connections. */ gecko_cmd_le_gap_start_advertising(0, le_gap_general_discoverable, le_gap_connectable_scannable); break;
Similarly, replace the
le_connection_opened
event handler with code below.case gecko_evt_le_connection_opened_id: printLog("connection opened\r\n"); /* go for a longer connection interval * latency = 0, timeout = 32000 ms * * timeout > (1+latency)*2*max_interval ms * therefore, max latency <= [timeout/(2*max_interval)] - 1 * * should be possible to use latency = 15 * * */ //gecko_cmd_le_connection_set_timing_parameters(evt->data.evt_le_connection_opened.connection, 700,760,1,600,0,0xffff); break;
Create
le_connection_parameters
event handler by adding following code under the comment/* Add additional event handlers as your application requires */
case gecko_evt_le_connection_parameters_id: { uint16 interval = evt->data.evt_le_connection_parameters.interval, latency = evt->data.evt_le_connection_parameters.latency, timeout = evt->data.evt_le_connection_parameters.timeout; printLog("connection interval %d, latency %d, timeout %d ms\n", interval, latency, timeout * 10); } break;
Open
app.h
and enableDEBUG_LEVEL
by setting it to 1.Build the project and download to your radio board. Open console and it will display the message “Low power test started” after a reset.
The Bluetooth specification allows the advertising interval to be anywhere between 20 ms and 10.24 s. In this configuration, the application uses default settings for the advertising interval (100 ms), and +8 dBm on a BGM121. This configuration results in an average current of 419 uA.
Set the transmit power to 0 dBm by changing
gecko_cmd_system_set_tx_power(80);
togecko_cmd_system_set_tx_power(0);
inapp.c
. Rebuild and download again to see the current consumption.
By reducing the transmit power to 0 dBm while keeping the same 100 ms advertising interval, the average current is reduced to 190 uA.
Increase the advertising interval to 1000 ms by changing
gecko_cmd_le_gap_set_advertise_timing(0, 160, 160, 0, 0);
; togecko_cmd_le_gap_set_advertise_timing(0, 1600, 1600, 0, 0);
inapp.c
. Then, rebuild and download once more to see current consumption.
By increasing the advertising interval to 1000 ms, the average current is reduced to 21.5 uA.
Connect to the device using the Silicon Labs EFR Connect app and check the power consumption. The console will display a message indicating the actual connection parameters being used.
The above figure shows the power consumption of the device when connected with an iOS phone. Using an Android device will produce slightly lower results since Android’s default connection interval is longer than that used by the iOS.
Another factor affecting average current consumption is the connection interval. A short connection interval results in higher throughput but also incurs an energy cost while a longer connection interval limits data throughput but also provides energy savings. The default connection intervals used by iOS and Android are currently 30 ms and 50 ms respectively. As shown below, the average current at 0 dBm and a 30 ms connection interval is approximately 228 uA.
Change the connection interval to between 875 - 950 ms by uncommenting the line //gecko_cmd_le_connection_set_timing_parameters(evt->data.evt_le_connection_opened.connection, 700,760,1,600,0,0xffff);
. Rebuild and download and connect again with the mobile app. The console should show the new connection parameters in use.
By using a longer connection interval, 950 ms, the average current is to approximately 25 uA.
Change the slave latency to 5 by changing the code
gecko_cmd_le_connection_set_timing_parameters(evt->data.evt_le_connection_opened.connection, 700,760,1,600,0,0xffff);
to
```cpp
gecko_cmd_le_connection_set_timing_parameters(evt->data.evt_le_connection_opened.connection, 700,760,5,3200,0,0xffff);;
```
Rebuild and download the application again and connect with the mobile app.
By increasing the slave latency, i.e., the number of intervals the slave can skip when it has no data to send, to 5 the average current drops below 10 uA.
Select the connection parameters carefully so that several retries are possible to ensure stable connections. The timeout must be greater (1+latency)*2*max_connection_interval
. As a result, if the maximum connection interval is chosen to be 950 ms and the timeout is set to the maximum, 32 seconds then the maximum latency allowed is 15. However, this will result in an unstable connection, so the latency in this example is set to 5 to allow for 2 retries.
Conclusion#
There is always a trade off between current consumption and data throughput. The application needs for battery life and throughput must be considered when choosing a connection interval. A longer connection interval will help improve battery life but will reduce throughput and may result in an unreliable or unstable connection unless the connection parameters are chosen carefully.