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.

Sprite
Espressif staff
Espressif staff
Posts: 10636
Joined: Thu Nov 26, 2015 4:08 am

Re: Data loss of esp32 serial port

Postby 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.

houwenxiang
Espressif staff
Espressif staff
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby 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

Code: Untitled.c Select all


#define BUF_SIZE (2048)

static QueueHandle_t uart0_queue;
static QueueHandle_t uart1_queue;
static QueueHandle_t uart2_queue;

uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};




uart_param_config(UART_NUM_0, &uart_config);
uart_set_pin(UART_NUM_0, 22, 21, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
xTaskCreate(uart0_event_task, "uart0_event_task", 4096, NULL, 4, NULL);

uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, 2, 4, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart1_queue, 0);
xTaskCreate(uart1_event_task, "uart1_event_task", 4096, NULL, 4, NULL);

uart_param_config(UART_NUM_2, &uart_config);
uart_set_pin(UART_NUM_2, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_2, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart2_queue, 0);
xTaskCreate(uart2_event_task, "uart2_event_task", 4096, NULL, 4, NULL);



static void uart0_event_task(void *pvParameters)
{
uart_event_t event;
size_t buffered_size;
uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
for (;;)
{
//Waiting for UART event.
if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY))
{
bzero(dtmp, RD_BUF_SIZE);
// ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0);
switch (event.type)
{
//Event of UART receving data
/*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might
be full.*/
case UART_DATA:
// ESP_LOGI(TAG, "NUM 1 [UART DATA]: %d", event.size);
uart_read_bytes(UART_NUM_0, dtmp, event.size, portMAX_DELAY);

// print data logic
break;

//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
ESP_LOGI(TAG, "hw fifo overflow");
// If fifo overflow happened, you should consider adding flow control for your application.
// The ISR has already reset the rx FIFO,
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(UART_NUM_0);
xQueueReset(uart0_queue);
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG, "ring buffer full");
// If buffer full happened, you should consider encreasing your buffer size
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(UART_NUM_0);
xQueueReset(uart0_queue);
break;
//Event of UART RX break detected
case UART_BREAK:
ESP_LOGI(TAG, "uart rx break");
break;
//Event of UART parity check error
case UART_PARITY_ERR:
ESP_LOGI(TAG, "uart parity error");
break;
//Event of UART frame error
case UART_FRAME_ERR:
ESP_LOGI(TAG, "uart frame error %d", UART_NUM_0);
break;
//UART_PATTERN_DET
case UART_PATTERN_DET:
uart_get_buffered_data_len(UART_NUM_0, &buffered_size);
int pos = uart_pattern_pop_pos(UART_NUM_0);
ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
if (pos == -1)
{
// There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
// record the position. We should set a larger queue size.
// As an example, we directly flush the rx buffer here.
uart_flush_input(UART_NUM_0);
}
else
{
uart_read_bytes(UART_NUM_0, dtmp, pos, 100 / portTICK_PERIOD_MS);
uint8_t pat[PATTERN_CHR_NUM + 1];
memset(pat, 0, sizeof(pat));
uart_read_bytes(UART_NUM_0, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "read data: %s", dtmp);
ESP_LOGI(TAG, "read pat : %s", pat);
}
break;
//Others
default:
ESP_LOGI(TAG, "uart event type: %d", event.type);
break;
}
}
}
free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
}

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

houwenxiang
Espressif staff
Espressif staff
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby 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 13475 times

houwenxiang
Espressif staff
Espressif staff
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Data loss of esp32 serial port

Postby houwenxiang » Fri Apr 10, 2020 6:04 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: Baidu [Spider], ChatGPT-User, Google [Bot] and 4 guests