I have been playing with one of Nordic’s nRF52 development boards to try and see how much data I can transmit using BLE to a smartphone. While continuous data transmission is not the ideal use case scenario for BLE (which is designed for intermittent usage), there are applications that do require high data rates at times. This is also evident from a very high number of questions posted on BLE forums about the maximum data rate achievable by a peripheral device.
It should be noted that the maximum data rates over such links between a peripheral and central (smartphone) is dependant on the peripheral chip itself i.e. the ones from Texas Instruments and Nordic may have their own limitations as well as smartphones where iOS supports 6 data packets per connection interval while Android seems to support 4 in most cases. Further, the connection interval between events is also variable with iOS supporting 30ms by default. All in all, there are a lot of possible factors that need to be taken care of during the final design of any product using BLE.
I started off by creating a custom service consisting of single data characteristic of size 20 bytes. This is because the MTU size is limited to be 20 so that’s the maximum data payload that can be transmitted in one packet after all the headers and other stuff are taken care of. I was using nRF52 SDK version 0.9.2 and SoftDevice S132. I kept transmitting (send notification) after every BLE_EVT_TX_COMPLETE event so as to have continuous data transmission. On the receiver side, I used an iPhone 6 running iOS 9 and noticed two packets being received in each connection interval. Browsing through the help forums I figured out that S132 v1 can send two packets per interval only. This meant a maximum data rate of 10.67 kbps (on an iPhone with 30ms interval).
The newer SoftDevice S132 v2 (with nRF5 SDK v11.0.0) supports 6 packets per interval and results in a data rate of 32kbps. If the connection interval can be reduced the data rate can be even higher. I have posted a working example using this version on GitHub which demonstrates how to set up a custom service for such continuous transmission. Things change quite quickly with each new release so its best to have a look at the docs in detail. Also, the Nordic developer forum is full of useful information and is also the source from where I found answers to most of the issues I was having with my work.