I have a Pico and the problem that UART reading & writing via uasyncio Streams stalls after some time.
Using following recent pre-built version:
MicroPython v1.17 on 2021-09-02; Raspberry Pi Pico with RP2040
The final goal is to attach multiple sensors to it and report status via UART to a pretty remote Beaglebone. Right now I'm focusing on the UART communication, which does not work reliable: For testing purpose I'm using the Pico to write to one UART and read the same signal from a different UART. That perfectly works fine for hours, but at some point the communication stalls. There is no error reported, the StreamWriter still loops, debug output is printed to my attached Linux box. But when I measure the electrical output on the pins, there is no change. The test is a little extreme, sending lots of data on fast interval, but this should simulate a Pico which runs reliable for months. Multiple tests have been performed, but it randomly fails after 10000, or more read and writes (typically after a few hours).
So the program is still working and looping, but there is no change on the electrical output PIN's and as result the reader doesn't report anything more.
I have tried lots of different things: Monitoring the memory consumption, which looks OK. Heap memory is consumed, but cleared by the GC on regular intervals. I also tried once and disabled all print statements to reduce the communication overhead, still the same problem shows up (checking the LED indicator)
Help and hints a really appreciated, since robust communication is key to make progress on this project.
The original code is more complex with sensors, timers etc., but I have down stripped it to a simple case:
Code: Select all
import machine
import uasyncio
class PicoUart:
def __init__(self):
self._led = machine.Pin(25, machine.Pin.OUT)
self._led.value(1)
self._uart0 = machine.UART(0, baudrate=9600, parity=0, bits=8, tx=machine.Pin(16), rx=machine.Pin(17))
self._uart1 = machine.UART(1, baudrate=9600, parity=0, bits=8, tx=machine.Pin(8), rx=machine.Pin(9))
self._button_stop = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)
self._run = True
self._swriter = uasyncio.StreamWriter(self._uart0)
self._led_timer = None
def close(self):
if self._led_timer:
self._led_timer.deinit()
self._led_timer = None
async def reader(self):
sreader = uasyncio.StreamReader(self._uart1)
while self._run:
bdata = await sreader.readline()
print("Read: ", bdata.decode("utf-8"))
self._led.value(1)
await uasyncio.sleep_ms(10)
self._led.value(0)
async def writer(self):
idx = 0
while self._button_stop.value() == 1:
idx += 1
data = f"{{'idx': {idx} 'temp_ext': 21.5625, 'temp_int': 26.57626, 'action': 'send_data'}}\n"
bdata = data.encode("utf-8")
self._swriter.write(bdata)
await self._swriter.drain()
await uasyncio.sleep_ms(200)
self._run = False
await uasyncio.sleep(3)
async def run(self):
t1 = uasyncio.create_task(self.writer())
t2 = uasyncio.create_task(self.reader())
await t1
t2.cancel()
print("running: uart.py...")
pico_uart = PicoUart()
uasyncio.run(pico_uart.run())
pico_uart.close()
print("bye...")