2025-02-12 11:03 PM - last edited on 2025-02-13 12:53 AM by Andrew Neil
while(dataRemain > 0){
Custom_STM_App_Update_Char( CUSTOM_STM_SENSORREAD, &audioSend[dataIndex] ); // each time send 48*2 = 148 bytes
dataIndex = dataIndex + CHUNK_SIZE;
dataRemain = dataRemain - CHUNK_SIZE;
}
2025-02-21 08:47 AM
I have some recent experience trying to get higher speed data transmissions using BLE, and I can share what I have learned. I confess I have not achieved anything like the maximum rate I thought (and continue to think) should be possible with BLE.
The best I got to was about 14 Kbytes per second. running in both directions concurrently, from client to server and back, in an echo testing framework. I need to revisit this later to boost it by a factor of at least 5 to 10, raising it to at least 100 Kbytes per second. I believe that should be possible, but so far I have not figured out how to do it.
Even to get to 14 Kbytes per second, I found it necessary to turn off message by message acknowledgement. There is a difference between NOTIFCATIONS, and INDICATIONS. A notification has no acknowledgement. An indication has an acknowledgement.
The problem with using message by message acknowledgements (ie- using INDICATIONS) is you only get to exchange one message every connection interval between the client and server (the BLE endpoints). If the connection interval is 100 ms, this means you send the data in one connection interval, and I think you get the acknowledgment in the next, and that has used 200 ms. You can repeat that about 5 times a second, thus 5 exchanges of your message (which apparently is 148 bytes), resulting in a pretty low data throughput rate.
You can improve things by shortening the connection interval (setting it to its minimum value of 6 results in a connection interval of 6 * 1.25 ms, which is 7.5 ms), at the expense of increased power usage. But you rapidly find there is fundamental round trip latency that limits your throughput. One solution is to switch to using NOTIFICATIONS (meaning no acknowledgement) on a message by message basis. This allows multiple messages to be in flight at the same time. Note I observe there was sufficient buffering in the windows bleak stack, to STM32 coprocessor, and back to a windows bleak stack to hold about 10 messages. I found keeping a count of messages in flight and limiting that to about 5 seemed to work pretty well to avoid dropped messages. But congestion can happen, in the RF space, or in the software real time load of the coprocessor, so messages can and do get dropped. For reliability you then need to have a higher level mechanism to ensure you have not lost messages, and perhaps resend an entire block of messages or one missing message if one gets dropped. At the very least it is useful to let the receiver detect that a message was lost.
Using this approach I was able to get up to about 14 Kbytes per second of throughput.
If anyone reading this knows the recipe to get up to 1 Megabit per second or 1.5 Megabits per second of throughput, please share it with me, because for now I cannot quite see how to do it.
2025-02-22 06:37 AM
Hi,
Thank you so much for sharing your experience, it's very helpful, and I will try and let you know the update :)