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
  • New updates:

    I am able to achieve must faster transfer using the following parameters:

    ********************************

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

    err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64);

    ******************************

    Knowing that the data length has been updated to 123 from the debug output, I send out the data in block of 100 bytes.

    Am I correct to say that it doesn't matter what I set for the MUT size in this line:  err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64)" , because at the end of the day, the program will negotiate with the mobile device for a larger MUT and DLE?

    How do I determine what is the optimum value for the connection intervals and also the pack size to send in ble_nus_string_send to achieve the best throughput assuming I know the final data length that has been negotiated?

  • Hi hmolesworth,

    Thanks for the information. I am still a bit of a beginner with Nordic BLE, so there is a lot of learn for me. I will may need to read up more to understand more about what happens during the actual transmission.

    I am actually still a little confused by the MUT size and data length parameters. Even if I were to set the MUT size to a max size of 247, I think this is still limited by the receiving device, in this case with my Android mobile device, the data length was negotiated to a value of 123.

    At the end of the day, I believe (but maybe i am wrong) its the MUT size, connection interval and size of the data packet to send in each call to ble_nus_string_send that will affect the final transmission rate. But how these parameters should be set/tuned still seems confusing for many. To add to the complexity, one would not be able to control what device is at the receiving end (iphone vs android phone, model etc) and the negotiated data length will always be different.

    I am actually hoping that Nordic could provide a throughput example for dev board to mobile device and guide users on what are the parameters to take note of.

  • You're quite correct that the receiving (Central) device controls the setting; the Peripheral can only make a request which is then often curtailed by the Central - Android SmartPhone in your case. I hadn't picked up on that you were using a SmartPhone. So I imagine you have not seen the Image Processing Demo Nordic kindly provided; well worth a look on Github here. It streams video to a Samsung Galaxy S8 using an MTU size of 244 bytes and BLE 4.2 compatibility (1 Mbit Phy) or BLE 5 (2 Mbit Phy).

    There is a Youtube video here, worth watching. It mentions a bit rate of 1.2 Mbits/sec with 2Mhz Phy

    The App for Android source and iOS source are at the links in GitHub

Reply
  • You're quite correct that the receiving (Central) device controls the setting; the Peripheral can only make a request which is then often curtailed by the Central - Android SmartPhone in your case. I hadn't picked up on that you were using a SmartPhone. So I imagine you have not seen the Image Processing Demo Nordic kindly provided; well worth a look on Github here. It streams video to a Samsung Galaxy S8 using an MTU size of 244 bytes and BLE 4.2 compatibility (1 Mbit Phy) or BLE 5 (2 Mbit Phy).

    There is a Youtube video here, worth watching. It mentions a bit rate of 1.2 Mbits/sec with 2Mhz Phy

    The App for Android source and iOS source are at the links in GitHub

Children
No Data
Related