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!

  • Hi Karl,

    we had different problems.

    One of them was that our controller sends data cyclically - regardless of whether there is a BLE connection or not. When we debug the BLE module, the situation arises that the BLE stack is not yet fully set up while the STM32 is already trying to send data via UART. This leads to an APP_ERROR_HANDLER.

    The disconnect event is generally recognized. However, an APP_ERROR_HANDLER was previously executed. We have to intercept this troubleshooting in a different way than has been done up to now. When we do this, it works to disconnect and reconnect the two devices.

    It may be that our queue is too small, but we currently cannot simply increase it.

    Many thanks for your support!

    Regards,

    Andi

  • Hello again Andi,

    Andi_Frueh said:
    the BLE stack is not yet fully set up while the STM32 is already trying to send data via UART. This leads to an APP_ERROR_HANDLER.

    The initialization and enabling of the BLE stack does not take very long, and the nRF52833 can still receive over UART regardless of the BLE stack status. Which error is generated, and from which function, when the STM32 sends data too soon?

    Andi_Frueh said:
    The disconnect event is generally recognized. However, an APP_ERROR_HANDLER was previously executed. We have to intercept this troubleshooting in a different way than has been done up to now. When we do this, it works to disconnect and reconnect the two devices.

    I am sorry, but I do not understand what you mean to say here fully. Are you saying that you do not see the DISCONNECTED event when a APP_ERROR_HANDLER execution has just finished? Have you implemented specific error handling in the APP_ERROR_HANDLER, or are you using the default which is to reset the device?
    Please elaborate on what you mean with this paragraph so I may better advice you on how to resolve the issue. 

    Andi_Frueh said:
    It may be that our queue is too small, but we currently cannot simply increase it.

    I do not understand what you mean by this. Why can you simply not increase the queue, if this is what is causing your NRF_ERROR_RESOURCES?
    The only alternative to increasing the queue to avoid the NRF_ERROR_RESOURCES would be to queue notifications less frequently. For example, only after receiving a BLE_GATTS_EVT_HVN_TX_COMPLETE event.

    Best regards,
    Karl

  • Hello Karl,

    sorry for the late response.

    The initialization and enabling of the BLE stack does not take very long, and the nRF52833 can still receive over UART regardless of the BLE stack status. Which error is generated, and from which function, when the STM32 sends data too soon?

    In Debug-Build I get following error message:

    In line 305 of main.c is the following function:

    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        switch (p_event->evt_type)
        {
            /**@snippet [Handling data from UART] */
            case APP_UART_DATA_READY:
                ...
                break;
    
            /**@snippet [Handling data from UART] */
            case APP_UART_COMMUNICATION_ERROR:
                index = 0;
                NRF_LOG_ERROR("Communication error occurred while handling UART.");
    
    /* line 305 */
                APP_ERROR_HANDLER(p_event->data.error_communication);
    
                break;
    
            case APP_UART_FIFO_ERROR:
                index = 0;
                NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }
    

    Whe I stopp the debugger before entering the APP_ERROR_HANDLER, the call stack changes to

    Since the error occurs while function "ble_stack_init()" is running, I suspected that the problem was in the area of initialization.

    I am sorry, but I do not understand what you mean to say here fully. Are you saying that you do not see the DISCONNECTED event when a APP_ERROR_HANDLER execution has just finished?

    If I reset the peripheral while there is a BLE connection and the cyclic heartbeat is being sent, I get the following error:

    Since we use the default APP_ERROR_HANDLER, application stopps and has to be reset! How should we handle this error?

    I do not understand what you mean by this. Why can you simply not increase the queue, if this is what is causing your NRF_ERROR_RESOURCES?

    The project we are working on is a safety application. The only message sent via BLE is a heartbeat (every 250 ms). If this heartbeat does not occur, the machine must be switched off immediately.

    If there is a corresponding error, the Central no longer sends a heartbeat and thus wants to force shutdown of the machine.

    If we handle messages in a queue, heartbeats could accumulate in the event of a disturbed transmission and lead to a delayed shutdown. That would be unacceptable!

    Kind regards,
    Andi

  • Hello Andi,

    Andi_Frueh said:
    sorry for the late response.

    No problem at all - we continue whenever you have the time, no worries.

    Andi_Frueh said:
    In line 305 of main.c is the following function:

    Exactly which APP_ERROR_CHECK is at line 305?
    Could it here be that you have unitialized the UART peripheral while not in a connection without having disabled related UART functionality in the application, or similar?

    Andi_Frueh said:
    If I reset the peripheral while there is a BLE connection and the cyclic heartbeat is being sent, I get the following error:

    Which function returned the NRF_ERROR_RESOURCES passed to the APP_ERROR_CHECK on line 119?

    Andi_Frueh said:
    Since we use the default APP_ERROR_HANDLER, application stopps and has to be reset! How should we handle this error?

    You could implement specific error handling for specific errors. The default error handling is to reset the device - no matter which error has occurred - this is not always necessary, but depends on your application. For example when the NRF_ERROR_RESOURCES is returned by the sd_ble_gatts_hvx call, that only means that the queue for notifications to send is already full. This is therefore then not a good reason to reset the application.
    In this case, a more fitting error handling would be to note which data was not successfully queued, and instead try to queue it again later, after having received a hvn tx event (notification successfully sent event). This way, you make sure not to restart the device unnecessarily, and not to loose any data that is not immediately queued, for example.

    Andi_Frueh said:

    The project we are working on is a safety application. The only message sent via BLE is a heartbeat (every 250 ms). If this heartbeat does not occur, the machine must be switched off immediately.

    If there is a corresponding error, the Central no longer sends a heartbeat and thus wants to force shutdown of the machine.

    If we handle messages in a queue, heartbeats could accumulate in the event of a disturbed transmission and lead to a delayed shutdown. That would be unacceptable!

    Thank you for elaborating on the requirements and constraints of the project - this makes it much easier for me to understand your issues and help you resolve them.

    Best regards,
    Karl

  • Hi Karl,

    Exactly which APP_ERROR_CHECK is at line 305?

    Could it here be that you have unitialized the UART peripheral while not in a connection without having disabled related UART functionality in the application, or similar?

    Since call stack shows, that the program counter has started in function ble_stack_init, uart would be already initialized:

    int main(void)
    {
        // Initialize.
        log_init();
        timer_init();
        uart_init();
        buttons_leds_init();
        db_discovery_init();
        power_management_init();
        ble_stack_init();
        gatt_init();
        nus_c_init();
        scan_init();
    
        // Start execution.
        printf("BLE UART central example started.\r\n");
        NRF_LOG_INFO("BLE UART central example started.");
        scan_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    

    Which function returned the NRF_ERROR_RESOURCES passed to the APP_ERROR_CHECK on line 119?

    in file nrf_ble_gq.c the function sd_ble_gattc_write returnesthe NRF_ERROR_RESOURCES.

    Could you handle with that informations?

    Best regards,
    Andi

Related