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

S130 Ble throughput optimization

Hello

I am developing an application where the data troughput is very important. As i understand, the data thoughput is dependent on the connection interval and the number of packets sent at every connection interval.

I am only able to get one packet sent at every connection interval. This means that throughput is not optimal as i must wait an entire connection interval before i can send the next packet. ( totaltime = scaninterval * packets )

My application is build on the SDK11.0.0 with SoftDevice 130, it supports 1 Central Link and 1 Peripheral Link.

Connection interval is set to min 15 max 20. (Slave Latency 0 and supervision timeout : 4s)

When acting as a central and sending 100bytes(100/20 = 5 packets) to peripheral i am doing it this way:

write_params.write_op = BLE_GATT_OP_WRITE_CMD;
write_params.offset = 0;
write_params.len = length;
write_params.p_value = buffer;

uint32_t errorCode = sd_ble_gattc_write(connectionHandle, &write_params);

Looping untill the errorcode is == BLE_ERROR_NO_TX_PACKETS

It works just fine, but when i snif the connection it looks like this:

image description

As you can see every packet is sent in each connection interval. Which means that sending 100 bytes takes approx 67ms.

In my demo application the 100 bytes is sent back to the central when the entire buffer is received. When the peripheral is responding using the Notification Handle value i am doing pretty much the same:

hvx_params.p_data = buffer;
hvx_params.p_len = &length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;

uint32_t errorCode = sd_ble_gatts_hvx(connectionHandle, &hvx_params);

Looping until errorCode == BLE_ERROR_NO_TX_PACKETS.

This gives a simular result on the snif output :

image description

Meaning that it takes approx 70ms to deliver 100bytes.

When using an Android Device (LG Nexus 5, with 6.0.1) as central it is running even slower. (But it seems lie the android device is using a bigger connection interval)

image description

When i look into this punchthrough.com/.../maximizing-ble-throughput-on-ios-and-android

It seems that Android devices should be able to send 4-6 packet pr connection interval. Giving an thoughput of up to 16Kbytes / second. However my thoughput is approx (100 bytes takes 67ms. (1000ms/67ms)*100bytes) = 1400KB/s

So i guess my questions are:

  1. Can i do anything to speed things up on the peripheral, and how?

  2. Can i do anything to speed things up on the central, and how?

  3. Can i do anything to speed things up on the android central, and how?

  4. What kind of thoughput can i expect?

Additional info:

During development and testing this application i am using the PCA10028 Dev Board(N51422 QFACA1), but the final result is supposed to run on a N51822 QFACA1 chip.

The peripheral in the example is Nordics PCA10000 dongle(N51822QFAAG0) Using SDK9.0.0 with SoftDevice 110. However when using the PCA10028 as peripheral it is the same thing.

I have attached some snif outputs

Android to Dongle: android_to_pca1000dongle.pcapng

pca10028 to pca10000 100 bytes.pcapng

android_to_pca1000dongle.pcapng

  • I don't know which version of the softdevice you are using. but the SD130 v1.0 only allow one connection, as on the SD130 v2.0 it allows 6 or 7 changes per connection. I achieved a max throughput of 123kbps between two nrf51422, but using a interval of 7.5ms.

  • I am jusing the SoftDevice 130 2.0.0. Cool that you got such a great throughput. I just found out that my problem is actually not that my packets are not being sent in the same connection interval. I just looked at the eventcounter in the sniffer trace an can clearly see that thay are sent the way as they should. But the timestamps in my sniffer trace is pretty far from the expected amount of times used pr. packet. In the sniffer trace there are 8 to 20 ms between the packets which gives a huge amount of time for the data exchange. It seems that the sniffer trace is unreliable when looking at the time stamps.

  • So i have started looking at the android output and the console output of my application. In here are some completely different time values. But the thoughput is still not good enough. When calculating the times in the android and my application it takes 1328 ms to exchange 1024 bytes(2048 bytes transfered) This is a thoughput of approx 1.5KB/s. Android is sending 4 packets pr connection interval and the max connection interval is 30ms. This should give me a worst case thoughput of 2.6KB/s. So it seems that i am still missing 1.1KB/s :-/

  • to calculate precisely the amount of data you are sending/receiving, try to make a timer and continuously send data during one second, or more if you want, and count the number of packets you send (seeing the timestamps on the terminal is not a good idea).

  • My Android application is using the SystemClock to give "reliable" timestamps. I just found out that i have forgotten to make the peripheral make a connection parameter update request when connection is established. When i do that my expected min and max intervals are obeyed by the Android phone(obviously). I altered my test scenario to send 10x1024 bytes to my peripheral and return a packet when all packets has been received. I use the SystemClock time stamp in android to calculate my values. This setup gives me a thorughput of 2.5KB/s. Still a little short from 2.6KB expected. But when looking in the trace it seems that Android comes to a point where it stops using 4 packets / interval but rather 1 or 2. This could explain the 2.5KB/s throughput.

Related