← index #5098Issue #8778
Likely Duplicate · medium · value 1.893
QUERY · ISSUE

UART timeout and timeout_char is not working in ESP32

openby WanderGitopened 2019-09-12updated 2021-05-11
port-esp32

Hi,

I noticed that UART timeout_char is not working. Regardless of the value of this parameter, UART always waits for around 8x the time of a character to identify that communication has ended.
With the help of a forum contributor, we were able to locate and fix the problem.
In the machine_uart.c we add the following command to line 208:

uart_set_rx_timeout(self->uart_num, self->timeout_char);

==================================================
Now that code snippet looked like this:

// set timeout_char
// make sure it is at least as long as a whole character (13 bits to be safe)
self->timeout_char = args[ARG_timeout_char].u_int;
uint32_t min_timeout_char = 13000 / baudrate + 1;
if (self->timeout_char < min_timeout_char) {
    self->timeout_char = min_timeout_char;
}
uart_set_rx_timeout(self->uart_num, self->timeout_char);

==================================================

I don't know if timeouts have been disabled for a specific reason, but I would like to report that this minor fix resolves the issue, at least for timeout_char.

CANDIDATE · ISSUE

Serial behavior under low baud rate

closedby Tangerinoopened 2022-06-18updated 2022-06-20
bug

MP Version 1.19
Target: ESP32
Serial TX <-> RX in the same port (loopback)

Under low baud rate, the information takes one second to be received.
In 110bps it takes 1/110 * 10 sec = 0.09 seconds to be transmitted and the following code demonstrate that the character is received back after 1 second or so.

Using legacy devices where the protocol is time sensitive is a huge problem.

from time import ticks_diff
from time import ticks_ms
import machine

def test(baud_rate, loops):
    uart = machine.UART(2, tx=12, rx=34, timeout=1, baudrate=baud_rate, timeout_char=1)
    for loop in range(loops):
        uart.write("U" * 1)
        now = ticks_ms()
        while True:
            if uart.any():
                elapsed = ticks_diff(ticks_ms(), now)
                rx = uart.read()
                print(f"{loop} - Baud rate:{baud_rate}. Got {len(rx)} bytes - Elapsed {elapsed} - {rx}")
                break


for baud_rate in [9600, 300, 110, 115200]:
    print(f"Testing baud rate {baud_rate}")
    test(baud_rate=baud_rate, loops=2)

Results

Testing baud rate 9600
0 - Baud rate:9600. Got 1 bytes - Elapsed 12 - b'U'
1 - Baud rate:9600. Got 1 bytes - Elapsed 12 - b'U'
Testing baud rate 300
0 - Baud rate:300. Got 1 bytes - Elapsed 373 - b'U'
1 - Baud rate:300. Got 1 bytes - Elapsed 371 - b'U'
Testing baud rate 110
0 - Baud rate:110. Got 1 bytes - Elapsed 1018 - b'U'
1 - Baud rate:110. Got 1 bytes - Elapsed 1016 - b'U'
Testing baud rate 115200
0 - Baud rate:115200. Got 1 bytes - Elapsed 1 - b'U'
1 - Baud rate:115200. Got 1 bytes - Elapsed 1 - b'U'

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied