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

Connection Interval

Hi everyone,

I'm new to working with Bluetooth/

My problem is that the connection interval time sent by the central device does not converge with the time I see using an oscilloscope or a configured timer for 1 ms.
The principle of operation of my program is that the peripheral device sleeps for a certain time and wakes up at a specified interval. The central device at this time is trying to connect to it. Using the timer, I count the time from when the device woke up to the time of the BLE_GAP_EVT_CONNECTED event and to the time of the BLE_GAP_EVT_CONN_PARAM_UPDATE event. The time difference between these events is about 600 ms. I can not understand why such a difference in time. Maybe I did not correctly understand the meaning of the parameters MIN_CONN_INTERVAL and MAX_CONN_INTERVAL? If so, then how can you reduce the time for a full connection, so that the BLE_GAP_EVT_CONN_PARAM_UPDATE event occurs as soon as possible.

To check what the actual value is transmitted by the central device, you can make a breakpoint during the execution of the program at the time of the BLE_GAP_EVT_CONN_PARAM_UPDATE event, which I actually did.

According to the received data, the central device set the value of the maximum and minimum interval of 7.5 ms.In the peripheral device, I have the following parameters:

MIN_CONN_INTERVAL    MSEC_TO_UNITS (7.5, UNIT_1_25_MS)

MAX_CONN_INTERVAL   MSEC_TO_UNITS (30, UNIT_1_25_MS)

SLAVE_LATENCY            1

CONN_SUP_TIMEOUT   MSEC_TO_UNITS (250, UNIT_10_MS)

I also read that the connection interval can vary from 7.5 ms to 4 s, maybe this value is the connection interval for my central device?

Chip: BT840F (analog nRF52840);

SDK: nRF5_SDK_15.2.0;

Softdevice: s132_nrf52_6.1.0_softdevice;

Phone: Xiaomi Redmi 5+.

Thanks in advance for your help.

Parents
  • Hi

    If the device needs 11.25 ms to complete the connection event you should set MIN_CONN_INTERVAL = 11.25 ms so that the device doesn't try connecting at times lower than possible. This should make your application connect on the first try.

    Next, I'm still struggling to understand what this 500-800 ms delay is. Do you have any screenshot or sniffer log you can upload that might be helpful?

    Best regards,

    Simon

  • Hi

    I set MIN_CONN_INTERVAL = 11.25 ms and it did not give results. Also, the first time it hits the BLE_GAP_EVT_CONN_PARAM_UPDATE event, it shows 7.5 ms.

    As for the demonstration, the following is the event handler code:

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
      ret_code_t err_code = NRF_SUCCESS;
      
      gap_evt_1 = p_ble_evt->header.evt_id;
      
      switch (p_ble_evt->header.evt_id)
      {
      case BLE_GAP_EVT_DISCONNECTED:
        {
          NRF_LOG_INFO("Disconnected.");
          app_timer_stop(m_our_char_timer_id);
          time_conn[3] = time_conn[0] - (time_conn[1]+time_conn[2]);
          time_conn[0] = 0;
          NRF_LOG_INFO("CONNECTED = %d, CONN_PARAM_UPDATE = %d, DISCONNECTED = %d", time_conn[1], time_conn[2], time_conn[3]);
        } break;
        
      case BLE_GAP_EVT_CONNECTED:
        {
          NRF_LOG_INFO("Connected.");
          err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
          APP_ERROR_CHECK(err_code);
          
          min_int = p_ble_evt->evt.gap_evt.params.connected.conn_params.min_conn_interval;
          max_int = p_ble_evt->evt.gap_evt.params.connected.conn_params.max_conn_interval;
          NRF_LOG_INFO("Min int = %d, Max int = %d", min_int, max_int);     
          
          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);
          
          time_conn[1] = time_conn[0];
        } break;
        
      case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {  
          
          min_int_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval;
          max_int_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval;
          slave_conn_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.slave_latency;
          conn_sup_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout;
          
          NRF_LOG_INFO("Min int upd = %d, Max int upd = %d, Slave latency = %d, Conn sup time = %d", min_int_upd, max_int_upd, slave_conn_upd, conn_sup_upd);
          app_timer_start(m_our_char_timer_id, OUR_CHAR_TIMER_INTERVAL, NULL);
          if (disc_evt == 0)
          {
            NRF_LOG_INFO("start conn"); 
            time_conn[2] = time_conn[0] - time_conn[1];
          }
        } 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_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;
      }
    }

    And a screenshot from the terminal:

    1) The parameters of the minimum and maximum interval of the connection event recorded at the time of contact with the event BLE_GAP_EVT_CONNECTED.
    2) The parameters of the minimum and maximum interval of the connection event recorded at the time of contact with the event BLE_GAP_EVT_CONN_PARAM_UPDATE. Here it is clear that there were 2 hits in this event with different parameters.
    3) Here are the times in ms. The time is shown from the moment the device woke up and hit every event (BLE_GAP_EVT_CONNECTED, BLE_GAP_EVT_CONN_PARAM_UPDATE, BLE_GAP_EVT_DISCONNECTED).

    The parameters of the minimum and maximum interval, which I set:

    #define MIN_CONN_INTERVAL   MSEC_TO_UNITS(11.25, UNIT_1_25_MS)
    #define MAX_CONN_INTERVAL   MSEC_TO_UNITS(12, UNIT_1_25_MS)
    #define SLAVE_LATENCY       1
    #define CONN_SUP_TIMEOUT    MSEC_TO_UNITS(350, UNIT_10_MS)

    I also decided to check on the source code of the example, which I took as a basis. The results are similar, just a few occurrences.

    1 option:

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(500, UNIT_1_25_MS)  
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(1000, UNIT_1_25_MS)           
    #define SLAVE_LATENCY                   0                                          
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)

    2 option:

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(48.75, UNIT_1_25_MS)           
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(1000, UNIT_1_25_MS)           
    #define SLAVE_LATENCY                   0                                          
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             

