Page 1 of 1

esp_ble_tx_power_set has no effect

Posted: Fri Jul 27, 2018 4:46 am
by espdude
Hi All,

I am playing with esp_ble_tx_power_set API to set maximum BLE TX power during advertisement and communication.
I run my code on WROVER-I module acting as BLE peripheral, latest IDF version, however I observe the issue for at least six months with latest IDF version.

What I have noticed is that changing esp_ble_tx_power_set has no effect on advertised TX level and also very limited (if any) effect on BLE connection distance (it is always around 10 meters indoors).

In my esp_ble_adv_data_t I set .include_txpower = true, and can observe advertised TX power using NRF Connect, however it is always -21dbm regardless of the value passed to esp_ble_tx_power_set.

Also, as I mentioned I do not notice any significant difference between ESP_PWR_LVL_P9 and ESP_PWR_LVL_N12, while I expect it to be clearly noticeable by communication distance.

Below is the code I use to change the TX level. Use both together with WiFi and without it. Can anyone suggest if this API has bugs, should I do it differently, or my expectations are just wrong?

Code: Select all

	esp_err_t ret;
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s initialize controller failed\n", __func__);
        return;
    }
    ESP_LOGI(BLE_TAG, "%s initialize controller success\n", __func__);

    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s enable controller failed\n", __func__);
        return;
    }
    ESP_LOGI(BLE_TAG, "%s enable controller success\n", __func__);

    ESP_LOGI(BLE_TAG, "%s Successfully set BLE Tx power level\n", __func__);

    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s init bluetooth failed\n", __func__);
        return;
    }
    ESP_LOGI(BLE_TAG, "%s init bluetooth success\n", __func__);

    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s enable bluetooth failed\n", __func__);
        return;
    }
    ESP_LOGI(BLE_TAG, "%s enable bluetooth success\n", __func__);

    ret = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9);
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s Unable to set BLE Tx power level\n", __func__);
        return;
    }
    ESP_LOGI(BLE_TAG, "%s Successfully set BLE Tx power level\n", __func__);

    ret = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
    if (ret) {
        ESP_LOGE(BLE_TAG, "%s Unable to set BLE Tx power level\n", __func__);
        return;
    }

Re: esp_ble_tx_power_set has no effect

Posted: Mon Jul 30, 2018 4:41 pm
by billiam
My code looks just like yours.

I am seeing a 20dbm difference in advertising RSSI using a ble monitor app between LVL_P7 and LVL_N14. I have not tested transmit power when connected. I am disappointed that N14 is as low as it can go. It is still, at N14, a stronger signal (rssi=-70) at 4 feet than any of my test sensors and I am kind of desperate to (further) reduce power consumption.

My range is much better than 10M using defaults. More like 100M through walls. I am using a WROVER-KIT.

Re: esp_ble_tx_power_set has no effect

Posted: Thu Aug 16, 2018 4:05 pm
by genedyne
I'm seeing the same as you describe.
I set the 'default' power for advertising using:

Code: Select all

esp_ble_tx_power_set( ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9 );
This function is called prior to starting advertisment, and the flag is set in advertising data to include Tx power. According to esp_ble_power_t defintion in esp_bt.h, this default power should be used for advertising, scans & connections if not explicitly set.

nRF Connect always reports the Tx Power listed in the ADV data as -21dBm.

Thinking this might be stale information, that the IDF (incorrectly) never updates, I also tried explicitly setting the connection Tx power
using:

Code: Select all

esp_ble_tx_power_set( ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9 );
This produced the same result: ADV data still shows Tx Power is -21dBm.

I then enabled the RSSI graph (on the nRF Connect 'scanner' screen, open the '3 dots' menu).
The image below shows RSSI at ESP_PWR_LVL_P9 (only the red trace is relevant):
RSSI_ESP_PWR_LVL_P9.jpg
RSSI_ESP_PWR_LVL_P9.jpg (106.24 KiB) Viewed 2533 times
The image below shows RSSI at ESP_PWR_LVL_DEFAULT:
RSSI_ESP_PWR_LVL_DEFAULT.jpg
RSSI_ESP_PWR_LVL_DEFAULT.jpg (106.49 KiB) Viewed 2533 times
The image below shows RSSI at ESP_PWR_LVL_N12:
RSSI_ESP_PWR_LVL_N12.jpg
RSSI_ESP_PWR_LVL_N12.jpg (102.46 KiB) Viewed 2533 times
Averaging the RSSI of the top image, and comparing with average RSSI of the bottom image does show a clear difference. The change from defaults to P9 appears nominal at best. The comment at the top of esp_ble_power_type_t in esp_bt.h indicates ESP_PWR_LVL_P3 (+3dBm) is used as default, if nothing has been set.

I also tried explicitly setting the connection Tx power using:

Code: Select all

esp_ble_tx_power_set( ESP_BLE_PWR_TYPE_CONN_HDL0, ESP_PWR_LVL_P9 );
Following comment at top of esp_ble_power_type_t defintion in esp_bt.h, this function is called when a connection has been established (handling 'ESP_GATTS_CONNECT_EVT', so connection handle 0 is valid). I found only a (possible) nominal affect on range with ESP_PWR_LVL_P9 compared to operating with default (P3) settings.

I've tested with ESP IDF branch v3.1, & with current master (020ade6), with the same results.

In any event, it appears the TxPower parameter in ADV data is NOT being updated when Tx Power setting is changed.

Re: esp_ble_tx_power_set has no effect

Posted: Fri Aug 17, 2018 12:10 pm
by genedyne
Could you post snapshots of the nRF Connect RSSI graph of your modules, running at PWR_LVL_N12 & PWR_LVL_P9?
That should provide some clue if the modules are somehow at fault.
At least we know you can ignore the -21dBm TxPower in the advertising packet.