Data loss of esp32 serial port

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Data loss of esp32 serial port

Postby huang.yan » Thu Apr 09, 2020 12:32 pm

I use four esp32 module to form a small system, three of which send data to the rest one as master through the serial port. The master esp32 uses three serial ports, and after testing, it is found that almost half of the data received through the serial port on the master esp32 will be lost. The data transmission rate of three slave modules is about 1200 bytes per second.
Is it because the three serial ports of master esp32 share a buffer? What is the root cause of this problem? Is there any solutions?
Any suggestion will be appreciated.
Thanks.

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Data loss of esp32 serial port

Postby ESP_Sprite » Thu Apr 09, 2020 3:02 pm

Any chance we can see your code? In theory there should not be a reason why the hardware drops packets, however 1200 baud is very slow and buffers aren't infinite so there may be a reason why software drops stuff.

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Re: Data loss of esp32 serial port

Postby huang.yan » Fri Apr 10, 2020 2:15 am

The baud is 115200,but the data send to serial port is about 1200 bytes per second.

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby ESP_houwenxiang » Fri Apr 10, 2020 2:23 am

Do you use RS485 or directly connect the gpio of the four UARTs together?
wookooho

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Re: Data loss of esp32 serial port

Postby huang.yan » Fri Apr 10, 2020 2:27 am

