Data loss of esp32 serial port
Data loss of esp32 serial port
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.
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.
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Data loss of esp32 serial port
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.
Re: Data loss of esp32 serial port
The baud is 115200,but the data send to serial port is about 1200 bytes per second.
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: Data loss of esp32 serial port
Do you use RS485 or directly connect the gpio of the four UARTs together?
wookooho
Re: Data loss of esp32 serial port
The logic of the serial data processing part is as follows
- #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);
- }
Re: Data loss of esp32 serial port
Directly connect the gpio of the four UARTs together
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: Data loss of esp32 serial port
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
Re: Data loss of esp32 serial port
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?
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 (129.44 KiB) Viewed 11643 times
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: Data loss of esp32 serial port
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).huang.yan wrote: ↑Fri Apr 10, 2020 3:10 amThe 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?
wookooho
Re: Data loss of esp32 serial port
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
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: No registered users and 215 guests