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

Getting lots of noise/errors using Serial library.

Hi,

I am getting lots of transmission errors using the Serial library.   I changed the Serial_Uartes example by removing the serial1 interface and creating a simple loopback at 115,200 bps.

Just by holding a key on the keyboard on a screen serial connection creates lots of lost bits.  What could be the problem?

Below is the modified code for .../examples/peripherial/serial_uartes/main.c

(....)

#include "app_error.h"
#include "app_util.h"
#include "boards.h"

/** @file
 * @defgroup nrf_serial_uartes_example main.c
 * @{
 * @ingroup nrf_serial_uartes_example
 * @brief Example of @ref nrf_serial usage. Loopback example using two UARTE peripherals.
 *        Please short Arduino SCL and SDA GPIOs to start transmission.
 *
 */

#define OP_QUEUES_SIZE          3
#define APP_TIMER_PRESCALER     NRF_SERIAL_APP_TIMER_PRESCALER

static void sleep_handler(void)
{
    __WFE();
    __SEV();
    __WFE();
}

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte0_drv_config,
                      RX_PIN_NUMBER, TX_PIN_NUMBER,
                      RTS_PIN_NUMBER, CTS_PIN_NUMBER,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte1_drv_config,
                      ARDUINO_SDA_PIN, ARDUINO_SCL_PIN,
                      RTS_PIN_NUMBER, CTS_PIN_NUMBER,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);


#define SERIAL_FIFO_TX_SIZE 256
#define SERIAL_FIFO_RX_SIZE 256

NRF_SERIAL_QUEUES_DEF(serial0_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
NRF_SERIAL_QUEUES_DEF(serial1_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);


#define SERIAL_BUFF_TX_SIZE 1
#define SERIAL_BUFF_RX_SIZE 1

NRF_SERIAL_BUFFERS_DEF(serial0_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
NRF_SERIAL_BUFFERS_DEF(serial1_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);


NRF_SERIAL_CONFIG_DEF(serial0_config, NRF_SERIAL_MODE_DMA,
                      &serial0_queues, &serial0_buffs, NULL, sleep_handler);
NRF_SERIAL_CONFIG_DEF(serial1_config, NRF_SERIAL_MODE_DMA,
                      &serial1_queues, &serial1_buffs, NULL, sleep_handler);


NRF_SERIAL_UART_DEF(serial0_uarte, 0);
NRF_SERIAL_UART_DEF(serial1_uarte, 1);


int main(void)
{
    ret_code_t ret;

    ret = nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);
    ret = nrf_drv_power_init(NULL);
    APP_ERROR_CHECK(ret);

    nrf_drv_clock_lfclk_request(NULL);
    ret = app_timer_init();
    APP_ERROR_CHECK(ret);

    // Initialize LEDs and buttons.
    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);

    ret = nrf_serial_init(&serial0_uarte, &m_uarte0_drv_config, &serial0_config);
    APP_ERROR_CHECK(ret);

    // ret = nrf_serial_init(&serial1_uarte, &m_uarte1_drv_config, &serial1_config);
    // APP_ERROR_CHECK(ret);

    static char tx_message[] = "Hello nrf_serial!\n\r";

    ret = nrf_serial_write(&serial0_uarte,
                           tx_message,
                           strlen(tx_message),
                           NULL,
                           NRF_SERIAL_MAX_TIMEOUT);
    (void)nrf_serial_flush(&serial0_uarte, 0);

    while (true)
    {
        char c;
        ret = nrf_serial_read(&serial0_uarte, &c, sizeof(c), NULL, 0);
        if (ret != NRF_SUCCESS)
        {
            continue;
        }
        (void)nrf_serial_write(&serial0_uarte, &c, sizeof(c), NULL, 0);
        (void)nrf_serial_flush(&serial0_uarte, 0);

        //ret = nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 1000);
       // if (ret != NRF_SUCCESS)
        //{
        //    continue;
        //}
        //(void)nrf_serial_write(&serial1_uarte, &c, sizeof(c), NULL, 0);
        //(void)nrf_serial_flush(&serial1_uarte, 0);
    }
}

The result from a terminal with the a key pressed, looks:

Hello nrf_serial!
aaa�aa�aaaaaaaaaaaaaaaaaaaaaaaaaaaa�aaa��aa�aaaaaaaa�a�a�aaaaaaaaaaaaa��aaaaaaaaaaa�aaaaaaaaaaaaaaaa�aaa�a�aaaaaaaaaaaa�a��aaa�a�aaaaaaaaaaa�aaa�a��aaaaaaaa�aaaaaaaaaaaaaaaaaaaaaaaaa�aaaaaa�aa�aaaaaa�aaaaaaaaaaaaaaaaa�aaaaaaaaaaaaaaaaaa�aaaaaaaa�aaaaaaaaaaaaaaaaaaaaa�aaa�a��aaa�aaaaaaaa�aaaaaaaaaaaaaaaaa�a�aaaaaa��aaaa