The logic of the serial data processing part is as follows
  1. #define BUF_SIZE (2048)
  2.  
  3. static QueueHandle_t uart0_queue;
  4. static QueueHandle_t uart1_queue;
  5. static QueueHandle_t uart2_queue;
  6.  
  7. uart_config_t uart_config = {
  8.          .baud_rate = 115200,
  9.          .data_bits = UART_DATA_8_BITS,
  10.          .parity = UART_PARITY_DISABLE,
  11.          .stop_bits = UART_STOP_BITS_1,
  12.          .flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
  13.          
  14.  
  15.  
  16.  
  17. uart_param_config(UART_NUM_0, &uart_config);
  18. uart_set_pin(UART_NUM_0, 22, 21, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  19. uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
  20. xTaskCreate(uart0_event_task, "uart0_event_task", 4096, NULL, 4, NULL);
  21.  
  22. uart_param_config(UART_NUM_1, &uart_config);
  23. uart_set_pin(UART_NUM_1, 2, 4, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  24. uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart1_queue, 0);
  25. xTaskCreate(uart1_event_task, "uart1_event_task", 4096, NULL, 4, NULL);
  26.  
  27. uart_param_config(UART_NUM_2, &uart_config);
  28. uart_set_pin(UART_NUM_2, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  29. uart_driver_install(UART_NUM_2, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart2_queue, 0);
  30. xTaskCreate(uart2_event_task, "uart2_event_task", 4096, NULL, 4, NULL);
  31.  
  32.  
  33.  
  34. static void uart0_event_task(void *pvParameters)
  35. {
  36.     uart_event_t event;
  37.     size_t buffered_size;
  38.     uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
  39.     for (;;)
  40.     {
  41.         //Waiting for UART event.
  42.         if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY))
  43.         {
  44.             bzero(dtmp, RD_BUF_SIZE);
  45.             // ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0);
  46.             switch (event.type)
  47.             {
  48.                 //Event of UART receving data
  49.             /*We'd better handler data event fast, there would be much more data events than
  50.                 other types of events. If we take too much time on data event, the queue might
  51.                 be full.*/
  52.             case UART_DATA:
  53.                 // ESP_LOGI(TAG, "NUM 1 [UART DATA]: %d", event.size);
  54.                 uart_read_bytes(UART_NUM_0, dtmp, event.size, portMAX_DELAY);
  55.                
  56.                 // print data logic
  57.                 break;
  58.  
  59.             //Event of HW FIFO overflow detected
  60.             case UART_FIFO_OVF:
  61.                 ESP_LOGI(TAG, "hw fifo overflow");
  62.                 // If fifo overflow happened, you should consider adding flow control for your application.
  63.                 // The ISR has already reset the rx FIFO,
  64.                 // As an example, we directly flush the rx buffer here in order to read more data.
  65.                 uart_flush_input(UART_NUM_0);
  66.                 xQueueReset(uart0_queue);
  67.                 break;
  68.             //Event of UART ring buffer full
  69.             case UART_BUFFER_FULL:
  70.                 ESP_LOGI(TAG, "ring buffer full");
  71.                 // If buffer full happened, you should consider encreasing your buffer size
  72.                 // As an example, we directly flush the rx buffer here in order to read more data.
  73.                 uart_flush_input(UART_NUM_0);
  74.                 xQueueReset(uart0_queue);
  75.                 break;
  76.             //Event of UART RX break detected
  77.             case UART_BREAK:
  78.                 ESP_LOGI(TAG, "uart rx break");
  79.                 break;
  80.             //Event of UART parity check error
  81.             case UART_PARITY_ERR:
  82.                 ESP_LOGI(TAG, "uart parity error");
  83.                 break;
  84.             //Event of UART frame error
  85.             case UART_FRAME_ERR:
  86.                 ESP_LOGI(TAG, "uart frame error %d", UART_NUM_0);
  87.                 break;
  88.             //UART_PATTERN_DET
  89.             case UART_PATTERN_DET:
  90.                 uart_get_buffered_data_len(UART_NUM_0, &buffered_size);
  91.                 int pos = uart_pattern_pop_pos(UART_NUM_0);
  92.                 ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
  93.                 if (pos == -1)
  94.                 {
  95.                     // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
  96.                     // record the position. We should set a larger queue size.
  97.                     // As an example, we directly flush the rx buffer here.
  98.                     uart_flush_input(UART_NUM_0);
  99.                 }
  100.                 else
  101.                 {
  102.                     uart_read_bytes(UART_NUM_0, dtmp, pos, 100 / portTICK_PERIOD_MS);
  103.                     uint8_t pat[PATTERN_CHR_NUM + 1];
  104.                     memset(pat, 0, sizeof(pat));
  105.                     uart_read_bytes(UART_NUM_0, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
  106.                     ESP_LOGI(TAG, "read data: %s", dtmp);
  107.                     ESP_LOGI(TAG, "read pat : %s", pat);
  108.                 }
  109.                 break;
  110.             //Others
  111.             default:
  112.                 ESP_LOGI(TAG, "uart event type: %d", event.type);
  113.                 break;
  114.             }
  115.         }
  116.     }
  117.     free(dtmp);
  118.     dtmp = NULL;
  119.     vTaskDelete(NULL);
  120. }

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Re: Data loss of esp32 serial port

Postby huang.yan » Fri Apr 10, 2020 2:28 am

Directly connect the gpio of the four UARTs together

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby ESP_houwenxiang » Fri Apr 10, 2020 2:37 am

I think this may be the reason. For example, when A needs to send data to D. At this time B and C are in the IDLE state( output high level). the low level of A output will be pulled by B and C, at intermediate level (perhaps 1.5V) . Can you look at the waveform with an oscilloscope ?
wookooho

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Re: Data loss of esp32 serial port

Postby huang.yan » Fri Apr 10, 2020 3:10 am

The serial ports used by master esp32 as shown in the attachment picture.
You mean when serial1 and serial2 are not sending data,output high level, will cause serial0 to a intermediate level,and the serial sending would be abnormal?
If all of the 3 serial ports are sending at the same time,output low level,there would be no data loss?
Attachments
esp32_serial.png
esp32_serial.png (129.44 KiB) Viewed 9554 times

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby ESP_houwenxiang » Fri Apr 10, 2020 6:04 am

huang.yan wrote:
Fri Apr 10, 2020 3:10 am
The serial ports used by master esp32 as shown in the attachment picture.
You mean when serial1 and serial2 are not sending data,output high level, will cause serial0 to a intermediate level,and the serial sending would be abnormal?
If all of the 3 serial ports are sending at the same time,output low level,there would be no data loss?
Yes, the serial0 want to pull the TXD line low, but serial1 and serial2 pull the TXD line high. So the TXD line will be in intermediate level (I have checked the level is 1.7V).
wookooho

huang.yan
Posts: 17
Joined: Thu Apr 09, 2020 12:26 pm

Re: Data loss of esp32 serial port

Postby huang.yan » Fri Apr 10, 2020 8:03 am

I'm not sure if I understand correctly.
Are the 3 serial ports share one txd and rxd bus line? And this is the cause of data loss.
For my scenario, the master esp32 module will receive a lot of data from 3 slave esp32 module and send little data.Even if rxd is in intermediate level,it will not cause all data loss?
Is there any way to solve this problem?
Thanks

Who is online

Users browsing this forum: Vilius and 105 guests