Bluetooth: Automated power control

The Automated power control sample demonstrates how to monitor the Bluetooth® Low Energy signal strength (RSSI) and dynamically adjust the transmit (TX) power of a connected Peripheral device. There are two versions of this sample: One for the central device (in the rssi_power_control/central folder) and one for the peripheral device (in the rssi_power_control/peripheral folder)

The sample for the central device collects RSSI data and sends power control commands to optimize the connection quality, which in turn optimizes the current consumption.

The sample for the peripheral device is simply advertising its existence, allowing the central device to establish a connection.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Board target

nRF54L15 DK

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l15/cpuapp

nRF52840 DK

PCA10056

nrf52840dk

nrf52840dk/nrf52840

You must use two compatible development kits to run this sample, one running the version for the central device (rssi_power_control/central) and one running the version for the peripheral device (rssi_power_control/peripheral).

Overview

This sample illustrates Bluetooth LE power control by having the central device read the RSSI of an active connection and use it to adjust the transmit power of the peripheral version. The central version directly invokes SoftDevice Controller (SDC) APIs to configure power control behavior based on RSSI measurements. This approach only works on single-core platforms where the Bluetooth Controller and application run on the same core.

There are two ways to monitor the connection parameters:

  • Terminal output - Connects to the Central device’s virtual serial port to view RSSI and TX power logs in real time.

  • Graphical plotting - Uses the provided script to visualize signal strength over time:

    python3 tools/plot_path_loss.py --comport COMPORT
    

Note

Make sure no terminal is open on the same serial port when using the Python plotting script, as it requires exclusive access. Example of serial port - /dev/ttyACM1.

This sample works only on single-core SoCs because it directly calls sdc_* functions (such as sdc_hci_cmd_vs_set_power_control_request_params()) that are only accessible on the core running the Bluetooth Controller. On dual-core platforms such as nRF5340 or nRF54H20 SoCs, the Bluetooth Controller runs on the network core, making these calls inaccessible from the application core and resulting in linker errors.

Workaround for dual-core SoCs

To adapt this sample for dual-core SoCs:

  1. Remove all sdc_* function calls from the application.

  2. Use Zephyr HCI commands to interface with the controller:

struct net_buf *buf = bt_hci_cmd_alloc(...);
bt_hci_cmd_send_sync(...);

Refer to the HCI Power Control sample or Nordic DevZone for reference implementations.

User interface

The following is the user interface used by the two versions of this sample:

Central device:

  • Virtual serial output displays live RSSI and TX power data.

  • Optional plotting provides a visual graph of signal variation over time.

Peripheral device:

  • No direct user interface.

  • Automatically accepts connections and responds to TX power control commands.

Configuration

See Configuring and building for information about how to permanently or temporarily change the configuration.

Additional configuration

Check and configure the following Kconfig options:

Building and running

This sample can be found under samples/bluetooth/power_control_demo in the nRF Connect SDK folder structure.

To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Note

When building repository applications in the SDK repositories, building with sysbuild is enabled by default. If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.

When building this sample with Sysbuild for an SoC that has a network core, the IPC radio firmware is automatically applied to the build. The IPC radio is one of the companion components in the nRF Connect SDK and allows to use the radio peripheral from another core in a multicore device. If needed, you can modify the IPC radio configuration in the prj.conf source file in the sample’s sysbuild/ipc_radio directory.

Testing

After programming the sample to your development kit, complete the following steps to test it:

  1. Program one development kit with the power control firmware for the peripheral device.

  2. Program another development kit with the power control firmware for the central device.

  3. Open a terminal on the Central’s virtual serial port or run the plotting script.

  4. Power on both devices.

  5. The Central will scan and connect to the Peripheral automatically.

  6. Observe RSSI and TX power data printed or plotted.

  7. Move the devices or add obstructions to see dynamic power adjustment.

Sample output

The following output is logged from the central device:

[00:00:01.000,000] I: Starting BLE Central
[00:00:01.500,000] I: Scanning for peripherals...
[00:00:03.020,000] I: Found peripheral: FF:EE:DD:CC:BB:AA (random)
[00:00:03.050,000] I: Connection to FF:EE:DD:CC:BB:AA (random)
[00:00:03.800,000] I: Connected to FF:EE:DD:CC:BB:AA (random)
[00:00:05.010,000] I: Successful initialization of power control
[00:00:06.010,000] I: Tx: 0 dBm, RSSI: -33 dBm
[00:00:07.010,000] I: Tx: -9 dBm, RSSI: -45 dBm

Dependencies

This sample uses the following nRF Connect SDK libraries:

It also relies on the following Zephyr’s Bluetooth and HCI layers:

  • Kernel Services:

    • include/zephyr/kernel.h

  • API:

    • include/zephyr/bluetooth/addr.h

    • include/zephyr/bluetooth/bluetooth.h

    • include/zephyr/bluetooth/conn.h

  • Logging:

    • include/zephyr/logging/log.h

If using the optional Python plotting script, the following dependencies are required:

  • Python 3.6 or newer

  • The following Python modules:

    pip install pyserial matplotlib