UART swallows bytes

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
grafalex
Posts: 9
Joined: Sun Mar 04, 2018 4:53 pm

UART swallows bytes

Post by grafalex » Sun Feb 27, 2022 3:09 pm

Hi All,

I am developing an application that is supposed to read a lot of text data from HW UART. For some reason it reads only first 15 bytes, and the rest of the message disappears. I tried both asyncio and raw UART approaches - same behavior. I also tried to use UART IRQ - looks like this is not supported in ESP8266 port.

Here is my sender (runs on a host Windows machine)

Code: Select all

import serial
import time

ser = serial.Serial('COM4', baudrate=115200)

i=0
while True:
	l = "Hello World ABC " + str(i) + "\n"
	i = i+1
	ser.write(l.encode())     # write a string
	time.sleep(1)
Receiver code on ESP8266

Code: Select all

import machine
import network
import webrepl
import uos
import time

connectWiFi('ssid', 'wifi_pw') # No problems with WiFi connectivity

webrepl.start() # detaching REPL from HW uart, use WebREPL only
uos.dupterm(None, 1)

uart = machine.UART(0, 115200)
while True:
    s = uart.read(128)
    if s:
        print("s = " + ' '.join('{:02x}'.format(x) for x in s))
        l = s.decode()
        print(l)
        
        # Some network connectivity code here in future
The problem is that some of the messages get truncated, and I can't figure out what the problem is.

Code: Select all

s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 30 0a                                                                                            
Hello World ABC0                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 31 0a                                                                                                
Hello World ABC1                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43                                                                                                      
Hello World ABC                                                                                                                                       
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 33 0a                                                                                                
Hello World ABC3                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 34 0a                                                                                                
Hello World ABC4                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 35 0a                                                                                                
Hello World ABC5                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43                                                                                                      
Hello World ABC                                                                                                                                       
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 37 0a                                                                                                
Hello World ABC7                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 38 0a                                                                                                
Hello World ABC8                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 39 0a                                                                                                
Hello World ABC9                                                                                                                                      
                                                                                                                                                      
s = 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 41 42 43 31 30 0a                                                                                             
Hello World ABC10
What could be the problem here? Is there a buffering on UART side? Or can I have own buffer somehow?

There will be some processing of the received message, and particularly sending the data to a server over a TCP connection. I tried to use asyncio, but have the same truncation at 15 byte boundary. Messages are pretty infrequent (once a second), but the baud rate seems to matter.

Is this because some heavy processing (e.g. prints, sending data over the network for WebREPL) which causes missing the rest of the message? Any thoughts?

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

Re: UART swallows bytes

Post by Roberthh » Sun Feb 27, 2022 4:00 pm

The default read buffer is 16 bytes, which can hold 15 bytes. You can increase the read buffer with the rxbuf=nnn option in the init() or constructor call, like:

Code: Select all

uart = machine.UART(0, 115200, rxbuf=256)

grafalex
Posts: 9
Joined: Sun Mar 04, 2018 4:53 pm

Re: UART swallows bytes

Post by grafalex » Sun Feb 27, 2022 4:39 pm

Thank you very much, that worked.
Though it still can receive the string in 16byte parts, but I managed to assemble the string in my code.

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

Re: UART swallows bytes

Post by Roberthh » Sun Feb 27, 2022 5:24 pm

If your messages and with newline like in the example, you can use uart.readline(). You may have to set timeout in the constructor or init() appropriately, so that the call does not return too early

grafalex
Posts: 9
Joined: Sun Mar 04, 2018 4:53 pm

Re: UART swallows bytes

Post by grafalex » Sun Feb 27, 2022 6:13 pm

Thank you for your suggestions.

Post Reply