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

Data loss while sending data over UART

I am using nRF52832 with SDK 15.2.0 for my application. The application is created taking ble_app_uart example as the base. I have modified the example to suit my requirements. The application uses only one characteristics for sending and receiving data. Characteristics supports NOTIFY. The application also supports BLE NUS client role so it can do service discovery and also enable NOTIFICATION on the peer and get data from peer via NOTIFICATION. Connection interval minimum & maximum is set at 20 ms and 40 ms respectively.

My application receives large data around 30KB from peer (which is another BLE module in central mode) over BLE. The data is received via NOTIFICATIONS, 20 bytes at a time. The data received is then sent to a custom board which is connected using UART. Baud rate for UART is set at 9600 bps. The data transfer over UART starts soon after the application receives the notification value i.e as soon at it receives the first 20 bytes. It is observed that few bytes of data are lost while transmitting over UART. The loss of data is not consistent and I do receive the entire data sometimes.

For testing purpose I have connected a generic BLE module in a central mode and my device (which is the peripheral) to a PC using USB-Serial adapter. The central device connects to the peripheral, and using RealTerm I transmit 30KB of data from central to peripheral. The data received by the peripheral is transmitted back to the PC and captured using RealTerm.

I am using app_uart_put() to transmit data over UART

   // Data transmit over UART
    for (uint32_t i = 0; i < data_len; i++)
    {
        do
        {
            ret_val = app_uart_put(p_data[i]);
            if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
            {
                NRF_LOG_ERROR("app_uart_put failed for index 0x%04x.", i);
                APP_ERROR_CHECK(ret_val);
            }  
        } while (ret_val == NRF_ERROR_BUSY);
    }

Any suggestions to further understand or debug the issues would be helpful.

On a side note, I noticed following comment in app_uart_put(). Is this causing the data loss, since BLE data is also being received continuously which has a higher priority and the function app_uart_put() is called in a do-while loop which will wait till the data is transmitted. Does this also explain why there is no data loss if the baud rate is higher. Is there a way to check if this is the reason for the data loss.

			// This operation should be almost always successful, since we've
            // just added a byte to FIFO, but if some bigger delay occurred
            // (some heavy interrupt handler routine has been executed) since
            // that time, FIFO might be empty already.
			if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
            {
                err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
            }

Parents
  • Hi 

    Have you calculated the approximate throughput of the data being sent to the device to make sure that you are not sending data quicker than the UART can handle?

    At 9600 bps the UART will be much slower than the BLE link, even when sending only 20 byte payloads. When sending notifications the BLE stack can buffer multiple payloads, and send them quickly back-to-back on a single connection event, increasing the throughput beyond one packet per connection event. 

    Ideally you need to be able to delay the data transmission over BLE once the UART buffers start filling up, to make sure that you are not overflowing the UART. 

    Best regards
    Torbjørn

  • Thanks for the response.

    At 9600 baud rate, it will take around ~17 msec to send 20 bytes over UART, which is as you have pointed out is much slower than the BLE link.

    While transmitting data over UART it is first stored in a FIFO before it is sent out, so I assumed that the mismatch in data rate between UART and BLE link would be taken care of.

    Any suggestions on how to delay the BLE link would be helpful

    Thanks & Regards,

    Bhushan P

Reply
  • Thanks for the response.

    At 9600 baud rate, it will take around ~17 msec to send 20 bytes over UART, which is as you have pointed out is much slower than the BLE link.

    While transmitting data over UART it is first stored in a FIFO before it is sent out, so I assumed that the mismatch in data rate between UART and BLE link would be taken care of.

    Any suggestions on how to delay the BLE link would be helpful

    Thanks & Regards,

    Bhushan P

Children
  • I am now storing the data received over BLE into a buffer and then transmitting it over UART.

    My application receives data in fixed data size. The peer waits for an acknowledgement before sending the next set of data. I am using this to add delay by sending the acknowledgement after first set of data has been transmitted over UART. 

    This is a slower method but works for me right now.

    Is there a better or faster way to ensure data is sent successfully over UART?

    Thanks.

  • Hi

    If the UART buffers fill up you don't really have any other options than to buffer the data externally, and wait for the UART buffers to clear before you can send more. 

    Bhushan P said:
    This is a slower method but works for me right now.

    In what way is it slower? Are you not able to maximize the UART throughput?

    Best regards
    Torbjørn

Related