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

nRF51822 BLE disconnecting when setting APP_TIMER_TICKS to small value

I'm using the nRF51822 DK + SDK10.0.0 + s110. I'm going to create a system where I do an SPI read from two sensors every 6ms. From these sensors I will get 20B each over SPI. I will send this data over BLE. Using 7.5ms connection events, I believe the BLE throughput should be sufficient (since some Android devices support 3-4 20B packets every 7.5ms). I want to test this out using the DK before developing my system.

Using the app_ble_hrs example, I modified the BATTERY_LEVEL_MEAS_INTERVAL to use 6ms (and disabled the other timers). Upon a m_battery_timer_id timeout, I call heart_rate_meas_send() which sends two 20B packets to the softdevice via sd_ble_gatts_hvx().

The Android Nexus 7 2013 is able to update to the 7.5ms connection event and data streams once notifications are enabled. However, the nRF51 eventually disconnects and goes back to advertising. If I set the timer to a slower value, the BLE connection seems to remain indefinitely. It also seems that SPI has some effect. For example, with 40B SPI reads (really just toggling the SPI lines to simulate a sensor read since I don't have the sensors hooked up) and 2 packets of psuedo-data sent every 6ms, the BLE connection gets dropped relatively quickly (say, 10 minutes). Sending the pseudo-data every 10ms causes the connection to last longer (1hr), but still eventually get dropped. Without SPI, sending the pseudo-data every 10ms the connection lasts long (>2hrs), but sending the pseudo-data every 6ms causes the disconnection to occur (relatively quickly at 10 minutes).

Since my application's datarate requires 2x 20B packets every 6ms, I also tried 4x 20B packets every 12ms, but the BLE connections still breaks. How can I resolve this BLE disconnection issue?

  • Are you handling errors returned from ble_hrs_heart_rate_measurement_send()? Maybe APP_ERROR_HANDLER() is called with an error code which causes a reset? See this question for more information.

  • Thanks for the suggestion Petter. Seems that I am getting 0x3004 (BLE_ERROR_NO_TX_BUFFERS per a Web search; does this hold true for SDK10.0.0?). Not sure why I'd be running out of buffers sending 2 packets every 6ms, especially at my home which is relatively interference free (compared to the office). Any thoughts?

  • 0x3004 is BLE_ERROR_NO_TX_BUFFERS for S110 v8.0.0. If you are able to send 3 packets in each connection interval, the connection interval is 7.5 ms, and you don't lose any packets, you shouldn't get this error (if this is the only thing you are doing on the link).

    Are you sure your connection interval is actually 7.5 ms? Do you know how many packets per connection interval your smart phone supports? Have you done a sniffer trace to see what is actually happening on air? You can use nRF Sniffer for this.

  • Hi Petter, I'm using an Asus Nexus 7 2013 which supports 7.5ms connection intervals and 3-4 packets per connection event. I confirmed with a sniffer that 3 can indeed go through when I did a simple test of "blasting data" then checking for BLE_ERROR_NO_TX_BUFFERS and waiting for BLE_EVT_TX_COMPLETE to start resending data. But now that my data will be at fixed intervals, I don't think I can wait for the stack buffers to clear out before restarting transmission. Any thoughts?

  • And you see 7.5 ms on the sniffer as well? The buffer size is fixed, so if you fill them up you will have to discard the data, or wait until there is a buffer available, and retry.

    Do you see anything interesting on the sniffer trace before you get the disconnection?

    Maybe you can do a print out of the number of packets that are put into the buffers, and the number of packets that are sent? Then we can see if the buffers are gradually filled up, or if it is a single incident that causes it. Number of packets that are actually sent you can get from the BLE_EVT_TX_COMPLETE event. See the documentation of sd_ble_tx_buffer_count_get() for more information.

Related