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

Connection timeout at central

Hi,

I'm using the example "ble_central/ble_app_uart_c" of nRF5_SDK_17.0.2. Connection to peripheral workes fine.

If the central re-starts while a connection is established, the peripheral get a "disconnect" event and wait for a new connection.

If the peripheral re-starts while a connection is established, the central get no "disconnect" event and runs into fatal error.

So, how to set up central, to handle a "disconnect" by timeout?

Thanks for helping!

  • Hello again, Andi

    Andi_Frueh said:
    In Debug-Build I get following error message:

    Thank you for clarifying.

    There is a issue with the logging of the UART communication error in the default error handler. It assumes that the error code is a standard nRF error code, but in fact the error code you get in case of a APP_UART_COMMUNICATION_ERROR is the content of the ERRORSRC register. So value 1 is not NRF_ERROR_SVC_HANDLER_MISSING, but rather an overrun error (1, i.e. the least significant bit is the OVERRUN field in ERRORSRC: "A start bit is received while the previous data still lies in RXD").

    It would seem that for some reason you are not able to process the data fast enough in some cases. Perhaps you get a interrupt at a "bad time", or something else. The best way to handle this is probably to use flow control if possible.

    Andi_Frueh said:

    in file nrf_ble_gq.c the function sd_ble_gattc_write returnesthe NRF_ERROR_RESOURCES.

    Could you handle with that informations?

    You can check returned error messages against the function API to read why this particular error message was returned.
    In the case of sd_ble_gattc_write, the description for the NRF_ERROR_RESOURCES reads:

    NRF_ERROR_RESOURCES Too many writes without responses queued. Wait for a BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.

    It seems to me that you are queueing the writes faster than they are being written, leading to an overflow of the queued writes buffer.
    Please read the note section of the function's API to see how you may use the CMD_TX_COMPLETE event to queue more write without responses.
    How fast are you queueing writes, compared to how fast they are being sent? What connection interval are you using?

    Best regards,
    Karl

  • Hello again,

    APP_UART_COMMUNICATION_ERROR

    When this error occurs, I see in call stack, that the initialization of application code isn't finished. The application code is still handling the function ble_stack_init(). While executing this function, nrf_sdh_enable_request() will be called, where a critical section ist entered and exited. While exit this critical section, the UARTE0_UART0_IRQHandler() is called immideatelly, which ends in the APP_UART_COMMUNICATION_ERROR.

    Even if the dedicated STM32 sends its 250ms heartbeat via UART while the Nordic chip is starting its firmware (start debug session): how can it be that an overflow occurs immediately at this point every time? How can I prevent this overflow?

    It seems to me that you are queueing the writes faster than they are being written, leading to an overflow of the queued writes buffer.
    Thisis quite possible. The Central needs approx. 4 seconds until it detects that the connection to the Peripheral has been broken. During this time the heartbeat continues to be sent every 250ms.
    Is it possible that the interplay between the
    • heartbeat cycle (250ms),
    • the duration for detecting the disconnection (approx. 4 Sec.) and
    • the size of the message queue (?)

    has been selected as "unfavorable"? Can I adjust disconnection time?

  • Hi Karl,

    we tried something to find out the interacting of

    • heartbeat cycle
    • disconnection time and
    • queue size.
    We found the place where the dosconnection time can be set. If we reduce this time (from 4000ms to 1000ms), a disconnection will be recognized before the queue overflows.
    Unfortunately we have not found the place where to adjust the size of the queue. Can this also be found in the sdk_config?
  • Hello again,

    the other issue with the APP_UART_COMMUNICATION_ERROR while initialization seems also to be fixed (by a workaround): We have changed the order of the initialization sequence and have moved uart_init() behind the ble_stack_init().

    While doing so, we have no APP_UART_COMMUNICATION_ERROR  anymore.

    While initialization the uart interrupts are already enabled, although the BLE stack has not yet been initialized. This obviously leads to this error.

    What better solution here than just changing the initialization order?

  • Hello again Andi,

    Thank you for your patience.

    Andi_Frueh said:
    We found the place where the dosconnection time can be set. If we reduce this time (from 4000ms to 1000ms), a disconnection will be recognized before the queue overflows.

    Yes, the connection timeout can be adjusted to fit the specific application. 
    You should also consider the environment that the device will be working in when configuring this, because packet loss or corruption happens more frequently in a 2.4 GHz noisy environment, or in an environment in which the peripheral and central moves behind obstacles and further away from each other. What connection interval are you using currently?
    The connection interval is what determines how often there is scheduled communication between the two devices, so for example if you need your central to stop a machine as fast as possible if a heartbeat is not received you can likely set the connection timeout even lower if you are using a low connection interval, such as 7.5 ms.

    Andi_Frueh said:
    Unfortunately we have not found the place where to adjust the size of the queue. Can this also be found in the sdk_config?

    The size of the queue, are you here talking about the UARTE RX buffer, or the hvn_tx_queue_size?

    Andi_Frueh said:
    What better solution here than just changing the initialization order?

    Is it a possibility for you to use flow control?
    This should negate this issue all together.
    Alternatively, perhaps your STM could wait until it receives some kind of go-ahead signal before it starts sending the heartbeats. This could for example be a start command sent over UART, or similar.

    Best regards,
    Karl

Related