Here's an update on the power consumption profile when using the BLE API. It's
a topic of considerable importance for BLE; and we target the best that the
radio controller has to offer. It is our goal that the power consumed by the
BLE stack (together with BLE API) will be dwarfed by the overhead of driving
the radio.
Measuring power can be tricky with BLE because of the large dynamic range
involved; the baseline currents are around 6-10uAmps while the BLE stack is
idling, but consumption jumps to 10-15mAmps when the radio is used. That's a
variance of 3 orders of magnitude. Traditional methods such as measuring the
voltage drop across a sense resistor don't have enough of a dynamic range, and
so don't work very well. In some cases useful measurements can be obtained as
averages (some multi-meters offer reasonably accurate estimates of average
currents through the use of min-max-avg modes); else through the use of auto-ranging
oscilloscopes.
Some of the dev boards (such as the mkit) pose a further challenge in the form
of introducing the mbed interface-chip into the equation. Measuring power by
observing what's fed into the USB input to the board gives misleading numbers
due to the overheads of the supporting circuitry. In those cases, it becomes
necessary to isolate the extraneous components through appropriate jumpers and
schematic-study; and by switching to battery supply instead of USB. Measuring
from a custom board with minimal components (or through the use of something
like the smart-beacon kit) is another successful strategy.
Using the smart beacon kit (where the inteface chip is absent), the BLE_Beacon
example on mbed consumes 35uA of average current. Here's a power profile for
that use-case.
The vertical axis in this figure is the current consumption (in milli-amps),
and the horizontal axis shows time. This picture captures nearly 1 second of
activity. The major peak is an advertising event where a beacon is broadcast;
the minor peak comes from periodic housekeeping activities of the bluetooth
stack. Outside the peaks, current consumption is around 6uAmps (when measured
using instruments with 0.1uA precision); as can be seen from the instantaneous
current value of 0.01mA.
The primary contribution to power consumption comes from the use of the radio.
Please note that the radio peaks at 12-15mA of current for around 2ms during
every advertisement event (where advertising payload must be sent out over the
three advertising channels and then the radio is run a little longer to look
for scan-requests or connection requests). In the default beacon example,
advertisements are sent out at 1Hz (once every second) and at a power level of
0dB; both of these factors are under the control of the developer. This
should give you an idea of what's possible.
The average current, highlighted with a red underline on the left panel, is
around 35uAmps; and with a coin cell battery the system may be expected to
last around 7000 hours (which is nearly a year).
Here are some of the strategies we've employed on the Nordic nRF51822 to lower
baseline power consumption:
- The system now starts with low-frequency clock by default (instead of using
the external 16MHz clock). The high frequency clock is still kicked into
action automatically by the soft-device when needed; but now it doesn't
remain active all the time. This by itself lowers the baseline consumption
significantly. It also means that if an application needs the high-
frequency clock (such as for any high-speed serial communication), then it
must enable the external clock source explicitly; and hopefully the
external clock will be managed in a power-conscious manner, which means
that clocks will be turned off when not needed.
- We make an effort to avoid using wait() API from mbed. This API is currently
synchronous and wastes a lot of power.
- We've also re-implemented the Ticker APIs to use the RTC instead of a high-
frequency timer. This makes a tradeoff between precision and power; and we
believe power trumps over precision in the context of BLE.
It's worth re-emphasizing this. Users are free to enable high-frequency timers
explicitly if needed. If an application requires the use of high-frequency
clock (for instance to do serial communication at high baud rates), then it
must enable the high-frequency clock by writing into the appropriate control
registers (please refer to the datasheets of the nRF51822). It would help to
turn off high-frequency clocks at the earliest opportunity.
Users may also experiment with reducing the transmit power of their radio;
there's an API for this.
Connection intervals and connection latency are also available for
modification, and play a very important role in power consumption.
Please try using the following API once a connection is made in order to
request the central to update the settings:
BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params)
It is ultimately up to the central/master to choose the connection parameters.
Your requested settings may not be honored.
Please take notice of the following comment from ble_gap.h (under nrf-
sdk/s110) and also pay attention to the constraint mentioned mentioned at the
end:
/**@brief Update connection parameters.
*
* @details In the central role this will initiate a Link Layer connection parameter update procedure,
* otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for
* the central to perform the procedure. In both cases, and regardless of success or failure, the application
* will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
*
* @note If both a connection supervision timeout and a maximum connection interval are specified, then the following constraint
* applies: (conn_sup_timeout * 8) >= (max_conn_interval * (slave_latency + 1))
...
Here's one
user's attempt to reduce connection intervals for the heart-rate demo after a
connection has been established:
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(379, UNIT_1_25_MS) /**< Minimum connection interval (379 ms) */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(399, UNIT_1_25_MS) /**< Maximum connection interval (399 ms). */
#define SLAVE_LATENCY 4 /**< Slave latency. */
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(6000, UNIT_10_MS) /**< Connection supervisory timeout (6 seconds). */
void onConnectionCallback(Gap::Handle_t handle, const Gap::ConnectionParams_t *p_conn_param)
{
Gap::ConnectionParams_t gap_conn_params;
gap_conn_params.minConnectionInterval = MIN_CONN_INTERVAL;
gap_conn_params.maxConnectionInterval = MAX_CONN_INTERVAL;
gap_conn_params.slaveLatency = SLAVE_LATENCY;
gap_conn_params.connectionSupervisionTimeout = CONN_SUP_TIMEOUT;
ble.updateConnectionParams(handle, &gap_conn_params);
}
...
The mbed team is also working towards asynchronous (non-blocking, interrupt-
driven) APIs; automatic, smart management of clocks; and the use of DMA. Once
these are in place, even non-trivial applications should be able to exhibit
excellent power profiles.
Here's an update on the power consumption profile when using the BLE API. It's a topic of considerable importance for BLE; and we target the best that the radio controller has to offer. It is our goal that the power consumed by the BLE stack (together with BLE API) will be dwarfed by the overhead of driving the radio.
Measuring power can be tricky with BLE because of the large dynamic range involved; the baseline currents are around 6-10uAmps while the BLE stack is idling, but consumption jumps to 10-15mAmps when the radio is used. That's a variance of 3 orders of magnitude. Traditional methods such as measuring the voltage drop across a sense resistor don't have enough of a dynamic range, and so don't work very well. In some cases useful measurements can be obtained as averages (some multi-meters offer reasonably accurate estimates of average currents through the use of min-max-avg modes); else through the use of auto-ranging oscilloscopes.
Some of the dev boards (such as the mkit) pose a further challenge in the form of introducing the mbed interface-chip into the equation. Measuring power by observing what's fed into the USB input to the board gives misleading numbers due to the overheads of the supporting circuitry. In those cases, it becomes necessary to isolate the extraneous components through appropriate jumpers and schematic-study; and by switching to battery supply instead of USB. Measuring from a custom board with minimal components (or through the use of something like the smart-beacon kit) is another successful strategy.
Using the smart beacon kit (where the inteface chip is absent), the BLE_Beacon example on mbed consumes 35uA of average current. Here's a power profile for that use-case.
The vertical axis in this figure is the current consumption (in milli-amps), and the horizontal axis shows time. This picture captures nearly 1 second of activity. The major peak is an advertising event where a beacon is broadcast; the minor peak comes from periodic housekeeping activities of the bluetooth stack. Outside the peaks, current consumption is around 6uAmps (when measured using instruments with 0.1uA precision); as can be seen from the instantaneous current value of 0.01mA.
The primary contribution to power consumption comes from the use of the radio. Please note that the radio peaks at 12-15mA of current for around 2ms during every advertisement event (where advertising payload must be sent out over the three advertising channels and then the radio is run a little longer to look for scan-requests or connection requests). In the default beacon example, advertisements are sent out at 1Hz (once every second) and at a power level of 0dB; both of these factors are under the control of the developer. This should give you an idea of what's possible.
The average current, highlighted with a red underline on the left panel, is around 35uAmps; and with a coin cell battery the system may be expected to last around 7000 hours (which is nearly a year).
Here are some of the strategies we've employed on the Nordic nRF51822 to lower baseline power consumption:
- The system now starts with low-frequency clock by default (instead of using the external 16MHz clock). The high frequency clock is still kicked into action automatically by the soft-device when needed; but now it doesn't remain active all the time. This by itself lowers the baseline consumption significantly. It also means that if an application needs the high- frequency clock (such as for any high-speed serial communication), then it must enable the external clock source explicitly; and hopefully the external clock will be managed in a power-conscious manner, which means that clocks will be turned off when not needed.
- We make an effort to avoid using wait() API from mbed. This API is currently synchronous and wastes a lot of power.
- We've also re-implemented the Ticker APIs to use the RTC instead of a high- frequency timer. This makes a tradeoff between precision and power; and we believe power trumps over precision in the context of BLE.
It's worth re-emphasizing this. Users are free to enable high-frequency timers explicitly if needed. If an application requires the use of high-frequency clock (for instance to do serial communication at high baud rates), then it must enable the high-frequency clock by writing into the appropriate control registers (please refer to the datasheets of the nRF51822). It would help to turn off high-frequency clocks at the earliest opportunity.
Users may also experiment with reducing the transmit power of their radio; there's an API for this.
Connection intervals and connection latency are also available for modification, and play a very important role in power consumption.
Please try using the following API once a connection is made in order to request the central to update the settings:
It is ultimately up to the central/master to choose the connection parameters. Your requested settings may not be honored.
Please take notice of the following comment from ble_gap.h (under nrf- sdk/s110) and also pay attention to the constraint mentioned mentioned at the end:
Here's one user's attempt to reduce connection intervals for the heart-rate demo after a connection has been established:
The mbed team is also working towards asynchronous (non-blocking, interrupt- driven) APIs; automatic, smart management of clocks; and the use of DMA. Once these are in place, even non-trivial applications should be able to exhibit excellent power profiles.