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

nRF52 SDK 15 iOS -> low data rate

Using nRF52832 w/ SDK 15.2 as peripheral connecting to an iOS 12.2 central (iPhone XS Max).

IDE: SEGGER Embedded Studio for ARM, Release 4.10a

The max data rate I can achieve is ~1250 Bytes per second using sd_ble_gatts_hvx notifications. Once I attempt to go over this, say ~2kBytes/sec then within a few hundred packets NRF_ERROR_RESOURCES is returned ... which I buffer and retry sending after BLE_GATTS_EVT_HVN_TX_COMPLETE is returned. The retry buffer has size 10 packets. Once the buffer is full then it dumps/loses the data and keeps going til the next overflow.

I've read several Nordic forums claiming much higher data rates (~775kbits 3 years ago :) and I've followed the parameters they suggested but still hitting the wall.

Current parameters:

- Data Length Extension: 251

- Connection Event Extension: Enabled via sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &optionsConnExt);

- #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247 (iOS negotiates to 185)

- My payload size: (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3)

- Tested with following MIN_CONNECTION_INTERVAL:
   * #define MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(7.5, UNIT_1_25_MS)
   * #define MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(30, UNIT_1_25_MS)
   * #define MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(200, UNIT_1_25_MS)
   * #define MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(550, UNIT_1_25_MS)


- #define MAX_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(600, UNIT_1_25_MS)
- #define SLAVE_LATENCY 0 // Slave latency in terms of connection events.
- #define SUPERVISION_TIMEOUT (uint16_t) MSEC_TO_UNITS(4000, UNIT_10_MS) // Supervision time-out in units of 10 milliseconds.

#define NRF_SDH_BLE_GAP_EVENT_LENGTH 400

- Other values: max_rx_octets: 251, max_tx_octets: 251, max_rx_time: 1364, max_tx_time: 1364

Any suggestions on how to get close to 100kBytes/second?

Thanks

Parents Reply Children
  • Thanks for the response.

    I'd be happy with 400kbps but still hitting the 10kbps (~1250 Bytes/sec) wall. Can you help me achieve the 400kbps?

  • Just found the issue. Not sure why yet, but after removing the following lines of code in my bleStackInit function I'm able to achieve ~264kbps (~33kBytes/sec).

        // Setup memory for a max sized attribute table
        memset(&bleCfg, 0, sizeof(bleCfg));
        bleCfg.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT + 512;
        err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &bleCfg, ramStart);
        APP_ERROR_RESET(err_code);

        // Setup memory for a max number of connections
        memset(&bleCfg, 0, sizeof(bleCfg));
        bleCfg.conn_cfg.params.gap_conn_cfg.conn_count = (peripheralConnections + centralConnections);
        bleCfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
        bleCfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &bleCfg, ramStart);
        APP_ERROR_RESET(err_code);
    If anyone has insight on the 'why', please share.
  • Urghh. After further testing... commenting out the lines above is a no go since now I'm getting errors related to not enough memory for my characteristics (characteristic_add --> error 4).

    Anyone with a fix/knowledge why the above code effects throughput?

  • Ok, have the answer now (thanks to   !)

    The original issue was due to me setting:

    bleCfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;

    BLE_GAP_EVENT_LENGTH_DEFAULT is too small for Extended Data Length, therefore I was getting errors in the log when connecting but didn't notice:
    <error> nrf_ble_gatt: sd_ble_gap_data_length_update() (request) on connection 0x1 returned NRF_ERROR_RESOURCES.
    <error> nrf_ble_gatt: The requested TX/RX packet length is too long by 95/95 octets.
    <info> app: NRF_BLE_SCAN_EVT_CONNECTED
    So the fix is setting event_length to something larger, for example:
    bleCfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT * 10;

    This fixed the low data rate issue.
Related