I'm looking for help determining the cause of an intermittent BLE throughput problem I'm having.
The Setup:
I have a cell phone (nexus 5x) running android 7.1.1 with a custom application that connecting to 3 sensors via BLE. The sensors are based on the Nordic NRF52832 and are running custom firmware. I didn’t write the Nordic firmware but I'm told its using the nrf5_SDK_v12.2 S132 sdk / soft device. The Nordic streams sensor data over the Nordic UART Service (NUS) to the phone.
The problem:
Usually I run my app, connect to the sensors, and then stream data from the sensors onto the phone. When everything works as expected I see an average data throughput of ~ 2250 Bps from each sensor (measured on the Phone). But occasionally I'll get 1 or 2 sensors (might always be 2 can't honestly remember) where the throughput is substantially reduced. When throughput is reduced I typically see 750Bps - 1500Bps from the sensors with reduced throughput but the throughput from the unaffected sensor stays the same. I've never observed the system running with full bandwidth to all 3 sensors, then all of a sudden reduce the throughput of 2 of the sensors or vice versa. It seem like once the connection is setup it's either a full or reduced speed connection. This reduction in throughput causes loss of data which prevents my application from running correctly.
Things I've Tried / Ruled Out:
- At first I thought that this was an RF issue, so I began logging RSSIs for each of the sensors on the phone side. After viewing the logs it seems not to be an RF issue. I've observed full throughput operation of the system with RSSIs as low as -90dB and reduced throughput with RSSIs as high as -40dB.
- My second though was maybe the sensors were having some sort of problem that was causing them to produce data at a reduced rate. To check this, I first I logged all the counts of bytes received from the NUS data characteristic notifications (on the phone). When the sensors bandwidth is reduced I see that characteristic change always results in 20 bytes received by the phone (MTU -3). This lead me to believe that the BLE subsystem on the sensor was not keeping up with the data produced by the sensors. I further validated this conclusion by connecting a debugger to the Nordic chip and watching a the buffer used to buffer measurements before they are sent over the ble NUS, I observed that samples were being dropped because the buffer was full.
- Additionally, I don’t think it's my app that’s causing the slowdown. I've made that I don’t linger in onCharacteristicChanged() callback. My app simply deposits the new bytes in a queue to be dealt with by another thread.
- I've requested a high priority connection for each of the sensors via a call to gatt.RequestConnectionPriority(GattConnectionPriority.High) on the phone after the gatt connection has been established in OnConnectionStateChanged().
- I've set min / max connection interval on the Nordic to 12.5ms
My Conclusion / Questions
Based on my observations it seems like there's something happening when the connection is made that causes the phone or the sensor to reduce the bandwidth of the connection. Outside of the MTU / connection interval (CI) I'm not sure what parameters could be causing such a decline in the throughput of the connections.
- Any ideas on why I'm intermittently having these throughput problem?
- I have a gut feeling that the android BLE stack is doing something I don’t want it to do but it's kind of a black box in terms of connection properties, any thought on … what that it might be changing? How I might detect it purposefully slowing down the connection?
Full disclaimer, my phone app is written in c# for Xamarin, but I don't think that shouldn't matter.
Thanks!