ble_nus_c_string_send crashing is repeated faster than 500ms

Hi All, trying to find a cause of this problem, we have two devices, one is acting as peripheral and one as master.

Peripheral: (nRF52832, s132 v7.0.1) a remote wireless sensor just sitting and waiting for request to send data using NUS, and once request is received it sends data back immediately, data length is 20 bytes. 

Central: (nRF52832, s132 v7.0.1), a device that reads data from above mentioned remote sensor. Used example code from SDK16 for UART Central and modified it adding repeated timer scheduled event every 500ms to just send "ble_nus_c_string_send" command to trigger remote sensor to send data back. This repeated sensor polling only starts after receiving BLE_GAP_EVT_CONNECTED event and once BLE_GAP_EVT_DISCONNECTED happens, polling stops. 

With that 500ms delay sensor polling speed It works fine and sensor reporting data without issues, however I need to speed up polling speed from 500ms to 250ms and if I do that, once central connected to the peripheral it sends requests and receives data until I turn sensor off by removing battery, in that case central crashes and never reporting BLE_GAP_EVT_DISCONNECTED event. It just reboots after executing "ble_nus_c_string_send".

I need to implement a check if connection is live before executing another "ble_nus_c_string_send" and my idea was to do it by catching BLE_GAP_EVT_CONNECTED and BLE_GAP_EVT_DISCONNECTED events to start or stop polling. But as I mentioned above the problem is that once peripheral is turned off, central never gets to BLE_GAP_EVT_DISCONNECTED event. Monitoring BLE_GATTS_EVT_HVN_TX_COMPLETE did not help as this even does not even get triggered.

What would you suggest to find a cause of this problem?

Thank you.

  • Hi,

    Reading what you write the problem occurs when calling ble_nus_c_string_send() and the device has just disconnected or is in the process of disconnecting. It makes sense to guard against this by checking if the connection is valid before calling ble_nus_c_string_send(), but even then things might happen at just the wrong time. So, if this is the problem, what you really need is a more fine tuned error handling mechanism than just calling APP_ERROR_CHECK() with the return value from ble_nus_c_string_send().

    For a release build, the default error handler will trigger a reset, which makes sense. However, what you probably should do here is to handle some errors specifically, and only call APP_ERROR_CHECK() for errors you do not handle specifically. Something like this:

    ret_val = ble_nus_c_string_send(&m_ble_nus_c, buffer, length);
    if (ret_val == NRF_ERROR_INVALID_STATE)
    {
         // Handle NRF_ERROR_INVALID_STATE
    }
    else if (ret_val == NRF_ERROR_RESOURCES)
    {
         // Handle NRF_ERROR_RESOURCES
    }
    else
    {
         APP_ERROR_CHECK(ret_val);
    }

    This is a generic pattern that can be relevant with several API calls. Some error codes you handle in a (application) specific way, others you do not handle, and then you need to reset to recover in order to get back into a known state.

Related