Lib uasyncio: Cannot receive ByteData bigger than 64byte

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
chiratoss
Posts: 3
Joined: Fri Jul 07, 2017 12:31 pm

Lib uasyncio: Cannot receive ByteData bigger than 64byte

Post by chiratoss » Fri Jul 07, 2017 1:18 pm

At first: Hello to all,

My Name is Tobias. I'm a professional high level application develper from Germany. So I'm lacking a bit in this low level stuff. But I think i will be able give help on plenty of other topics.

My current use case is receiving up to 250 byte of data from the UART. I want to do this asynchron for several reasons and run into a issue which I'm unable to solve atm. It would be really glad, if somebody could give me a hint to solve this.

This is the minimal Code:

------------------------------------------------------------------------------------------------------------------------------------------

import uasyncio as asyncio
from pyb import UART
uart = UART(4, baudrate=115200, bits=8, parity=None, stop=2)

async def sender():
swriter = asyncio.StreamWriter(uart, {})
while True:
await swriter.awrite(b'2201FFFFFFFFFFFFFFFFFCFFFDFFE5FFFFF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n')
await asyncio.sleep(2)

async def receiver():
sreader = asyncio.StreamReader(uart)
while True:
res = await sreader.readline()
print('Recieved: ' + str(len(res)), res)

print('UART Test: Link X1 and X2')
loop = asyncio.get_event_loop()
loop.create_task(sender())
loop.create_task(receiver())
loop.run_forever()

------------------------------------------------------------------------------------------------------------------------------------------

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Lib uasyncio: Cannot receive ByteData bigger than 64byte

Post by pythoncoder » Sat Jul 08, 2017 7:23 am

The code looks correct. I think the internal buffer is filling up; by default it's 64 bytes long. To prove this you might like to try a much lower baud rate. Assuming this works, one option is to use flow control. This involves linking the transmitter's CTS line to the receiver's RTS line and specifying flow = UART.RTS | UART.CTS to the UART constructor. This enables the receiver to stop the transmitter when the buffer is full. For this to work with an external device rather than a loopback the device will need to support hardware RTS/CTS handshaking.

This solution reduces throughput. Another option is to specify read_buf_len=260 to the UART constructor. This is OK if you know in advance the maximum message size.

The solutions can be combined to ensure that the larger buffer will never overflow.
Peter Hinch
Index to my micropython libraries.

chiratoss
Posts: 3
Joined: Fri Jul 07, 2017 12:31 pm

Re: Lib uasyncio: Cannot receive ByteData bigger than 64byte

Post by chiratoss » Mon Jul 10, 2017 2:10 pm

Thanks for your thoughts on this thing. Today I did a view more testing on this side.
Adding read_buf_len=260 in the constructor is doing the job. Adding the flow control doesn't fix the issue in my special case, but that should be working too.

I changed the testsetting by removing the bridge between X1 and X2 and I created test data from a external device. The read buffer doesn't overflow in both cases (read_buf_len is specified and read_buf_len is not specified). I can receive up to 900byte, maybe even more, this was the max data in my test case.

I think this test failes cause the write buffer if filling up and the data cannot be sent. I'm going to check next wednesday by using a oscilloscope.

Post Reply