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

Disconnection within short range

Hello ,

I am working on a project in which two devices(one is central and other is peripheral ) uses Nordic bluetooth controller  for connection and data exchange. nrf51822 for peripheral and nrf51422 for the central. I have random disconnection when I try to send too many messages from the remote(central) to the peripheral. 

The short range disconnection happens by pressing the buttons on the remote in a fast random manner at a distance of 20 metres from the peripheral. The issue does not  happen, when the same buttons are pressed randomly fast in a close range(5-10 m) or if the buttons are pressed not so fast at long range(> 30m).

The analysis points to the fact that, when packets/messages sent from remote to the wheel is very high, some of the packets are lost and disconnection event is triggered by the soft device.

More analysis on the short range disconnection issue is due to distance between central and peripheral, some packets are getting lost and do not get BLE_EVT_TX_COMPLETE/BLE_GATTS_EVT_HVX_TX_COMPLETE for those messages. Due to which the transmit buffers are not cleared and on sending more messages fills up the transmit buffers very fast. This would lead to NRF_ERROR_NO_TX_PACKETS.

Our code does not use APP_ERROR_CHECK(err_code) . and no soft device resets happen due to that. Below the code to send ble messages.

#define MAX_TIMEOUT_COUNT 0xFFFF

while (ble_nus_c_control_send(&m_ble_nus_c_first_client, data_array, leng) != NRF_SUCCESS)   
      {
       // repeat until sent or until timeout counter reached maximum count
       timeout_counter++;
       if(timeout_counter > MAX_TIMEOUT_COUNT)
       {
        break;
       }
      }

Could you please look at the above code that we use to send ble messages and let us know if this could cause any issues to fill up the TX buffer fast.

Kindly answer the questions below for us to help in debugging.

1, In above scenario, is it possible to tell the BLE layer to clear the transmit buffers irrespective the sent message was successful or not. Which method to use, BLE_GATT_HVX_NOTIFICATION or BLE_GATT_HVX_INDICATION ?

2, Can you please suggest optimistic connection parameters (too short connection supervision timeout relative to the connection interval) so that only a few packet drops will lead to disconnect. In our case, we will have frequent out of range scenarios and expect to reconnect back quickly. when in range.

#define MIN_CONNECTION_INTERVAL     MSEC_TO_UNITS(7.5, UNIT_1_25_MS)    /**< Determines minimum connection interval in millisecond. */

#define MAX_CONNECTION_INTERVAL     MSEC_TO_UNITS(30, UNIT_1_25_MS)     /**< Determines maximum connection interval in millisecond. */
#define SLAVE_LATENCY               0                                   /**< Determines slave latency in counts of connection events. */
#define SUPERVISION_TIMEOUT         MSEC_TO_UNITS(1000, UNIT_10_MS)     /**< Determines supervision time-out in units of 10 millisecond. */

3, Please advise if the LF_CLK_SRC values are opptimal.

#define NRF_CLOCK_LFCLKSRC      {.source        = NRF_CLOCK_LF_SRC_RC,            \

                                 .rc_ctiv       = 16,                                \
                                 .rc_temp_ctiv  = 2,                                \
                                 .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM}

Adding the previous queries what was posted in previous mail.

1, Is it possible to increase the transmit/receive FIFO/buffer size or number of TX/RX buffer ?

2, Can we use any function to clear the TX/RX FIFO/buffer ? If yes can you please let us know what function could do this ?

Kind Regards,

