This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to set tx_power using sd_ble_gap_tx_power_set() on nrf52832?

Hi Everyone,

I am working on nrf52832, I am using sdk15.0.0 ble_peripheral /ble_app_beacon as reference.

I want to set TX_POWER using sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle,RADIO_TXPOWER_TXPOWER_Pos4dBm);

  m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;

when I called this function after the ble_advertising function,err_code return 12292.

actually i am not understood BLE_GAP_ADV_SET_HANDLE_NOT_SET=0xFF.

Initially tx_power set to 4dbm but when softdevice enable getting error (code stuck at blx ,r3).

I am also trying using NRF_RADIO->TX_POWER=RADIO_TXPOWER_TXPOWER_Pos4dBm;

Register initially set to 4dbm but after call ble_stack_init() it set to 0dbm.When you change txpower, you need to update this value of the advertising data, it doesn't get updated automatically by the softdevice. 

 I think I forgot some configuration in my code, Can you suggest a proper solution to see the changes in TXPOWER.

thanks.

Parents
  • Hi,

    Error code 12292 = 0x3004 = BLE_ERROR_INVALID_ADV_HANDLE. The issue here is that you do not provide the correct advertising handle, which you get from the call to sd_ble_gap_adv_set_configure(). See this post.

  • thanks for reply, 

    i am passing below parameter, 

    err_code = sd_ble_gap_adv_set_configure(&(m_adv_handle), &m_adv_data, &m_adv_params);

    Is this wrong?

    I want to set TX_POWER using sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_adv_handle,RADIO_TXPOWER_TXPOWER_Pos4dBm);

    This function called after the advertising_start() .

    Is this right way to set the tx_power ? 

  • hi, 

    i am trying to set tx_power through scan response parameter,

    Tx power set through that but not continuosly it gives me one time 0 and one time 4dbm.

    srdata.p_tx_power_level = &m_tx_power;

    printf("after memset_srdata %d\t",&srdata);

    this parameter set in advertising_init() function.

    when data is update that time  err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); return invalid state error.

    but i need to set tx_power continuously not need to change.

    I am trying to provide new array in advertising_upadate() but not set continuosly .

    please check the log file attached it. Mac_id of my device is Address: e9:98:e4:e3:ad:b1

    15:45:38.965 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f410000020001cdc00000000 
    15:45:38.965 ->  RSSI: -49 TxPower: 0
    15:45:39.287 -> Devices found: 2
    15:45:39.287 -> Scan done!
    15:45:39.407 -> Advertised Device: Name: , Address: 47:af:bd:6d:6b:cf, manufacturer data: 0600010920026c3227c22cdd301dc276a5350e365f64a95c4923e9cda2 
    15:45:39.407 ->  RSSI: -83 TxPower: 0
    15:45:40.007 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f510000020001cdc00000000, txPower: 4 
    15:45:40.007 ->  RSSI: -49 TxPower: 4
    15:45:40.287 -> Devices found: 2
    15:45:40.287 -> Scan done!
    15:45:40.407 -> Advertised Device: Name: , Address: 47:af:bd:6d:6b:cf, manufacturer data: 0600010920026c3227c22cdd301dc276a5350e365f64a95c4923e9cda2 
    15:45:40.407 ->  RSSI: -83 TxPower: 0
    15:45:41.007 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f610000020001cdc00000000 
    15:45:41.007 ->  RSSI: -49 TxPower: 0
    15:45:41.287 -> Devices found: 2
    15:45:41.287 -> Scan done!
    15:45:41.407 -> Advertised Device: Name: , Address: 47:af:bd:6d:6b:cf, manufacturer data: 0600010920026c3227c22cdd301dc276a5350e365f64a95c4923e9cda2 
    15:45:41.407 ->  RSSI: -82 TxPower: 0
    15:45:42.007 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f810000020001cdc00000000, txPower: 4 
    15:45:42.007 ->  RSSI: -49 TxPower: 4
    15:45:42.287 -> Devices found: 2
    15:45:42.287 -> Scan done!
    15:45:42.418 -> Advertised Device: Name: , Address: 47:af:bd:6d:6b:cf, manufacturer data: 0600010920026c3227c22cdd301dc276a5350e365f64a95c4923e9cda2 
    15:45:42.418 ->  RSSI: -86 TxPower: 0
    15:45:42.983 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f910000020001cdc00000000 
    15:45:42.983 ->  RSSI: -49 TxPower: 0
    15:45:43.303 -> Devices found: 2
    15:45:43.303 -> Scan done!
    15:45:43.417 -> Advertised Device: Name: , Address: 47:af:bd:6d:6b:cf, manufacturer data: 0600010920026c3227c22cdd301dc276a5350e365f64a95c4923e9cda2 
    15:45:43.417 ->  RSSI: -85 TxPower: 0
    15:45:44.020 -> Advertised Device: Name: , Address: e9:98:e4:e3:ad:b1, manufacturer data: 59000215454d422d3101000001f910000020001cdc00000000, txPower: 4 
    15:45:44.020 ->  RSSI: -50 TxPower: 4

  • Hi,

    ande_dewal said:
    i am trying to set tx_power through scan response parameter,

    I am not sure I understand. Do you mean set the actual Tx power or some data in the scan response packet that indicate the Tx power (typically measured at a specific distance)? Please elaborate.

    ande_dewal said:
    when data is update that time  err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); return invalid state error.

    If you try to change the configuration of a currently active advertiser, you will get invalid state. In this case, you should stop advertising and start again. This is not the way to change Tx power though, so I am not sure what you want to do. If you are having a different problem now, then please backtrack and explain in detail from the beginning.

    ande_dewal said:
    but i need to set tx_power continuously not need to change.

    Can you explain more? Do you want to set it once, or do you want to set it repeatedly? In any case, to change the Tx power you use sd_ble_gap_tx_power_set() as we have discussed before and as described in the API documentation.

  • thanks for reply,

    1)i am trying to set tx_power through scan response parameter

    firstly i am setting tx_power through sd_ble_gap_tx_power_set() but not set it gives always 0dbm. another way i tried to set tx power through scan response paramter. 

    first change the structure member ,

    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = m_enc_advdata[0],
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        },
        .scan_rsp_data =
        {
            .p_data = m_enc_srdata[0],
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        }
    };
    

    after that this setting in advertising_init function()

     //// Build and set scan response data.
        memset(&srdata, 0, sizeof(srdata));
        printf("\n/#/#/#   D   #/#/#/\n");
        srdata.p_tx_power_level = &m_tx_power;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        //printf("\n/#/#/#   E   #/#/#/\n");
    
        //printf("after memset_adv_param %d\t",&m_adv_params);
        // printf("after memset_adv_param %d\n",m_adv_params);
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED; //Beacon needs to be scannable to receive scan response
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        //m_adv_params.primary_phy     = BLE_GAP_PHY_CODED;
        //m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED;
    
       //printf("\n/#/#/#   F   #/#/#/\n");
       err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        printf("err_code_encode : %d\n",err_code);
        APP_ERROR_CHECK(err_code);
        err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    
       //printf("\n/#/#/#   G   #/#/#/\n");
    
       
      
       //printf("\n/#/#/#   H   #/#/#/\n");
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);

    while set the advertising_update() return err_code invalid state .please help me for solved this problem.

       //printf("\n/#/#/#   b   #/#/#/\n");
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info1;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
        //printf("address of array %d\n",&m_beacon_info1);
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
        
        //printf("\n/#/#/#   c   #/#/#/\n");
    
    
        //int8_t tx_power                 = 4;
        //advdata.p_tx_power_level        = &tx_power;
    
        //advdata.name_type             = BLE_ADVDATA_SHORT_NAME;
        //  advdata.short_name_len          = 5;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
         // Build and set scan response data.
        //memset(&srdata, 0, sizeof(srdata));
        //printf("\n/#/#/#   D   #/#/#/\n");
        //srdata.p_tx_power_level = &m_tx_power;
        //printf("after memset_srdata %d\t",&srdata);
        //printf("after memset_srdata %d\n",srdata);
        //srdata.name_type             = BLE_ADVDATA_FULL_NAME;
        
     /*swap adv data buffer - from API doc: "In order to update advertising 
        data while advertising,new advertising buffers must be provided"*/
        //m_adv_data.adv_data.p_data = (m_adv_data.adv_data.p_data == m_enc_advdata[0])         
         //                             ? m_enc_advdata[1] : m_enc_advdata[0];
        //adv_data_buf_swap();
         m_adv_data.adv_data.p_data = (m_adv_data.adv_data.p_data == m_enc_srdata[0])         
                                      ? m_enc_srdata[1] : m_enc_srdata[0];
        
    
       printf("advertising new array data %d\n",m_adv_data.adv_data.p_data == m_enc_advdata[0]);
       printf("flag = %d\n",falling_edge_detect);
       
       err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
       APP_ERROR_CHECK(err_code);
     
       //sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV , m_adv_handle,m_tx_power);
       //APP_ERROR_CHECK(err_code);
    
        //printf("\n/#/#/#   d   #/#/#/\n");
        // err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
        //APP_ERROR_CHECK(err_code);
    
      err_code = sd_ble_gap_adv_set_configure(&(m_adv_handle), &m_adv_data,NULL);
      printf("et_error_cde %d\n",err_code);
      APP_ERROR_CHECK(err_code);

  • The p_tx_power_level field points to the Tx power level field  in the advertising data. This is not directly related to the actual Tx power and does not set the Tx power for you. There is no problem specifying it here if you want the Tx power to be part of the advertising data, but this is just data. To adjust the physical Tx power, you must use sd_ble_gap_tx_power_set() as we have allready discussed.

  • thanks for reply,

    I tried using sd_ble_gap_tx_power_set()  but not set tx_power in my application. As our above discussion I called this function after the advertising_init() and before advertising_start(), still not set tx_power it always gives me 0dbm. 

    advertising_init();
     
     err_code = sd_ble_gap_tx_power_set(  BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle,RADIO_TXPOWER_TXPOWER_Pos4dBm);
      APP_ERROR_CHECK(err_code);
     advertising_start();
    please check this i am not understood ,what setting going wrong in my code. please help me for set tx_power for range . 

