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

Slow Transfer - Calling ble_nus_string_send multiple times to send a large array

Hi all,

I am using PCA10040 with nRF5_SDK_14.2.0 and using the ble_app_uart example.

Basically I have a large array of size 18750 to send out and having read on the forum, I understand that I need to split up the data into smaller chunks and call ble_nus_string_send multiple times. Most people manage to get it to work by splitting into chuck of 20 bytes.

What I have tried so far is that I can provide a 150 byte array into the ble_nus_string_send function without any problem and its receiving well on a mobile phone. I also made a few changes:

#define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */

Inside the gatt_init function, I also increase the max MUT size to 247:

err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 247);

This is what I did in the main function:

// Enter main loop.
    for (;;)
    {
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        power_manage();
			
				if(start_transfer)
				{
					start_transfer = false;
					uint16_t length = 150;
					uint8_t j = 0;
					uint16_t k = 0;
					for(j=0; j<125; j++)
					{
						do
						{	
							err_code = ble_nus_string_send(&m_nus, mybuffer+k, &length);
							if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) )
							{
								APP_ERROR_CHECK(err_code);
							}
						} while (err_code == NRF_ERROR_BUSY);
						k = k + 150;
						while(!tx_complete);
						tx_complete = false;
					}
					
				}
    }

Each call to ble_nus_string_send, I am sending out 150 bytes, and I go this in a for loop that iterates for 125 times, so essentially I will transfer all 18750 bytes. After each call to ble_nus_string send, I am checking a flag tx_complete , which is set to true when a BLE_GATTS_EVT_HVN_TX_COMPLETE event happens. 

case BLE_GATTS_EVT_HVN_TX_COMPLETE:
	tx_complete = true;
	break;

This is working well except that the transfer seems to be still fairly slow about 19-20 seconds to send everything over. Is there anything I am doing wrong? How can I make this go much more faster?

Parents
  • Few weeks ago, I posted a somewhat similar question in this thread:
    https://devzone.nordicsemi.com/f/nordic-q-a/30667/ble-uart-slow-transfer-to-android

    I was able to get that to work successfully. But that was when 49 bytes of data was coming in from a serial port at 40ms interval. And there was no lag in receiving the data.  This is about a transfer rate of 1225 bytes per seconds. Still this is actually very slow. I am hoping to achieve faster transfer rates.

    So now I have all the data 18750 bytes all in an array and I am hoping to be able to send them to the phone in 5 seconds or less. I think this is definitely possible. Its just something that I am perhaps missing. Hope someone can enlighten. Thanks!

  • I am also looking at this in a similar thread, in which there was a helpful response. I currently have a 186-byte packet every 30mSecs, which would equate to 3 seconds in your application. That is still too slow for me, as I am looking for several hundred packets per second. I'll post an update if I find a solution. One question is what is at the other end? If it is iOS or Android, both throttle BLE reception to something near your results. Try testing with a nRF52 dev kit if you have not already tried that.

    Other thread

    This is my reasoning:

    // An integral number of packets can be sent in each connection interval using "Write Command". Shortest interval
    // is 7.5mSecs, longest 4,000mSecs in steps of 1.25mSecs. Packet size is 186 bytes
    // 7.5 mSec Connection Interval:
    //  1MHz: 2,116 uSecs @ 7.50mSecs -> 3.5 so maximum of 3 packets per connection interval, 400 packets/sec
    //  2MHz: 1,260 uSecs @ 7.50mSecs -> 5.9 so maximum of 5 packets per connection interval, 666 packets/sec
    // 40.0 mSec Connection Interval (proposed size):
    //  1MHz: 2,116 uSecs @ 40mSecs -> 18.9 so maximum of 18 packets per connection interval, 450 packets/sec
    //  2MHz: 1,260 uSecs @ 40mSecs -> 31.7 so maximum of 31 packets per connection interval, 775 packets/sec
    

  • I actually have an Android phone on the other end. Do you mean that the mobile devices slow down the BLE reception? My application requires that I send the data over to an app as fast as possible so testing with a nRF52 dev kit on the receiving end wouldn't solve my problem.

    But I am pretty sure this should be possible. I have seen a demo involving a nrf52DK connected to a camera module and streaming images to a mobile phone.

Reply
  • I actually have an Android phone on the other end. Do you mean that the mobile devices slow down the BLE reception? My application requires that I send the data over to an app as fast as possible so testing with a nRF52 dev kit on the receiving end wouldn't solve my problem.

    But I am pretty sure this should be possible. I have seen a demo involving a nrf52DK connected to a camera module and streaming images to a mobile phone.

Children
No Data
Related