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

NRF52840 UART high error rate communicating with Raspberry Pi

I am using nrf52840 DK and communicate with Raspberry Pi 3 through UART port. The Raspberry Pi is used as a gateway. The baud rate is set at 115200 default on both nrf52840 and Raspberry Pi 3. Raspberry Pi 3 is using GPIO14 and GPIO15 and its UART is set up by following the official guide.

Since this is a direct wired connection from nrf52840 and Raspberry Pi 3, it does not involve the soft device. The SDK version is 17.0.2.

I found that there is rather high data error rate during the UART data transmission. For 300 sets of data transmitted from nrf52840 to Raspberry Pi, there are 13-15 set of data dropping one byte. The dropping byte position is not fixed. This is about 4% error, which is too high? 

I am using the standard Nordic UART function following the examples. 

The following is the UART init function:

static void uart_init(void)
{
ret_code_t err_code;

app_uart_comm_params_t const comm_params =
{
.rx_pin_no = RX_PIN_NUMBER,
.tx_pin_no = TX_PIN_NUMBER,
.rts_pin_no = RTS_PIN_NUMBER,
.cts_pin_no = CTS_PIN_NUMBER,
.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
.use_parity = false,
.baud_rate = UART_BAUDRATE_BAUDRATE_Baud115200
};

APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_event_handle,
APP_IRQ_PRIORITY_LOWEST,
err_code);

APP_ERROR_CHECK(err_code);
}

The following is the sending data function:

static void ble_uart_send(uint8_t * p_data, uint16_t data_len)
{
ret_code_t ret_val;


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_INFO("app_uart_put failed for index 0x%04x.", i);

}
} while (ret_val == NRF_ERROR_BUSY);
}

// Add two end bytes to identify the ending of the packet
do
{

ret_val = app_uart_put(0xAA);
if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
{
NRF_LOG_INFO("app_uart_put failed\r\n");

}
} while (ret_val == NRF_ERROR_BUSY);
do
{
ret_val = app_uart_put('\n');
if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
{
NRF_LOG_INFO("app_uart_put failed\r\n");

}
} while (ret_val == NRF_ERROR_BUSY);

}

Parents Reply
  • Yes the pins are fine. I have narrowed down to the following right now: 

    The nrf52840 also uses nus UART service to receive data from peripheral. Once nus data is received, then nrf52840 calls ble_uart_send() function to send data to Raspberry Pi. 

    The data received via nus UART is correct (I double-checked :)).

    The program sends data via UART to Raspberry Pi also correctly when it runs alone (without connecting to the nus UART service). I used constant dummy data to verify this. No errors occur even at higher UART rate. 

    The problem arises when they run together. The nus data is always correct. But the UART data transfer to the Raspberry Pi start having errors. 

Children
  • If central, does the busy NRF_ERROR_BUSY get handled like this:

    static void ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len)
    {
        ret_code_t ret_val;
    
        NRF_LOG_DEBUG("Receiving data.");
        NRF_LOG_HEXDUMP_DEBUG(p_data, data_len);
    
        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);
        }
        if (p_data[data_len-1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
    

    Hopefully also ECHOBACK_BLE_UART_DATA is 0

  • The problem was solved. It turns out that for high speed UART, the UART function should not be called in the nus event. Otherwise, it will cause the UART higher error rate. 

Related