Serial write-read slower than expected

brazoayeye
Posts: 44
Joined: Sun May 03, 2020 2:37 pm

Serial write-read slower than expected

Postby brazoayeye » Tue Apr 20, 2021 10:40 am

I have a serial protocol running on a 1-wire 232, the system works but is very slow (slower than theoretical value). Master send two bytes to slave, that reply other two bytes.

Here the setup:

Code: Select all

void setup() {
	static uart_config_t config = {
		    .baud_rate = 1200,
		    .data_bits = UART_DATA_8_BITS,
		    .parity = UART_PARITY_DISABLE,
		    .stop_bits = UART_STOP_BITS_2,
		    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
	};
	uart_param_config(1, &config)
	uart_set_line_inverse(1, UART_SIGNAL_RXD_INV | UART_SIGNAL_TXD_INV);
	uart_set_pin(1, GPIO_NUM_23, GPIO_NUM_5, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	uart_driver_install(1, 200 /*uart_rx_buffer_size*/ , /*uart_tx_buffer_size*/0 , 0, NULL, 0);
	}
	
void loop() {
	uint8_t buf[2] = {2, 135}
	int ret = uart_write_bytes(SERIAL_PWR_PORT, (char *)buf, 2);
	ESP_LOGI(TAG, "Wrote: %u %u", buf[0], buf[1]);
	ret = uart_read_bytes(SERIAL_PWR_PORT, buf , 2, RWMSreadTimeout); // I also read sent data
	ESP_LOGI(TAG, "Read: %u %u", buf[0], buf[1]);
	ret = uart_read_bytes(SERIAL_PWR_PORT, buf , 2, RWMSreadTimeout); // reply
	ESP_LOGI(TAG, "Read2: %u %u", buf[0], buf[1]);
		}
The code is working, but a typical timing is the following

Code: Select all

I (6147) RWMS: Wrote: 2 136
I (6277) RWMS: Read: 2 136
I (6277) RWMS: Read2: 138 0
Since the connection is one-wire I receive as input the written value, the problem is that I receive it 130ms after the command uart_write_bytes, that should be blocking.

Is it normal? Is it possible to speed up the connection? (1200bps * 0.130s = 156b = 19B)

brazoayeye
Posts: 44
Joined: Sun May 03, 2020 2:37 pm

Re: Serial write-read slower than expected

Postby brazoayeye » Wed Jun 09, 2021 1:14 pm

Still having the same issue, I tried also to check with uart_wait_tx_done, but all seems to show that bytes have been written. uart_wait_tx_done return almost instantly.

I can't understand if
  • The stack is slow writing values, the slave is very fast to reply (see read and read2 in the same ms)
  • The stack wrote data fast, but read from serial delayed (and maybe in "packets") that results in receiving both 2+2 bytes very close
That's very annoying, my protocol is designed keep synchronized master and slave to avoid collisions (1-wire), so the described behavior hardly slow down the communication.

I tried master esp-idf without any difference.

brazoayeye
Posts: 44
Joined: Sun May 03, 2020 2:37 pm

Re: Serial write-read slower than expected

Postby brazoayeye » Wed Mar 05, 2025 4:39 pm

Still having the same problem, using this row takes two or three times the above script

Code: Select all

buf_idx = uart_read_bytes(SERIAL_PORT, buf, len, to);

Code: Select all

TickType_t t = xTaskGetTickCount();
uart_dev_t* uart_reg = (uart_dev_t*) REG_UART_BASE(SERIAL_PORT);
while (buf_idx < len) {
	if (uart_reg->status.rxfifo_cnt){
		buf[buf_idx++] = uart_reg->fifo.val; // rw_byte
		t = xTaskGetTickCount();
	}
	if (xTaskGetTickCount() > (t + (TickType_t) to))	break;
}
The how can I see the code for uart_read_bytes to understand what is taking the time?
The previous code works well for some devices but it's not working for a RS485 with a rts_io_num pin and set as

Code: Select all

uart_set_mode(SERIAL_PORT, UART_MODE_RS485_HALF_DUPLEX)
Can someone help?

Thanks

MicroController
Posts: 2661
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Serial write-read slower than expected

Postby MicroController » Wed Mar 05, 2025 6:55 pm

You can try reducing the RX full threshold (uart_set_rx_full_threshold()) and/or the RX timeout (uart_set_rx_timeout()) in order for your code to receive data from the UART's FIFO as quickly as possible.

brazoayeye
Posts: 44
Joined: Sun May 03, 2020 2:37 pm

Re: Serial write-read slower than expected

Postby brazoayeye » Thu Mar 06, 2025 1:21 pm

Right! I send and recive very short messages (2-4 bytes) so the overhead is very high.

uart_set_rx_timeout(SERIAL_PORT, 0); => Fails
uart_set_rx_timeout(SERIAL_PORT, 1); => 14 messages/s
uart_set_rx_timeout(SERIAL_PORT, 2); => 14 messages/s
uart_set_rx_timeout(SERIAL_PORT, 10); => 7 messages/s
uart_set_rx_timeout(SERIAL_PORT, 20); => Fails

With also
uart_set_rx_full_threshold(SERIAL_PORT, 4);

i can reach the same performance as with the old method (20p/s)

User avatar
ok-home
Posts: 156
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Serial write-read slower than expected

Postby ok-home » Fri Mar 07, 2025 1:01 am

for

Code: Select all

uart_set_rx_timeout(SERIAL_PORT, 1);
try this example
https://github.com/espressif/esp-idf/bl ... ple_main.c
and check timeout_flag in event

Code: Select all

typedef struct {
    uart_event_type_t type; /*!< UART event type */
    size_t size;            /*!< UART data size for UART_DATA event*/
    bool timeout_flag;      /*!< UART data read timeout flag for UART_DATA event (no new data received during configured RX TOUT)*/
    /*!< If the event is caused by FIFO-full interrupt, then there will be no event with the timeout flag before the next byte coming.*/
} uart_event_t;

Who is online

Users browsing this forum: PetalBot, Qwantbot and 3 guests