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

central and peripheral mode connection disconnecting in nrf52840

hai ,

   in my apllication i am using nrf52840 , i merged a code code of peripheral and central (app_blinky example)

i need to connect a peripheral to central (with esp32 ), i can able to connect.

i should with connect with another nrf ( which acts as peripheral) for this ,i need to switch mode from peripheral to central .

and now question is ,

in my merged code , it should connected with esp32 and when i send a message it sholud connect with another nrf at that time it should not lose connection with esp32 .

how to connect without disconnecting from another mode ??

  • Hi.

    I suggest that you take a look at the BLE Multi-link Example.

    The BLE Multi-link Central example application shows how one central can be connected to several peripherals simultaneously.

    Br,
    Joakim

  • actually my application is  with esp32(A) , relay_NRF(B) , nrf(C)

    relay(B) - merged code (with central and peripheral)

    STEP 1 : A and B DEVICE should be always in connected mode 

    1. in this ESP32- A(acts as central ) and relay _NRF- B(in peripheral mode )

    STEP 2 :  a data should send from A TO B , then B (relay_NRF )should connect with NRF - C(peripheral) from central mode in relay(B) without disconnecting from ESP32 (A).

    Is it possible to always connect with ESP32(A) as well relay_NRF should connect with another NRF - C(which is peripheral)??

    if you have any code kindly share the code ..

    Thank you

  • Yes, it is possible to do this.

    The S140 softdevice supports up to 20 concurrent connections.
    We already have sample code for this in our nRF5 SDK. You can take a look at the Multi-link example is referred to in my last reply or the relay example.
    Relay example:
    "The application combines a collector part on one end and a sensor part on the other to show how the SoftDevice can be used to make a device simultaneously function as central and peripheral device. "

  • hello,

    i tried with ble app-blinky example merged with central and peripheral.

    at first i can able to connect with ESP32(A - acts as central) and RELAY (B - acts as peripheral role)

    then i send a message from ESP32(A) TO RELAY(B) 

    When its get the message from esp32(A) then RELAY (B - already in peripheral role now after getting message i need to switch over the role to central ) to connect with another NRF(C -acts as peripheral)

    after this message should pass to NRF(C) then when C gives a acknowledgment to RELAY(B - again switch to Peripheral mode ) to connect with ESP32(A)

    for this , every time i am disconnect the role using 

    err_code = sd_ble_gap_disconnect(m_conn_handle,
    BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION);

    but sometimes its not getting disconnecting gives me a fatal error.

    i am searching to connecting the modes without disconnecting the roles every time.

    can you please explain me how to work on this???

    int main(void)
    {
     ret_code_t err_code;
        // Initialize.
         log_init();
         leds_init();
          timers_init();
     power_management_init();
        ble_stack_init();
     
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
       conn_params_init();
     
         db_discovery_init();
         lbs_c_init();
    
        // Start execution.
        NRF_LOG_INFO("Blinky example started pheriperal.");
        advertising_start();
    
        // Enter main loop.
        for (;;)
        {
       idle_state_handle();
    
        }
    }
    

    //ble stack initiate
    
    static void ble_stack_init(void)
    {
    //printf("ble_stack_init\n");
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
    
         // Register handlers for BLE and SoC events.
         NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
        NRF_SDH_BLE_OBSERVER(m_ble_observer_re, APP_BLE_OBSERVER_PRIO, ble_evt_handler_relay, NULL);
       
    }
    
    

    event handler  for peripheral using flag to  play each role

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
          if(periperal_central_role == false)
          { 
    
            // printf("inside peripheral role----\n");
               on_ble_peripheral_evt(p_ble_evt);
    
           }
    
          else if(periperal_central_role == true)
           {
            // printf("inside Central role----\n");
               on_ble_central_evt(p_ble_evt);
    
           }
           
    
    

    at first it should go to on_ble_peripheral_evt() to connect with esp32

     void on_ble_peripheral_evt(ble_evt_t const * p_ble_evt)
    {
        ret_code_t err_code;
      //  printf("peripheral event handler\n");
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
               NRF_LOG_INFO("Connected with peripheral--------");
               scan_start();
              
          //   NRF_LOG_INFO("BLE peroi %d", p_gap_evt->params.connected.role);  
               // bsp_board_led_on(CONNECTED_LED);
               // bsp_board_led_off(ADVERTISING_LED);
                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);
                 data_ret_fun();
                err_code = app_button_enable();
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected peri-------");
                bsp_board_led_off(CONNECTED_LED);
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                err_code = app_button_disable();
                APP_ERROR_CHECK(err_code);
                advertising_start();
                break;
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // 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_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                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_GATTS_EVT_SYS_ATTR_MISSING:
                // 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.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                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:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                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:
             
      
                // No implementation needed.
                break;
        }
    }
    

    once connect getting message from esp32 and then switch over to central role to connect with another device - NRF(C - acts as peripheral) here i have shown how i disconnected and connecting to device (c)  , i tried without disconnecting from peripheral role used  ble_gap_connect fun to connect with device (c) but its not worked , when disconnect using ble_gap_disconnect.

    after i scan_init AND on_ble_central_evt - its connected with DEVICE NRF(C)

    static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t *data_ptr,ble_evt_t const * p_ble_evt)
    {
                chk_flag = true;
       
               ret_code_t err_code;
    
              printf("DATA:%s\n",data_ptr);
    
                  process_msg(data_ptr) ;     
    
     if(periperal_central_role == false && chk_flag == true) 
     {
      periperal_central_role = true;
             printf("inside fun call of central\n");
    /* err_code = sd_ble_gap_connect(p_addr,
                                      p_scan_params,
                                      p_conn_params,
                                      con_cfg_tag); */
    
    
             ret_code_t err_code;
              err_code = sd_ble_gap_disconnect(m_conn_handle,
                                                BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    
     if(err_code  ==  NRF_SUCCESS)
      {
     printf("sucess\n");
    
    
     scan_init();  
      
     on_ble_central_evt(p_ble_evt);
    
     }
    i am geting a mac id of devcie(C) from the message got from esp32 , then with the mac id i have to connect with device (C), for this connection i used the below fun

     void scan_init(void)
    {
        ret_code_t          err_code;
        nrf_ble_scan_init_t init_scan;
    
        memset(&init_scan, 0, sizeof(init_scan));
    if(periperal_central_role == true)
    {
    printf("inside central scan\n");
        init_scan.connect_if_match = true;
        init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
    
    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler_central);
        APP_ERROR_CHECK(err_code);
       
    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, m_addr);
        APP_ERROR_CHECK(err_code);
             if(err_code == NRF_SUCCESS)
        {
         printf("nrf_ble_scan_filter_set\n");
        }
        else
        {
         printf("nrf_ble_scan_filter_notttttt ok-----\n");
        }  
    
         err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
        APP_ERROR_CHECK(err_code);
          if(err_code == NRF_SUCCESS)
        {
         printf("nrf_ble_scan_filters_enable\n");
        }
        else
        {
         printf("nrf_ble_scan_not ok-----\n");
        }
    }
    else if(periperal_central_role == false)
    {
     printf("inside periperal scan\n");
          init_scan.connect_if_match = false;
        init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
        init_scan.p_scan_param     = &m_scan_param;
        err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler_peri);
        APP_ERROR_CHECK(err_code);
    
    }
       
    }
    

    when getting the ack from DEVICE (C) I switching over the role to peripheral in RELAY(B)

    void central_msg_handler(void * p_context)
    {
    ret_code_t err_code;
    printf("handle -------centrl---\n");
    err_code = ble_lbs_led_status_send(&m_ble_lbs_c, button_action);
    if (err_code != NRF_SUCCESS &&
    err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
    err_code != NRF_ERROR_INVALID_STATE)
    {

    sprintf(collect_data, "{\"MSTS\":\"%s\",\"MAC\":\"%02X%02X%02X%02X%02X%02X\"}","0", m_addr_c[0], m_addr_c[1],
    m_addr_c[2], m_addr_c[3],
    m_addr_c[4], m_addr_c[5]);
    coaster_msg_suc = true ;
    APP_ERROR_CHECK(err_code);
    printf("data ret %s\n",collect_data);
    }
    if (err_code == NRF_SUCCESS)
    {
    coaster_msg_suc = true ;
    sprintf(collect_data, "{\"MSTS\":\"%s\",\"MAC\":\"%02X%02X%02X%02X%02X%02X\"}","1", m_addr_c[0], m_addr_c[1],
    m_addr_c[2], m_addr_c[3],
    m_addr_c[4], m_addr_c[5]);
    printf("data ret %s\n",collect_data);
    printf("sucess return------------\n");

    }
    mode_chnage_peripheral();
    }

    void mode_chnage_peripheral()
    {


    ret_code_t err_code;
    err_code = sd_ble_gap_disconnect(m_conn_handle,
    BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION);err_code = sd_ble_gap_adv_stop(m_adv_handle);

    }

  • after this starting advertising_start();

    function to reconnect with esp32.

    for me sometimes again connecting with esp32 but most times it is not disconnecting from DEVICE(C) and to reconnect with esp32 ..

    whats the mistake here ...could u explain??

Related