UART answer in 2ms

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Wander
Posts: 6
Joined: Wed Sep 11, 2019 1:03 am
Location: Brazil

UART answer in 2ms

Post by Wander » Wed Sep 11, 2019 1:46 am

Hi,
I'm trying to get UART to respond within 2ms after receiving something.
But the fastest I could get was 8ms, responding immediately after any data received without processing.
Apparently the answer is scheduled rather than sent immediately.
Measuring the time between receiving something from UART and replying, I got 1.6ms, but when I monitor the pins with an oscilloscope, I see that the response only starts to be sent 8 or 9ms after the end of the received message.
These times happen with baudrate = 9600.
If I use baudrate = 19200 the response time drops in half as well.
Working in C, directly with FreeRTOS I get a 2ms response at 9600 baud, so I know it's not a hardware limitation.
Does anyone have any idea how to reduce this time?

User avatar
jimmo
Posts: 507
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia

Re: UART answer in 2ms

Post by jimmo » Wed Sep 11, 2019 5:36 am

Are you using UART.irq to detect the incoming data?

User avatar
Roberthh
Posts: 1568
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: UART answer in 2ms

Post by Roberthh » Wed Sep 11, 2019 7:54 am

Since the delay depends on the baud rate, it looks like a timeout behavior in the receive. Looking at the documentation of the UART irq handler, that might not help much, because that is definitely waits for a timeout, however only of one character. But maybe there's a fault there, taking bits for bytes.

Wander
Posts: 6
Joined: Wed Sep 11, 2019 1:03 am
Location: Brazil

Re: UART answer in 2ms

Post by Wander » Wed Sep 11, 2019 5:54 pm

jimmo wrote:
Wed Sep 11, 2019 5:36 am
Are you using UART.irq to detect the incoming data?
No, I'm doing this way:

Code: Select all

uart1 = UART(1,
             baudrate = 9600,
             bits = 8,
             parity = 0,    # 0 = even / 1 = odd
             stop = 1,
             tx = 4,
             rx = 5,
             txbuf = 1024,
             rxbuf = 1024)

wr1 = uart1.write
rd1 = uart1.read

def send(msg):
    snd_msgs = ('RESET',
                b'\x82\x96\x06\x01\x32\x56\x01\x00\x61',
                b'\x82\x96\x06\x01\x58\x6B\xFB\xFF\x30',
                b'\x82\x96\x06\x01\x00\x00\x00\x00\x07',
                b'\x82\x96\x06\x01\xA8\x94\x04\x00\x3F',
                b'\x82\x96\x03\x01\xB2\xB0\x00\x00\x00',
                b'\x82\x96\x03\x01\xC0\xC2\x00\x00\x00')

    ok_to_send = (msg > 0) & (msg <= 6)
    if(ok_to_send):
        wr1(snd_msgs[msg])

def teste():
    buff = None

    while(buff != b'x'):
        buff = rd1(32)
        if(buff is None):
            continue
        else:
            send(1)

Wander
Posts: 6
Joined: Wed Sep 11, 2019 1:03 am
Location: Brazil

Re: UART answer in 2ms

Post by Wander » Wed Sep 11, 2019 6:03 pm

[quote=Roberthh post_id=39326 time=1568188453 user_id=601]
Since the delay depends on the baud rate, it looks like a timeout behavior in the receive. Looking at the documentation of the UART irq handler, that might not help much, because that is definitely waits for a timeout, however only of one character. But maybe there's a fault there, taking bits for bytes.
[/quote]

Yes, taking bits for bytes.... it's possible. :o

I followed this tutorial (https://www.microdev.it/wp/en/2018/08/0 ... for-esp32/) and compiled everything from scratch again, so I could modify some files for testing.

I changed the timeouts on machine_uart.c and compile again, but the result was the same.

User avatar
Roberthh
Posts: 1568
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: UART answer in 2ms

Post by Roberthh » Wed Sep 11, 2019 6:17 pm

Did you try to use uart.any() to check, whether there is data to be read? That could be faster than read, which might have a timeout.

Wander
Posts: 6
Joined: Wed Sep 11, 2019 1:03 am
Location: Brazil

Re: UART answer in 2ms

Post by Wander » Wed Sep 11, 2019 6:31 pm

No, I'll try to use the different options for read and write to see if the timing changes.

User avatar
Roberthh
Posts: 1568
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: UART answer in 2ms

Post by Roberthh » Wed Sep 11, 2019 6:56 pm

I made a test set-up and tried to use uart.any() and it dos not change the picture.

Wander
Posts: 6
Joined: Wed Sep 11, 2019 1:03 am
Location: Brazil

Re: UART answer in 2ms

Post by Wander » Wed Sep 11, 2019 7:15 pm

Ok...
I can't test right now, but tonight I'll test all the possibilities.
Thank you for test read.any()

User avatar
Roberthh
Posts: 1568
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: UART answer in 2ms

Post by Roberthh » Wed Sep 11, 2019 7:33 pm

I have a solution:
in file machine_uart.c, add the following line after line 207:

Code: Select all

    uart_set_rx_timeout(self->uart_num, self->timeout_char);
This section should then look like:

Code: Select all

    // 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);
There is a parameter for the UART constructor, which is timeout_char=xxx. The smallest accepted value is 2. Then you get a delay of ~1ms at 9600 baud. It seems that this parameter was not set for the UART.
rxtx_1ms.jpg
rxtx_1ms.jpg (64.31 KiB) Viewed 58 times

Post Reply