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

How to achieve higher throughput in Piconet using Nordic UART Service?

I have created a Piconet using nrf52840(s140). The 'Central' application was built on ble_app_uart_c example, which is now successfully connecting up to 7 peripherals. The Peripherals are also using NUS service to send data with(ble_nus_string_send) to Central.

I am generating some random data in peripherals. Data ranges are from 12kB/s to 10B/s in different peripheral device. I want to send total 15kB/s of data from 7 peripherals to Central.

My problem is- ALL the peripherals are only successfully sending data while I am sending limited amount of data. The central can receive upto 1kB/s in total, but the connection drops while I want to introduce a peripheral with a higher data rate(more than 1kB/s).The Central cannot maintain that connection in that case any longer.

I kept all the Connection Parameters same as examples. My question is- How I can achieve higher throughput in that system? Please feel free to ask additional questions. Thanks in advance.

PS: I am not sending/receiving any data via UART.

  • No, I don't want to increase throughput. Even my total requirement is only 125 kbps from seven peripherals in total.But each peripheral should have different data-rate. They are: 96 kbps, 16 kbps, 6 kbps, 4 kbps, 2 kbps, 600 bps, 400 bps(total 125 kbps). And I need very fixed amount of data to be sent.

    What I meant by 'control data-rate' that, I want very specific data-rate. Currently... the data-rate is fluctuating a lot, because it is always waiting for the queue to be free in cases of multiple connection. Specially the peripheral with highest data-rate is never stable(always fluctuating between 70-110 kbps). Since I could already send data with a lot higher-rate in single connection. I am not sure why it is not possible to queue more notification with lower rates? The problem is because I am not choosing the right connection interval? Or I should change the way I am using the function to send data?

    FYI: For sending data, I am calling this function with a delay. For and example, for sending 96 kbps( 12 bytes/s): there is a 10ms delay and data length is 120 bytes(char array).

  • I am using nrf SDK 13.0.0 and Softdevice S140 (nRF52840).

  • You need to tune the event length. Let's say you want to use a connection interval/connection length of 400 ms with all peripheral and you have an ATT MTU size of 247. Which means you can have 244 bytes of actual application data in each packet.

    Sending one packet every connection interval gives a throughput of:

    244 * 8 / 0.400 = 4880 bps

    This should be enough to cover 4 kbps, 2 kbps, 600 bps, 400 bps

    So for the connections that require these throughputs you should set the event length to 4, because 4 * 1.25ms is 5ms:

    1.25ms + ((251-27)82*(1))/1000 = 4.834ms (be aware that this is the time need to send a full packet pair, i.e. one full packet in each direction)

    See this and this for information about the calculation.

    This will use up 4 * 5ms = 20 ms of your connection length. Left with 380 ms.

    Sending two packets every connection interval gives a throughput of:

    244 * 8 * 2 / 0.400 = 9760 bps

    This should be enough to cover 6 kbps.

    So for the connection that require this throughput you should set the event length to 8, because 8 * 1.25ms is 10ms:

    Two full packet pairs will require 2 * 4.834 = 9.668 ms

    This will use up 1 * 10ms = 10 ms of your connection length. Left with 370 ms.

    Sending four packets every connection interval gives a throughput of:

    244 * 8 * 4 / 0.400 = 19520 bps

    This should be enough to cover 16 kbps.

    So for the connection that require this throughput you should set the event length to 16, because 16 * 1.25ms is 20ms:

    Two full packet pairs will require 4 * 4.834 = 19.336 ms

    This will use up 1 * 20ms = 20 ms of your connection length. Left with 350 ms.

    Sending 19 packets every connection interval gives a throughput of:

    244 * 8 * 19 / 0.400 = 92720 bps

    This should be enough to cover 92 kbps.

    So for the connection that require this throughput you should set the event length to 74, because 74 * 1.25ms is 92.5ms:

    Two full packet pairs will require 19 * 4.834 = 91.846 ms

    This will use up 1 * 92.5ms = 92.5 ms of your connection length. Left with 257.5 ms.

    As you can see less than half of the connection length was needed, so you could use a connection interval/length of 200ms. Then you would have some like: Sending one packet every connection interval gives a throughput of:

    244 * 8 / 0.200 = 9760 bps

    This should be enough to cover 6 kbps, 4 kbps, 2 kbps, 600 bps, 400 bps

    So for the connections that require these throughputs you should set the event length to 4, because 4 * 1.25ms is 5ms:

    1.25ms + ((251-27)82*(1))/1000 = 4.834ms (be aware that this is the time need to send a full packet pair, i.e. one full packet in each direction)

    This will use up 5 * 5ms = 25 ms of your connection length. Left with 175 ms.

    And so on...

    To select which event length to use on a connection you need to refer to the correct connection configuration tag.

Related