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

Parents
  • 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);
    
            cnt++;
            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)
            {
                break;
            }
            else if (err_code != NRF_SUCCESS) 
            {
                APP_ERROR_HANDLER(err_code);
            }
        
            // 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:
                heart_rate_meas_send();
                break;
    
    

    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;
    
    
  • Hi Ole,

    Thanks again for this excellent tutorial and example code. I tried it, and it greatly improved the achievable bandwidth.

    One problem I had was using this code was that I was missing every 7th packet. It seems that the while(1) above allows you an attempt to send 7 packets each connection interval, and the last one always fails. I got around this problem by checking to make sure I only attempt to send 6 packets (also using BLE_ERROR_NO_TX_BUFFERS to break me out of the loop), and my missing every 7th packet disappears.

    However, I still do miss the occasional packet, which I don't believe should happen given that notifications are still acked on the lower BLE layers (perhaps link layer?).

    What could I be doing wrong to be losing packets here?

    Thanks! Jamie

Reply
  • Hi Ole,

    Thanks again for this excellent tutorial and example code. I tried it, and it greatly improved the achievable bandwidth.

    One problem I had was using this code was that I was missing every 7th packet. It seems that the while(1) above allows you an attempt to send 7 packets each connection interval, and the last one always fails. I got around this problem by checking to make sure I only attempt to send 6 packets (also using BLE_ERROR_NO_TX_BUFFERS to break me out of the loop), and my missing every 7th packet disappears.

    However, I still do miss the occasional packet, which I don't believe should happen given that notifications are still acked on the lower BLE layers (perhaps link layer?).

    What could I be doing wrong to be losing packets here?

    Thanks! Jamie

Children
No Data
Related