Reply
  • thanks for reply,

    I tried using sd_ble_gap_tx_power_set()  but not set tx_power in my application. As our above discussion I called this function after the advertising_init() and before advertising_start(), still not set tx_power it always gives me 0dbm. 

    advertising_init();
     
     err_code = sd_ble_gap_tx_power_set(  BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle,RADIO_TXPOWER_TXPOWER_Pos4dBm);
      APP_ERROR_CHECK(err_code);
     advertising_start();
    please check this i am not understood ,what setting going wrong in my code. please help me for set tx_power for range . 

Children
  • Hi,

    ande_dewal said:
    still not set tx_power it always gives me 0dbm. 

    How do you know that it is 0 dBm? How have you measured it? Could it be that the problem here is that you read the tx_value field of the advertising or scan response packet and misinterprets that as the actual Tx power? As mention before, those are two separate things altogether. sd_ble_gap_tx_power_set() is used to change the physical Tx power. You can optionally include the Tx power in your scan reponse/advertising packet, but that is just data. Do you want to signal the Tx power? If so, you can add that here, but you still need to actually change it using sd_ble_gap_tx_power_set().

    ande_dewal said:
    please help me for set tx_power for range . 

    You set tx_power using sd_ble_gap_tx_power_set() exactly as described in the API documentation.

  • thanks for response,

    At scanner, get_tx_power gives me 0dbm.also i checked at debugging on segger studio in RADIO->TX_POWER register . it always gives 0dbm. when i am using  below fun err_code = sd_ble_gap_tx_power_set(  BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle,RADIO_TXPOWER_TXPOWER_Pos4dBm);

    now, I am not set through scan response .

  • I see. Then the problem here is this misunderstanding. The physical Tx power and the Tx power you signal are completely independent. To check the physical Tx power you need to measure. Alternatively, you could check the RSSI using nRF Connect. Note that there will typically be a lot of variation in these measurements unless you have proper equipment, but you could for instance check to see that you see a clear difference between when you call sd_ble_gap_tx_power_set with 0 and -40 or similar.

Related