This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

dealing large data packet's through ble

Hi, I need to send(using BLE) large amount of data's, which are collected by the accelerometer sensor for 1 hour. I have an external NOR flash where the accelerometer data's are stored and from there data's are transmitted to the BLE stack when sync occurs. I am using nRF51822 nordic controller. Assume that, data size will be 50KB.

Regards, Balaji

  • The easiest way to send large amounts of data is to send them sequentially as notifications.

    Add a characteristic that is 20 bytes long and has the notify property. Split your data in 20 byte chunks and call sd_ble_gatts_hvx() repeatedly until you get the BLE_ERROR_NO_TX_BUFFERS back. At that time, wait until you get a BLE_EVT_TX_COMPLETE, at which point you again can send data until you get the BLE_ERROR_NO_TX_BUFFERS. Repeat until all data has been sent.

    Edit: Following is a code snippet that shows how this could be done:

    static void heart_rate_meas_send(void)
        static uint32_t cnt = 0;
        uint32_t        err_code;
        uint16_t        heart_rate;
        while (true)
            heart_rate = (uint16_t)ble_sensorsim_measure(&m_heart_rate_sim_state, &m_heart_rate_sim_cfg);
            err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, heart_rate);
            if (err_code == BLE_ERROR_NO_TX_BUFFERS ||
                err_code == NRF_ERROR_INVALID_STATE || 
                err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING)
            else if (err_code != NRF_SUCCESS) 
            // Disable RR Interval recording every third heart rate measurement.
            // NOTE: An application will normally not do this. It is done here just for testing generation
            //       of messages without RR Interval measurements.
            m_rr_interval_enabled = ((cnt % 3) != 0);

    and then in the event handler on_ble_evt:

            case BLE_EVT_TX_COMPLETE:

    You'd also have to add a call to hear_rate_meas_send() somewhere after a connection has been established and the CCCD written, to actually start the transmission (or do something else that triggers a TX_COMPLETE).

    To maximize throughput, you'd also have to change the size of the characteristic to be 20 bytes. This is done by setting the max_len field of the ble_gatts_attr_t struct, and possibly vlen in ble_gatts_attr_md_t for the characteristic to be variable length. This is done on lines 228 and 237 in ble_hrs.c:

        attr_md.vlen       = 1;
        attr_char_value.max_len      = MAX_HRM_LEN;
  • Thank you for the Information. I have a Evaluation kit from Nordic and the sample code for HRS. I need to modify the sample code to send 20 bytes per connection interval instead of 2 bytes send by the existing code. Kindly help us how to change in the existing sensor code and view the same using the Master Control Panel.

  • I've extended my answer above somewhat to show how this can be done. Please make sure to take a look.

  • Thanks for this example. I got it working at 6580 bytes per second in a setup with a minimum connection interval of 10ms, and a timer interval of 10ms stuffing 20 bytes packets until it receives the BLE_ERROR_NO_TX_BUFFERS.

    Just what I needed :-)

  • I need to transfer100KB of data in 1 sec. Is it possible?

    How many TX Buffers available in the Softdevice stack ? Where can I get the information regarding the available TX buffers and RX Buffers.

    I want to create 4 characteristic and send all 4 characterstic at a time in a single connection Interval of 10ms. To do this, I need to know before filling the new data to characteristic that data is transmitted on the air to avoid overwriting the existing data.