Thomas

  • Hi,

    What is the functionality of the buttons? What happens in the code when you press the buttons?

    How is the button locations in relation to the 32 MHz crystal and antenna?

    What is the value of MAX_TIMEOUT_COUNT?

    What SDK version are you using? 12.3?

    1, In above scenario, is it possible to tell the BLE layer to clear the transmit buffers irrespective the sent message was successful or not. Which method to use, BLE_GATT_HVX_NOTIFICATION or BLE_GATT_HVX_INDICATION ?

    No, you cannot remove packets from the internal SD queue. If for some reason the SoftDeice was not able to send the packets that was queued, the BLE link will be disconnected. The NUS service uses notification.

    2, Can you please suggest optimistic connection parameters (too short connection supervision timeout relative to the connection interval) so that only a few packet drops will lead to disconnect. In our case, we will have frequent out of range scenarios and expect to reconnect back quickly. when in range.

    You are using 1 sec now. How is that working in your scenario? Have you tried experimenting with other values? 1 sec timeout for an application that goes out range frequently seems reasonable. This means that you can lose 1000ms/30ms(connection interval) ≈ 33 packets before the link is lost.

    3, Please advise if the LF_CLK_SRC values are opptimal.

    This looks correct.

    1, Is it possible to increase the transmit/receive FIFO/buffer size or number of TX/RX buffer ?

    Assuming S130, then you can set the bandwidth to low, mid/medium or high. This will give max 1, 3 or 6 packet per connection interval. By default a peripheral link will use high, and a central link medium bandwidth . See this link.

    Snippet:

    ble_opt_t ble_opt; 
    
    memset(&ble_opt, 0x00, sizeof(ble_opt));
    ble_opt.common_opt.conn_bw.conn_bw.conn_bw_tx = BLE_CONN_BW_HIGH;
    ble_opt.common_opt.conn_bw.conn_bw.conn_bw_rx = BLE_CONN_BW_HIGH;  
    ble_opt.common_opt.conn_bw.role = BLE_GAP_ROLE_CENTRAL; 
    
    err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_BW, &ble_opt);
    APP_ERROR_CHECK(err_code);

    Can we use any function to clear the TX/RX FIFO/buffer ?

    No, but the buffer is cleared when you lose the link.

  • Hi Sigurd,

    Thanks for the reply. 

    Each press of a button would send a packet/message to the peripheral.  MAX_TIMEOUT_COUNT IS 0xFFFF. Yes we use SDK version 12.3. 

    From your reply, what I understand is

    ”since the soft device was not able to send packets that was queued up, the BLE link would be disconnected. In our case the reason for not able to send packets was bad link. Is this right ?

    Or

    1, Could you suggest other possible reasons where BLE link would be disconnected when tx queue is full.

    2, Will there be disconnect if soft device is not able to execute because CPU time is used by other resources?

    3, Can a buffer overflow of tx queue cause this disconnection.

    Kind Regards,

    Thomas

  • ”since the soft device was not able to send packets that was queued up, the BLE link would be disconnected. In our case the reason for not able to send packets was bad link. Is this right ?

    This is most likely. When the disconnect happens, you will get a event called BLE_GAP_EVT_DISCONNECTED, here you can check the disconnect reason code

    Snippet:

    case BLE_GAP_EVT_DISCONNECTED:
            
                NRF_LOG_INFO("Disconnected reason: %d.",p_ble_evt->evt.gap_evt.params.disconnected.reason);

    1, Could you suggest other possible reasons where BLE link would be disconnected when tx queue is full.

    It could be any scenario where the other side of the link stops responding, such as going out of range.

    2, Will there be disconnect if soft device is not able to execute because CPU time is used by other resources?

    The SoftDevice is running at highest interrupt priority, so that would be unlikely. But if you have blocking code in your application, you won't be able to process any new SoftDevice events in the application. I therefore recommend decreasing the value of "MAX_TIMEOUT_COUNT".

    3, Can a buffer overflow of tx queue cause this disconnection.

    No.

    You should check the disconnect reason, if it happens because you went out of range, the supervision timeout will trigger and and you will get a BLE_GAP_EVT_DISCONNECTED event with reason BLE_HCI_CONNECTION_TIMEOUT(0x08).

  • Hi Sigurd,
    Thanks for your inputs.

    Summarizing the issue, tx buffers are getting full when messages are sent at high rate and it results in a disconnection event.
    1, Is it possible to tell the BLE layer to clear the transmit buffers irrespective the sent message was successful or not. Which method to use, BLE_GATT_HVX_NOTIFICATION or BLE_GATT_HVX_INDICATION ?
    2, Please suggest a way so that irrespective the ACK is received for the messages, the buffer could be cleared.
    3, Does configuring as BLE_GATT_HVX_NOTIFICATION means buffers are cleared and no ACKS are needed to clear the tx buffer.
    Request you to give answers to the above queries.
    Thanks,
    Thomas
  • tpoly said:
    Summarizing the issue, tx buffers are getting full when messages are sent at high rate and it results in a disconnection event.

    As previously mentioned, full TX buffers should not cause a disconnection. Did you check disconnect reason ?

    tpoly said:
    1, Is it possible to tell the BLE layer to clear the transmit buffers irrespective the sent message was successful or not.

     No.

    tpoly said:
    2, Please suggest a way so that irrespective the ACK is received for the messages, the buffer could be cleared.

     Buffer is first cleared when the packet is acked on the BLE link layer.

    tpoly said:
    3, Does configuring as BLE_GATT_HVX_NOTIFICATION means buffers are cleared and no ACKS are needed to clear the tx buffer.

     No. Notifications are acked on BLE link layer. Indications are also acked on the application level. See this post.

    Do you get the event BLE_GAP_EVT_DISCONNECTED ? If yes, what is the disconnect reason?

    Snippet:

    case BLE_GAP_EVT_DISCONNECTED:
    
    NRF_LOG_INFO("Disconnected reason: %d.",p_ble_evt->evt.gap_evt.params.disconnected.reason);

Related