serial read function not return content as expected

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
User avatar
liudr
Posts: 211
Joined: Tue Oct 17, 2017 5:18 am

serial read function not return content as expected

Post by liudr » Thu Jun 21, 2018 6:57 pm

I am experimenting with serial ports. What I am doing is pure ASCII lines with /r/n. When I tried ser.readline(), the entire line is returned, great! But when I tried ser.read(), I got empty byte string b''. The content is 22 bytes long, including the /r/n.

I thought that I was supposed to get as many bytes as available, which is the whole line. I also tried to use parameter ser.read(10) for example. It only read 10 bytes each time, the first two times I called it, as expected. Then the last two bytes didn't return when I called ser.read(10) a third time. I had to call ser.readline(), or ser.read(1) twice, to get the last two bytes. More experiments indicated that if I specify a parameter that is longer than the serial port's current content, the return is empty byte string. If I specify a parameter that is less than the length of serial port's current content, the read was successful. This is not what the doc says. Am I missing something:

This is the wipy version of the doc:

http://docs.micropython.org/en/latest/w ... .UART.read

cefn
Posts: 230
Joined: Tue Aug 09, 2016 10:58 am

Re: serial read function not return content as expected

Post by cefn » Thu Jun 21, 2018 8:59 pm

I think that ser.read() is probably behaving as it should, though I'm no expert.

I think it tries to read whatever characters are already available, and doesn't wait on a particular character (newline) coming through.

The number n you passed to ser.read(n) isn't interpreted as a minimum number of characters returned, it's a maximum.

So if you happen to query the serial port before the characters have arrived, then it won't wait around for n characters, it'll just give you what it has, which may be nothing. However, if it has more than n, it will only give you n characters.

Can anyone who actually knows this stuff confirm my description?

User avatar
liudr
Posts: 211
Joined: Tue Oct 17, 2017 5:18 am

Re: serial read function not return content as expected

Post by liudr » Fri Jun 22, 2018 7:17 pm

No, the characters HAVE arrived. Their time to arrival is within 0.01 seconds of receiving command from ESP32's serial port. I was hand typing commands, giving about several extra seconds of time. readline() always gets the whole line but read() always gets nothing. It's not a timing issue. I'll dig into the source code for answers eventually.

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

Re: serial read function not return content as expected

Post by pythoncoder » Sat Jun 23, 2018 5:50 am

This is the behaviour on a Pyboard, which is as I'd expect. To test I linked pins X1 and X2.

Code: Select all

>>> u = pyb.UART(4, 9600, timeout=5000)
>>> u.write('rats')
4
>>> u.read(4)  # Returns immediately
b'rats'
>>> u.write('rats')
4
>>> u.read()  # Delay while 5s timeout elapses
b'rats'
>>> 
In this case return from read() was immediate:

Code: Select all

>>> u.write('rats')
4
>>> u.read(2)
b'ra'
>>> u.read(2)
b'ts'
>>> 
Peter Hinch
Index to my micropython libraries.

User avatar
liudr
Posts: 211
Joined: Tue Oct 17, 2017 5:18 am

Re: serial read function not return content as expected

Post by liudr » Mon Jun 25, 2018 5:24 am

Thanks for testing. I followed your method and got the same results as you. Now I am a bit confused. I'll retest my original hardware again. I've been using transistor-type of bi-directional level shifter on the ESP32 at 3.3V with my ATMEGA328P at 5V. I'll switch to a 74HC4050 and test tomorrow.

I was using the bi-directional level shifter to read some I2C sensors at 5V.

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

Re: serial read function not return content as expected

Post by pythoncoder » Mon Jun 25, 2018 9:04 am

Testing serial interfaces with a loopback is a useful technique for separating hardware and software issues, and also for distinguishing between problems on the host and on the remote device.
Peter Hinch
Index to my micropython libraries.

Post Reply