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

regarding about enhance the distance of range between the ble_app_uart_c_central and ble_app_uart_peripheral

I am using the two units talking with each other for the BLE uart. 

One is running with the example ble_app_uart_c_central. The other is running with the ble_app_uart_peripheral. Both example based on the SDK version nRF5_SDK_17.0.2_d674dde.

Also I am using the S140 softdevice. Both examples are running on the nrf52840 development boards as a pair. 

I want to use them for communication in as long distance as possible. Is there anyway can make it by setting up the TX power for the connection.  I am using your advice as the link below and did some changes to my code in the ble_app_uart_peripheral example side. But seems the distance for communication still around 10 meters, else the connection will lost. My aim is try to make it works for more than 250 meters.

Based on my changes: 1. Does it means the TX power for 8dBm only works for the advertisement mode and not working for the connection mode? 2. Do I need to do any modification for the  ble_app_uart_c_central  example side to improve the communication distance? 3. Do I need to change the S140 softdvice into other softdivce version to make the long distance communication? Does the S340 better for the long distance communication  4. Do I need to make any changes for the hardware side to make it long distance communication?

devzone.nordicsemi.com/.../282647

my modification for the code for the ble_app_uart_peripheral example side is lised below. 

static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advertising_init_t init;
    int8_t tx_power = 8; 

    memset(&init, 0, sizeof(init));

    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false;
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;

    init.config.ble_adv_fast_enabled  = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    init.evt_handler = on_adv_evt;

    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);

    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV , m_advertising.adv_handle, tx_power);
    APP_ERROR_CHECK(err_code);
}

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;
	int8_t tx_power = 8; //niklas

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            //NRF_LOG_INFO("Connected"); 
			status=1;
			status_connected=1;
			printf("Connected");nrf_delay_ms(1);
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            //reference https://jimmywongiot.com/2019/11/30/how-to-get-the-rssi-change-on-the-nrf5-sdk/
            //https://devzone.nordicsemi.com/f/nordic-q-a/69366/regarding-about-the-connection-rssi-for-signal-strength
            err_code = sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle,1,2);//niklas
            APP_ERROR_CHECK(err_code);

            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
			err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, m_conn_handle, tx_power); //niklas
			APP_ERROR_CHECK(err_code);
            break;

        //case BLE_GAP_EVT_RSSI_CHANGED:
        //     rssi_value=p_ble_evt->evt.gap_evt.params.rssi_changed.rssi;
        //     printf("RSSI=%d\n",p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);

        case BLE_GAP_EVT_DISCONNECTED:
		    status=2;
			status_connected=2;
            //NRF_LOG_INFO("Disconnected");
			printf("Disconnected");nrf_delay_ms(1);
            // LED indication will be changed when advertising starts.
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            status=3;
			//NRF_LOG_DEBUG("PHY update request.");
			printf("PHY update request.");nrf_delay_ms(1);
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
		     status=5;
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
		    status=6;
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
			status=7;
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
		    status=8;
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        default:
		    status=9;
            // No implementation needed.
            break;
    }
}

int main(void)
{
    bool erase_bonds;
    uint8_t find_flag;
        
    // Initialize.
    uart_init();
    log_init();
    timers_init();
    bsp_board_init(BSP_INIT_LEDS);



    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    // Start execution.
    advertising_start();

my modification for the code for the ble_app_uart_c_central example side is lised below. 

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;
	int8_t tx_power = 8; //niklas

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            //NRF_LOG_INFO("Connected"); 
			status=1;
			status_connected=1;
			printf("Connected");nrf_delay_ms(1);
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            //reference https://jimmywongiot.com/2019/11/30/how-to-get-the-rssi-change-on-the-nrf5-sdk/
            //https://devzone.nordicsemi.com/f/nordic-q-a/69366/regarding-about-the-connection-rssi-for-signal-strength
            err_code = sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle,1,2);//niklas
            APP_ERROR_CHECK(err_code);

            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
			err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, m_conn_handle, tx_power); //niklas
			APP_ERROR_CHECK(err_code);
            break;

        //case BLE_GAP_EVT_RSSI_CHANGED:
        //     rssi_value=p_ble_evt->evt.gap_evt.params.rssi_changed.rssi;
        //     printf("RSSI=%d\n",p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);

        case BLE_GAP_EVT_DISCONNECTED:
		    status=2;
			status_connected=2;
            //NRF_LOG_INFO("Disconnected");
			printf("Disconnected");nrf_delay_ms(1);
            // LED indication will be changed when advertising starts.
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            status=3;
			//NRF_LOG_DEBUG("PHY update request.");
			printf("PHY update request.");nrf_delay_ms(1);
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
		     status=5;
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
		    status=6;
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
			status=7;
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
		    status=8;
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        default:
		    status=9;
            // No implementation needed.
            break;
    }
}

