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

Unable to receive notifications from peripheral after reconnect

Hello everyone,
I am using an nrf52840 development board with the NUS UART Central example from the SDKv15.3.0 packet as the code basis. I am also using the s140 softdevice. I have a custom service which is exactly the same as the ble_nuc_c service but with custom uuids which connect to our specific peripheral. All of the handles for the custom service are the same as the nus service, including the tx_cccd handle and rx handle. For our task, after we have connected to the peripheral and enabled notifications, a data string is sent from the central to our peripheral, which then responds with it's own data string. When I first begin the debug, I am able to connect to the peripheral,enable notifications, send the data string and receive a notification with the response string. The problem seems to be that I can only do this with the first connection to the peripheral.

When the peripheral disconnects and reconnects I no longer receive notifications or data from the peripheral. I believe that I am still able to enable notifications after the reconnect since the tx cccd and rx handles are re-assigned correctly. The ble_nus_c_tx_notif_enable() also returns NRF_SUCCESS and triggers a BLE_GATTC_EVT_WRITE_RSP. But when I send the data string, I don't receive a notification for the response string as expected. The only way I am able to receive notifications again is by resetting the development board and restarting the debug.

Here are my questions:
1. Is there a way to know for sure that the notifications are being enabled in the peripheral after the reconnect? I have only seen answers for the nrf52840 board acting as a server, not as a client.
2. Is there a way to get the board back to a state that mimics its state before the first connection? My original solution was to use sd_nvic_SystemReset() after the peripheral disconnected since we could exchange data with the peripheral only when we connected to it for the first time. When the peripheral disconnected, the development board would be reset and if we tried reconnecting the peripheral, it was like it was connecting for the first time. Unfortunately, this solution doesn't work on our custom central boards since the sd_nvic_SystemReset() causes our custom board to crash.
3. Is there a proper way to handle the peripheral disconnecting? I assume that the NUS UART central already handles disconnect events properly but would like to be sure. The example does trigger the on_disconnect_evt() function which contains the link_init() function that is used to reset the connection parameters. However, since it seems I can only connect once to a peripheral and any subsequent connections don't work as expected, I am wondering if I might be missing additional steps that the example wasn't focused on and therefore didn't include.

Parents
  • Hello,

    Enabling notifications is only necessary to be able to send notifications from peripheral to central, not the other way around.

    I assume that you are using the functions ble_nus_data_send() and ble_nus_c_data_send() to send data between the devices, right?

    Can you check what that call returns when the notifications doesn't show up on the other device?

Reply
  • Hello,

    Enabling notifications is only necessary to be able to send notifications from peripheral to central, not the other way around.

    I assume that you are using the functions ble_nus_data_send() and ble_nus_c_data_send() to send data between the devices, right?

    Can you check what that call returns when the notifications doesn't show up on the other device?

Children
  • Thanks for the reply!

    Yes, I am using the ble_nus_data_send() and ble_nus_c_data_send().

    I used the SEGGER_RTT_printf() function to print out the ble events that occur in my program:

    When notifications don't show up on the device I get event BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE

    and then the program waits for the next event which never comes.

    When I do get notifications on the first connection, I get the event:

    BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE

    followed by the event:

    BLE_GATTC_EVT_HVX

    which then triggers the UART print events.

    I don't know if this will help but here is the complete list of ble events that occur from the first connection and correct transfer of data until the second connection when the data transfer fails.

    I used SEGGER_RTT_printf() in the function nrf_sdh_ble_evts_poll() to print the ble events as they occur. I have listed the event id and enumeration name. I have also added notes that hopefully make the work flow clear:

    DEBUG STARTS


    BLE event: 0x1D.  BLE_GAP_EVT_ADV_REPORT              <==  Scanning
    BLE event: 0x10.   BLE_GAP_EVT_CONNECTED               <==  Peripheral is found

    BLE event: 0x24.   BLE_GAP_EVT_DATA_LENGTH_UPDATE
    BLE event: 0x3A.   BLE_GATTC_EVT_EXCHANGE_MTU_RSP


    BLE event: 0x30. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP
    BLE event: 0x32. BLE_GATTC_EVT_CHAR_DISC_RSP
    BLE event: 0x32. BLE_GATTC_EVT_CHAR_DISC_RSP
    BLE event: 0x33. BLE_GATTC_EVT_DESC_DISC_RSP
    BLE event: 0x30. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP   <==  NUS service discovered

    Connected to device with NUS Comm Service.                             <==  Debug message I use to indicate connection


    BLE event: 0x38. BLE_GATTC_EVT_WRITE_RSP                       <== cccd configured to enable notifications on peripheral


    BLE event: 0x1F. BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
    BLE event: 0x12. BLE_GAP_EVT_RSSI_CHANGED


    Data hex: 0x54 68 69 73 20 69 73 20 61 20 6d 65 73 73 61 67 65 20 34 75    <==  Random data string that I send
    BLE event: 0x3C. BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE           <== data is sent
    BLE event: 0x39. BLE_GATTC_EVT_HVX                                                   <== central receives a notification with reply string

    Receiving data from KN                                                                            <== Name of our peripheral
    Data hex: 0x54 68 69 73 20 69 73 20 61 20 72 65 70 6c 79 20 34 75     <== Reply string of random data

    BLE event: 0x11. BLE_GAP_EVT_DISCONNECTED                             <== Peripheral disconnects


    BLE event: 0x1D. BLE_GAP_EVT_ADV_REPORT      <==  Scanning
    BLE event: 0x10. BLE_GAP_EVT_CONNECTED        <== Peripheral is found again and connects for the second time

    BLE event: 0x11. BLE_GAP_EVT_DISCONNECTED  <== Peripheral disconnects (this doesn't always happen)


    BLE event: 0x1D. BLE_GAP_EVT_ADV_REPORT    <==  Scanning 
    BLE event: 0x10. BLE_GAP_EVT_CONNECTED      <== Peripheral is found again connects for the third time
     
    BLE event: 0x24. BLE_GAP_EVT_DATA_LENGTH_UPDATE
    BLE event: 0x3A. BLE_GATTC_EVT_EXCHANGE_MTU_RSP


    BLE event: 0x30. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP
    BLE event: 0x32. BLE_GATTC_EVT_CHAR_DISC_RSP
    BLE event: 0x32. BLE_GATTC_EVT_CHAR_DISC_RSP
    BLE event: 0x33. BLE_GATTC_EVT_DESC_DISC_RSP
    BLE event: 0x30. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP  <==  NUS service discovered

    Connected to device with NUS Comm Service.                             <==  Debug message I use to indicate connection


    BLE event: 0x38. BLE_GATTC_EVT_WRITE_RSP                       <== cccd configured to enable notifications on peripheral 


    BLE event: 0x1F. BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
    BLE event: 0x12. BLE_GAP_EVT_RSSI_CHANGED


    Data hex: 0x54 68 69 73 20 69 73 20 61 20 6d 65 73 73 61 67 65 20 34 75   <==  Random data string that I send
    BLE event: 0x3C. BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE          <== data is sent

    This is where the events stop occurring. On subsequent events, I don't receive BLE_GATTC_EVT_HVX events which makes me believe that notifications might not actually enabled on the peripheral.

Related