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

Error enabling connection event extension in UART example

Hi all,

I use nRF52832 with the UART peripheral example.

I try to enable connection event extension in the device and get an error.

I use SDK V15.0.0 and Softdevice V 6.0.0

I put the following code at the end of the nrf_sdh_ble_default_cfg_set function:

    ble_opt_t  opt;
    memset(&opt, 0x00, sizeof(opt));
    opt.common_opt.conn_evt_ext.enable = 1;
    ret_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
    APP_ERROR_CHECK(ret_code);

ret_code returns with 0x3001.

What am I doing wrong?

I'm am new to BLE and my knowledge is limited, specific detailed answers will be greatly appreciated.

Thank you

  • Moved the code right after ble_stack_init();

    Now the error doesn't appear, but data rate is awful.

    I have connection interval min = 15, max = 30

    Event length = 12

    sending 906 bytes every 220msec and every 4-6 packets I have a few packets missing.

    The data is sent, instead of within the interrupt, in main, using the following function:

    static void SendDataToHost(void)
    {
      static uint16_t length_to_send;
      static uint16_t current_length_to_send;
    
      uint32_t err_code;
    
      if (ring_buffer_out_point < ring_buffer_fill_point)
        length_to_send = ring_buffer_fill_point - ring_buffer_out_point;
      else if (ring_buffer_out_point > ring_buffer_fill_point)
      {
        length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
        length_to_send += (ring_buffer_fill_point - application_tx_ring_buffer);
      }
    
      do
      {
        if (f_ble_tx_complete)
        {
          if (length_to_send > m_ble_nus_max_data_len)
          {
            current_length_to_send = m_ble_nus_max_data_len;
    
            if ((current_length_to_send + ring_buffer_out_point) > kEND_OF_TX_RING_BUFFER_LOCATION)
              current_length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
    
            f_ble_tx_complete = 0;
            err_code = ble_nus_data_send(&m_nus, ring_buffer_out_point, &current_length_to_send, m_conn_handle);
    
            if (err_code != NRF_SUCCESS)
              f_ble_tx_complete = 1;
            else
            {
              ring_buffer_out_point += current_length_to_send;
              if (ring_buffer_out_point >= kEND_OF_TX_RING_BUFFER_LOCATION)
                ring_buffer_out_point = application_tx_ring_buffer;
              length_to_send -= current_length_to_send;
              current_length_to_send = 0;
            }
          }
          else if (length_to_send)
          {
            if ((length_to_send + ring_buffer_out_point) > kEND_OF_TX_RING_BUFFER_LOCATION)
              current_length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
            else
              current_length_to_send = length_to_send;
    
            f_ble_tx_complete = 0;
            err_code = ble_nus_data_send(&m_nus, ring_buffer_out_point, &current_length_to_send, m_conn_handle);
            if (err_code != NRF_SUCCESS)
              f_ble_tx_complete = 1;
            else
            {
              ring_buffer_out_point += current_length_to_send;
              if (ring_buffer_out_point >= kEND_OF_TX_RING_BUFFER_LOCATION)
                ring_buffer_out_point = application_tx_ring_buffer;
              length_to_send -= current_length_to_send;
              current_length_to_send = 0;
            }
          }
        }
      } while(length_to_send);
    
      length_to_send = 0;
      current_length_to_send = 0;
    
      (void)err_code;
    }

    The ring buffer is of 4KB.

    f_ble_tx_complete is set in BLE_GATTS_EVT_HVN_TX_COMPLETE event.

  • Hi, 

    The option API must be called after sd_ble_enable(). This is probably why you got 0x3001 error ( corresponds to BLE_ERROR_NOT_ENABLED) . As for the data rate, are you using a central device that supports Data length extension (nRF52 dev kit or a newer ios/android device)? I did a quick test with the ble_app_uart example and an iphone 7 and got ~9.8 kB/s throughput @ 30 ms , 244 byte data length, NRF_SDH_BLE_GAP_EVENT_LENGTH = 6. 

     

  • My Central device can either be iOS (iPhone 6/7 was tested), Android (tested with HTC that has Android 4, and Honor 9 which has Android 8), or Nordic nRF52832 (PCA10040 board).

    I managed to get good results with connection interval min=max=15 msec, and NRF_SDH_BLE_GAP_EVENT_LENGTH = 6. I don't like this option as it has no negotiation for connection interval, and I don't want to be limited in case the Central will not support this interval. In addition this interval is not optimized for power consumption in the case where I send small amounts of data (45 bytes once a second).

    My understanding of BLE is limited, I don't understand how your configuration can work. 244 byte data length means you can send 6x244 bytes every 30 msec?

    I have BLE_GATT_ATT_MTU_DEFAULT = 23, and I saw that I also got 244 byte data length in my configuration, but I don't think it will always be the case, no? if BLE_GATT_ATT_MTU_DEFAULT = 23 the data length can actually be 23, no? In which case, using your configuration, you can achieve only 6x20 per 30 msec, that is about 808 bytes every 220 msec (short of my requirements of 906 bytes).

    I tried BLE_GATT_ATT_MTU_DEFAULT = 247, but it caused problems and didn't always work.

    When I tried connection interval min = 15 & max = 30, NRF_SDH_BLE_GAP_EVENT_LENGTH = 12 & BLE_GATT_ATT_MTU_DEFAULT = 23, I also got 244 byte data length but had missed/uncompleted packets.

    I tried even:

    1. connection interval min = 200 & max = 400, NRF_SDH_BLE_GAP_EVENT_LENGTH = 160 & BLE_GATT_ATT_MTU_DEFAULT = 23

    2. connection interval min = 100 & max = 200, NRF_SDH_BLE_GAP_EVENT_LENGTH = 80 & BLE_GATT_ATT_MTU_DEFAULT = 23

    Most of the data was missed.

    Do I need to set the option API in the [Nordic] Central as well? What about Android Central?

  • Transfer speed is typically limited by the phone and it will not be possible to guarantee the 906 byte requirement for all phones unfortunately. Is this a hard requirement?  I think most, if not all phones support a connection interval of 30 ms, but the number of packets per connection event can be less than 6 (w standard 27 byte link layer packet). See attached pdf  section 4.5 for a comparison between a selection of phones that we have tested internally. 

    BLE_on_Android_v1.0.1.pdf

    "244 byte data length means you can send 6x244 bytes every 30 msec?"  Yes, this means the radio will send 244 byte packets except the number of packets per event depends on the event length and connection interval. See "Bluetooth Low energy data throughput" in the softdevice specification for max. transfer speed achievable with the softdevice: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.sds/dita/softdevices/s130/ble_data_throughput/ble_data_throughput.html?cp=2_3_1_0_16. Note that support for data length extension, long MTU, and 2M mode is not available on "most" phones, but you can test these features with iphone 7 or newer. 

    You can use the connection parameter negation module to renegotiate connection interval (doc) as needed (power consumption vs transfer speed). 

     

     

  • Yes this is a hard requirement, only with Android and Nordic Central (as in PCA10040).
    When the data length is 244, m_ble_nus_max_data_len = 244 (or 241 not sure), since in gatt_evt_handler we have:

        m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;

    The transmit code sends packets up to m_ble_nus_max_data_len per transmission, but my understanding is that notification (via ble_nus_data_send) can send only 20 bytes at a time, can this be part of the problem?

    As I said, it worked for me with connection interval min=max=15 msec, and with the same phone/Nordic central, it didn't work using the following configurations:

    1. connection interval min = 200 & max = 400, NRF_SDH_BLE_GAP_EVENT_LENGTH = 160 & BLE_GATT_ATT_MTU_DEFAULT = 23

    2. connection interval min = 100 & max = 200, NRF_SDH_BLE_GAP_EVENT_LENGTH = 80 & BLE_GATT_ATT_MTU_DEFAULT = 23

    3. connection interval min = 15 & max = 30, NRF_SDH_BLE_GAP_EVENT_LENGTH = 12 & BLE_GATT_ATT_MTU_DEFAULT = 23

    4. connection interval min = 15 & max = 30, NRF_SDH_BLE_GAP_EVENT_LENGTH = 6 (without event extension) & BLE_GATT_ATT_MTU_DEFAULT = 23

Related