I am using the DK pca_10065 board, this is running on the Release configuration, connected through the USB port to a Mac.

I am using this example as a basis for a software that should transmit data reliably between a PC and a BLE sensor on the other side, but just between the board and the PC the communication seems to be very flaky.

Will appreciate any help!

Thanks,

Juan

Parents
  • Hi,

     

    This might be inherited from the 64 MHz RC oscillator, which has a high tolerance.

    Could you try starting the external HFCLK? can be done in this function: nrf_drv_clock_hfclk_request();

     

    Kind regards,

    Håkon

  • Thanks Hakon.

    I tried your suggestion, both by leaving the call to:

    nrf_drv_clock_lfclk_request(NULL);

    and without it.  Same result.

    On general guidance, which example would you recommend using as a basis for UART communications between the NRF52840 and an external board? which example/library is the most reliable?

    In the last few days, I have tried so far: libuarte, serial_uartes, serial, ble_central_uart.  I see similar issues on all of them when I run loopback tests.  In the specs, it says that UART and UARTE should support full-duplex communication, but I am not seeing that with any the examples above.  It fails even at 9600 bps.

    Could it be a bug on SDK 16? 

    Help please, we need to get this working.

    Thanks many,

    Juan

  • Yes, I did.  Same result.

    @snip...

    int main(void) {
      ret_code_t ret;
    
      ret = NRF_LOG_INIT(NULL);
      NRF_LOG_DEFAULT_BACKENDS_INIT();
    
      
      ret = nrf_drv_clock_init();
      APP_ERROR_CHECK(ret);
      ret = nrf_drv_power_init(NULL);
      APP_ERROR_CHECK(ret);
      nrf_drv_clock_hfclk_request(NULL);
      nrf_drv_clock_lfclk_request(NULL);
      ret = app_timer_init();
      APP_ERROR_CHECK(ret);
    
      // Initialize LEDs and buttons.
      bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
    
      ret = nrf_serial_init(&serial0_uarte, &m_uarte0_drv_config, &serial0_config);
      APP_ERROR_CHECK(ret);
    
      //ret = nrf_serial_init(&serial1_uarte, &m_uarte1_drv_config, &serial1_config);
      //APP_ERROR_CHECK(ret);
    
      static char tx_message[] = "Hello nrf_serial!\n\r";
    
      ret = nrf_serial_write(&serial0_uarte,
          tx_message,
          strlen(tx_message),
          NULL,
          NRF_SERIAL_MAX_TIMEOUT);
      (void) nrf_serial_flush(&serial0_uarte, 0);
      void* buf = malloc(300);
      if ( buf == NULL ) {
        NRF_LOG_ERROR("Not enough memory!");
        ASSERT(false);
      }
      memset(buf, 0, 250);
      size_t tread = 0;
      uint32_t totB = 0;
      while (true) {
        size_t rd = 0;
        ret = nrf_serial_read(&serial0_uarte, buf, 250, &rd, 0);
        if (ret != NRF_SUCCESS && rd == 0) {
          continue;
        }
        (void) nrf_serial_write(&serial0_uarte, buf, rd, NULL, 0);
        totB = totB + rd;
        tread = tread + rd;
        if (tread > 100) {
          (void) nrf_serial_flush(&serial0_uarte, 0);
          tread = 0;
          NRF_LOG_INFO("Flushed after %d bytes", totB);
        }
       
    
        //ret = nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 1000);
        // if (ret != NRF_SUCCESS)
        //{
        //    continue;
        //}
        //(void)nrf_serial_write(&serial1_uarte, &c, sizeof(c), NULL, 0);
        //(void)nrf_serial_flush(&serial1_uarte, 0);
      }
    }
    

  • Hi,

     

    Thanks, I have recreated the issue with your sample.

    Unfortunately, I haven't been able to find a workaround on this matter, so my suggestion is to use libuarte if you require timed uart reception.

    I have reported the issue internally to the SDK team so that they are aware of this issue.

     

    Kind regards,

    Håkon

  • Thanks a lot, Hakon.

    Just for FYI, the UART connection works acceptably if all logging is disabled.  My guess is that logging may be sharing something with UART that creates the problem.  Just my ignorant guess.

    Cheers,

    Juan

  • jfarjona said:
    Just for FYI, the UART connection works acceptably if all logging is disabled.  My guess is that logging may be sharing something with UART that creates the problem.  Just my ignorant guess.

     I tried to disable the logging (I also suspected this one), and still got corrupted characters "here and there", while if I changed the mode to polling (instead of DMA / interrupt driven) it worked as it should, but you do not want polling in a power optimized application.

     

    Kind regards,

    Håkon

  • I decided to use app_uart, which gives me the same problem if logging is enabled, but without logging it works ok at 115200 bps.  I haven’t tried libuarte without logging yet.

    Cheers,

    Juan

Reply Children
No Data
Related