Reply
  • Hi

    I set MIN_CONN_INTERVAL = 11.25 ms and it did not give results. Also, the first time it hits the BLE_GAP_EVT_CONN_PARAM_UPDATE event, it shows 7.5 ms.

    As for the demonstration, the following is the event handler code:

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
      ret_code_t err_code = NRF_SUCCESS;
      
      gap_evt_1 = p_ble_evt->header.evt_id;
      
      switch (p_ble_evt->header.evt_id)
      {
      case BLE_GAP_EVT_DISCONNECTED:
        {
          NRF_LOG_INFO("Disconnected.");
          app_timer_stop(m_our_char_timer_id);
          time_conn[3] = time_conn[0] - (time_conn[1]+time_conn[2]);
          time_conn[0] = 0;
          NRF_LOG_INFO("CONNECTED = %d, CONN_PARAM_UPDATE = %d, DISCONNECTED = %d", time_conn[1], time_conn[2], time_conn[3]);
        } break;
        
      case BLE_GAP_EVT_CONNECTED:
        {
          NRF_LOG_INFO("Connected.");
          err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
          APP_ERROR_CHECK(err_code);
          
          min_int = p_ble_evt->evt.gap_evt.params.connected.conn_params.min_conn_interval;
          max_int = p_ble_evt->evt.gap_evt.params.connected.conn_params.max_conn_interval;
          NRF_LOG_INFO("Min int = %d, Max int = %d", min_int, max_int);     
          
          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);
          
          time_conn[1] = time_conn[0];
        } break;
        
      case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {  
          
          min_int_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval;
          max_int_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval;
          slave_conn_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.slave_latency;
          conn_sup_upd = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout;
          
          NRF_LOG_INFO("Min int upd = %d, Max int upd = %d, Slave latency = %d, Conn sup time = %d", min_int_upd, max_int_upd, slave_conn_upd, conn_sup_upd);
          app_timer_start(m_our_char_timer_id, OUR_CHAR_TIMER_INTERVAL, NULL);
          if (disc_evt == 0)
          {
            NRF_LOG_INFO("start conn"); 
            time_conn[2] = time_conn[0] - time_conn[1];
          }
        } 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_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;
      }
    }

    And a screenshot from the terminal:

    1) The parameters of the minimum and maximum interval of the connection event recorded at the time of contact with the event BLE_GAP_EVT_CONNECTED.
    2) The parameters of the minimum and maximum interval of the connection event recorded at the time of contact with the event BLE_GAP_EVT_CONN_PARAM_UPDATE. Here it is clear that there were 2 hits in this event with different parameters.
    3) Here are the times in ms. The time is shown from the moment the device woke up and hit every event (BLE_GAP_EVT_CONNECTED, BLE_GAP_EVT_CONN_PARAM_UPDATE, BLE_GAP_EVT_DISCONNECTED).

    The parameters of the minimum and maximum interval, which I set:

    #define MIN_CONN_INTERVAL   MSEC_TO_UNITS(11.25, UNIT_1_25_MS)
    #define MAX_CONN_INTERVAL   MSEC_TO_UNITS(12, UNIT_1_25_MS)
    #define SLAVE_LATENCY       1
    #define CONN_SUP_TIMEOUT    MSEC_TO_UNITS(350, UNIT_10_MS)

    I also decided to check on the source code of the example, which I took as a basis. The results are similar, just a few occurrences.

    1 option:

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(500, UNIT_1_25_MS)  
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(1000, UNIT_1_25_MS)           
    #define SLAVE_LATENCY                   0                                          
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)

    2 option:

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(48.75, UNIT_1_25_MS)           
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(1000, UNIT_1_25_MS)           
    #define SLAVE_LATENCY                   0                                          
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             

Children
No Data
Related