How does the peripherals reconnect to central board when the BLE connection lost

Hello everyone, I am developing a system with multiple peripherals to a central board. How many peripherals can keep connecting with central at one time? I made some peripherals connected to a central board but after several hours, the connection of some peripherals lost and cannot reconnect to the BLE network. How can the peripherals reconnected to the central board? I have enlarge the timeout to 20s but it doesn't work. Any help will be appreciated. 

  • Hi Jared, the peripherals in my project send data at a 20ms interval. The data should be sent to central during the connection interval. Here is the detailed code below.

    For peripherals:

    #define SAADC_SAMPLE_RATE               20                                         /**< SAADC sample rate in ms. */     
    
    // BLE connection parameter.
    #define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    
    #define APP_ADV_INTERVAL                64  //3000  //64                                  /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    
    #define APP_ADV_DURATION                18000                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
    
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             //10 /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ // VersionINote1: Purpose: change MIN_CONN_INTERVAL to 10ms and MAX_CONN_INTERVAL to 250. change the timing of the BLE transmission.
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)            //1900  /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
    #define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(20000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    16   //3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    // Initialize saadc
    void saadc_init(void)
    {
        ret_code_t err_code;
    	
        nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
        saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;
    	
        nrf_saadc_channel_config_t channel_0_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
        channel_0_config.gain = NRF_SAADC_GAIN1_4;
        channel_0_config.reference = NRF_SAADC_REFERENCE_VDD4;
    	
        nrf_saadc_channel_config_t channel_1_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
        channel_1_config.gain = NRF_SAADC_GAIN1_4;
        channel_1_config.reference = NRF_SAADC_REFERENCE_VDD4;
    	
        nrf_saadc_channel_config_t channel_2_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);
        channel_2_config.gain = NRF_SAADC_GAIN1_4;
        channel_2_config.reference = NRF_SAADC_REFERENCE_VDD4;
    	
        nrf_saadc_channel_config_t channel_3_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
        channel_3_config.gain = NRF_SAADC_GAIN1_4;
        channel_3_config.reference = NRF_SAADC_REFERENCE_VDD4;				
    	
        err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_saadc_channel_init(2, &channel_2_config);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_saadc_channel_init(3, &channel_3_config);
        APP_ERROR_CHECK(err_code);	
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);   
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    }
    
    // Transmit data in SAADC function
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
            uint16_t adc_value;
            uint8_t value[SAADC_SAMPLES_IN_BUFFER*2];
            uint16_t bytes_to_send;
         
            // set buffers
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
            err_code = ble_nus_data_send(&m_nus, d_tx_buf_1, &nus_length, m_conn_handle);       // VersionFNote1: Purpose: decrease the transfer array by 2. Remove the checking sum.
            if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_NOT_FOUND))
            {
                APP_ERROR_CHECK(err_code);
            }
        }
    }
    
    

    For central:

    //BLE Timing in sdk_config.h
    
    // <o> NRF_BLE_SCAN_SCAN_INTERVAL - Scanning interval. Determines the scan interval in units of 0.625 millisecond. 
    #ifndef NRF_BLE_SCAN_SCAN_INTERVAL
    #define NRF_BLE_SCAN_SCAN_INTERVAL 400      //160
    #endif
    
    // <o> NRF_BLE_SCAN_SCAN_DURATION - Duration of a scanning session in units of 10 ms. Range: 0x0001 - 0xFFFF (10 ms to 10.9225 ms). If set to 0x0000, the scanning continues until it is explicitly disabled. 
    #ifndef NRF_BLE_SCAN_SCAN_DURATION
    #define NRF_BLE_SCAN_SCAN_DURATION 0
    #endif
    
    // <o> NRF_BLE_SCAN_SCAN_WINDOW - Scanning window. Determines the scanning window in units of 0.625 millisecond. 
    #ifndef NRF_BLE_SCAN_SCAN_WINDOW
    #define NRF_BLE_SCAN_SCAN_WINDOW 200      // 80
    #endif
    
    // <o> NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL - Determines minimum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 7.5       //7.5
    #endif
    
    // <o> NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL - Determines maximum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 180      //30
    #endif
    
    // <o> NRF_BLE_SCAN_SLAVE_LATENCY - Determines the slave latency in counts of connection events. 
    #ifndef NRF_BLE_SCAN_SLAVE_LATENCY
    #define NRF_BLE_SCAN_SLAVE_LATENCY 0
    #endif
    
    // <o> NRF_BLE_SCAN_SUPERVISION_TIMEOUT - Determines the supervision time-out in units of 10 millisecond. 
    #ifndef NRF_BLE_SCAN_SUPERVISION_TIMEOUT
    #define NRF_BLE_SCAN_SUPERVISION_TIMEOUT 4000
    #endif
    
    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        switch (p_event->evt_type)
        {
            /**@snippet [Handling data from UART] */
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
                /*
                if ((data_array[index - 1] == '\n') ||
                    (data_array[index - 1] == '\r') ||
                    (index >= (m_ble_nus_max_data_len)))
                */
                if (index >= (m_ble_nus_max_data_len))
                
                {
                    NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                    NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                    NRF_LOG_INFO("Ready to send data over BLE NUS");
                    for(int c = 0; c < NRF_SDH_BLE_CENTRAL_LINK_COUNT; c++)
                    {
                        do
                        {
                            ret_val = ble_nus_c_string_send(&m_ble_nus_c[c], data_array, index);
                            if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                            {
                                APP_ERROR_CHECK(ret_val);
                            }
                        } while (ret_val == NRF_ERROR_RESOURCES);
                    }
                    index = 0;
                }
                break;
    
            /**@snippet [Handling data from UART] */
            case APP_UART_COMMUNICATION_ERROR:
                NRF_LOG_ERROR("Communication error occurred while handling UART.");
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:
                NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief Function for handling characters received by the Nordic UART Service (NUS).
     *
     * @details This function takes a list of characters of length data_len and prints the characters out on UART.
     *          If @ref ECHOBACK_BLE_UART_DATA is set, the data is sent back to sender.
     */
    static void ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len)
    {
        for (uint32_t i = 0; i < packet; i++)
        {
            app_uart_put( 0xAA );
            for(uint32_t j = 0; j < 16; j++ )
            {
                app_uart_put(p_data[ i*16 + j ]);
            }
            // nrf_gpio_pin_toggle(13);
        }
    }
    

    Are the parameter of my BLE connection correct? 

    For the second question, when to reconnection to the BLE network, after the connection is timeout? Thanks.

  • Hi,

    It depends on the number of peripherals that are going to be connected to the central. Did you try the multi-link central example that I linked in a previous reply?

    laumung said:
    For the second question, when to reconnection to the BLE network, after the connection is timeout? Thanks.

    You can restart it after a disconnection event in the ble event handler

    best regards

    Jared 

Related