Thank you in advance. 

Parents Reply Children
  • Hi, I think I have sloved the issue with the long range connection. But in the long range connection, it seems can not streaming the data with long package size for the ble sending 

    In the peripheral side, when it call the intrruption function "void in_pin_handler(void)" been called for each 20 seconds, in each call it sending the bluetooth package to the centeral unit by the function "void niklas_ble_send_array_handler(void)". when the package is big, for example size is 70 as below the parameter set, then comes out memory issues. 

    ble_tx_buffer_acc_len=70;
    ble_tx_buffer_ang_len=70;

    code as below

    void niklas_ble_send_array_handler(void)
    {
      uint32_t       err_code;
      #ifdef DEBUG_BLE_SEND_DEBUG
      printf("G1 \r\n");nrf_delay_ms(1);
      #endif
      if(ble_tx_buffer_acc_len<BLE_NUS_MAX_DATA_LEN)
      {
         do
         {
         
             err_code = ble_nus_data_send(&m_nus, ble_tx_buffer_acc, &ble_tx_buffer_acc_len, m_conn_handle);
             if ((err_code != NRF_ERROR_INVALID_STATE) &&
                 (err_code != NRF_ERROR_RESOURCES) &&
                 (err_code != NRF_ERROR_NOT_FOUND))
             {
                 APP_ERROR_CHECK(err_code);
             }
         } while (err_code == NRF_ERROR_RESOURCES);	  
      }
    
      #ifdef DEBUG_BLE_SEND_DEBUG
      printf("G2 \r\n");nrf_delay_ms(1);
      #endif
      if(ble_tx_buffer_acc_len<BLE_NUS_MAX_DATA_LEN)
      {  
         do
         {
             
             err_code = ble_nus_data_send(&m_nus, ble_tx_buffer_ang, &ble_tx_buffer_ang_len, m_conn_handle);
             if ((err_code != NRF_ERROR_INVALID_STATE) &&
                 (err_code != NRF_ERROR_RESOURCES) &&
                 (err_code != NRF_ERROR_NOT_FOUND))
             {
                 APP_ERROR_CHECK(err_code);
             }
         } while (err_code == NRF_ERROR_RESOURCES);
      }
      #ifdef DEBUG_BLE_SEND_DEBUG 
      printf("G3 \r\n");nrf_delay_ms(1);
      #endif
    }
    
    void in_pin_handler(void)
    {
        //nrf_drv_gpiote_out_toggle(PIN_OUT);
        printf("INTC\n");nrf_delay_ms(1);
        uint8_t k=0;
        uint32_t err_code;  
        uint8_t channel;
        k=read_out_FIFO_float();
    	
        bsp_board_led_invert(BSP_BOARD_LED_2);
    	
        #ifdef DEBUG_FIFO_SIZE_INSIDE
    	 printf("P3:%d\n", k);nrf_delay_ms(1);
    	 printf("s_connected=%d\n",status_connected);nrf_delay_ms(1);
        #endif
    	
        #ifdef DEBUG_BLE_SEND_DEBUG
      	 printf("ble_tx_buffer_acc_len=%d\n",ble_tx_buffer_acc_len);nrf_delay_ms(1);
      	 printf("ble_tx_buffer_ang_len=%d\n",ble_tx_buffer_ang_len);nrf_delay_ms(1);
      	 printf("BLE_NUS_MAX_DATA_LEN=%d\n",BLE_NUS_MAX_DATA_LEN);nrf_delay_ms(1);
        #endif
    	
    	//if((status_connected==1)&&(status==9)){niklas_ble_send_handler();}
    	if((status_connected==1)&&(status==9))
            {
              
              #ifdef LONG_RANGE_HIGH_SPEED_BLE_STREAMING_SLOW
                ble_tx_buffer_acc_len=70;
                ble_tx_buffer_ang_len=70;
              #endif
              niklas_ble_send_array_handler();
    
    
              
              
              //reference https://www.jianshu.com/p/c81c576bbdf5
              /*
    		  err_code =sd_ble_gap_rssi_get(m_conn_handle,&rssi_value,&channel);
              printf("RSSI=%d\n",rssi_value);nrf_delay_ms(1);
              APP_ERROR_CHECK(err_code);
    		  */
    
            
            }
    
    }

    errors as below 

    also here is a new ticket for it

    devzone.nordicsemi.com/.../in-the-long-range-mode-streaming-data-between-the-ble_app_uart_c_central-and-ble_app_uart_peripheral

Related