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

Introducing FIFO buffer in uart_data_handler function..

I am working with ble_app_uart code, in that I am trying to send continuous data over BLE. But the BLE getting disconnected while sending large data.

So I planned to have an FIFO buffer which should continuously receive and stores the data(whatever the data size). Then the data should be processed and then it should be sent as frame with the length of 20 bytes. So how to introduce a new buffer and how to handle it with default app_uart_get() buffer.

Parents
  • Hi Mani

    The problem is that the example doesn't check if there are any BLE buffers available before calling app_uart_get(..).

    If the call to ble_nus_string_send(..) returns the NRF_ERROR_RESOURCES error it means that all the BLE buffers in the SoftDevice are full, and that you can not upload any more notifications until the BLE_GATTS_EVT_HVN_TX_COMPLETE event occurs.

    In this case you can set a flag in the code to say that the BLE buffers are full, so that you don't read any more data from the UART. Once the BLE_GATTS_EVT_HVN_TX_COMPLETE event occurs there is more room in the buffers, and you can start pulling UART data again.

    For this to work properly you should also use flow control on the UART. Otherwise you might lose bytes over the UART if the UART communication is quicker than the BLE link.

    Using a separate buffer in the application for UART data should not be necessary, since you already have internal buffers in the UART driver and in the SoftDevice.

    Best regards
    Torbjørn

  • The event will be propagated through the main BLE event handler, typically implemented by the following function in main.c:

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    

    If the BLE_GATTS_EVT_HVN_TX_COMPLETE case is not handled you have to add it to the switch case.

    Best regards

  • Hi ..i have the same problem . so to be ensure is it i need to paste the BLE_GATTS_EVT_HVN_TX_COMPLETE in this part ??

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
    uint32_t err_code;
    ble_nus_t * p_nus = (ble_nus_t *)p_context;
    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_CONNECTED:
    NRF_LOG_INFO("Connected");
    err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
    APP_ERROR_CHECK(err_code);
    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    ble_nus_t * p_nus = (ble_nus_t *)p_context;
    break;

    case BLE_GAP_EVT_DISCONNECTED:
    NRF_LOG_INFO("Disconnected");
    // LED indication will be changed when advertising starts.
    m_conn_handle = BLE_CONN_HANDLE_INVALID;
    break;

    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
    {
    //notify with empty data that some tx was completed.
    ble_nus_evt_t evt = {
    .type = BLE_NUS_EVT_TX_RDY,
    .p_nus = p_nus
    };
    p_nus->data_handler(&evt);
    app_uart_flush();
    break;
    }

  • Hi Saffiq

    The BLE_GATTS_EVT_HVN_TX_COMPLETE event must be handled in that function, that is correct. 

    Looking at your code I see that the BLE_GATTS_EVT_HVN_TX_COMPLETE case is already there, so you don't have to add it again. 

    What version of the  SDK are you using?
    In the later versions the BLE_GATTS_EVT_HVN_TX_COMPLETE event is handled internally by the ble_nus module itself, and you shouldn't need to do it explicitly in the application. 

    Best regards
    Torbjørn

     

  • Yes the BLE_GATTS_EVT_HVN_TX_COMPLETE was added by me ..I am using SDK 14.2 ..My project is I am trying to send my sensor data which is connected to RXD pin and send it via BLE app UART. My board is nRF52832

  • Hi Saffiq

    Any chance you can try the ble_app_uart example included in SDK v15?

    I believe this example is updated to do the buffering like you need, and would save the time needed for you to implement this yourself. 

    Best regards
    Torbjørn

Reply Children
  • Hi avrebekk, 

    I have try ble_app_uart example in the SDK v15. However the problem still the same where after i connected my sensor to the board and suddenly BLE is disconnected and i need to remove back my sensor in order for the board to advertise bluetooth again

  • Hi Saffiq

    In that case I think I will have to reproduce the problem on my end, to make it easier to debug. 

    Can you let me know what baud rate you are using, and how much data the sensor is sending? 

    Best regards
    Torbjørn

  • I have the same issue. I'm sending a Json string to the Bluetooth module over UART. I can send up to 80 characters. When i send more characters the BLE buffer crashes. Baudrate is 115200.

  • Hi guys

    I have reported the issue to the SDK team, and they are looking into a quick fix that would just require a small change to the uart_event_handle(..) function in main.c

    In the code snippet below, NRF_ERROR_BUSY is replaced with NRF_ERROR_RESOURCES, to make the application attempt to retry sending the packet when the BLE buffers are full:

    do
    {
      uint16_t length = (uint16_t)index;
      err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
      if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) &&
      (err_code != NRF_ERROR_NOT_FOUND) )
      {
        APP_ERROR_CHECK(err_code);
      }
    } while (err_code == NRF_ERROR_RESOURCES);

    Please try this out and see if it solves the issue. 

    While this method is a bit rudimentary for applications that constantly push the communication to the limits, it should work fine if you only have occasional bursts of data. 

    Best regards
    Torbjørn

Related