working with UART and Bytearrays

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
User avatar
EasyRider
Posts: 94
Joined: Wed Dec 30, 2015 8:17 am
Location: Land Down Under

Re: working with UART and Bytearrays

Post by EasyRider » Sun Jan 24, 2016 2:34 am

uart.any returns if any characters are available. If it executes immediately after the write, its possible that your response may not have arrived yet.
Absolutely correct Dave,

By placing a delay(10), uart.any is now executing after the complete response packet is received and solves the initial problem.
My understanding of uart.any was that it would also initiate the start to listen Rx buffer, but it actually needs data in Rx buffer before it tests for uart.any.
If you want to read ulen bytes, then you'll need a loop.
Loop and delay may cause problems or at least poor efficiency as I will be building this in a "State Machine" application where I don't want unnecessary blocking or wasting time in a loop, that's why I have asked if there is a way or setting up a UART read in interrupt routine something similar to callback()?

Regards
John

User avatar
dhylands
Posts: 3009
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: working with UART and Bytearrays

Post by dhylands » Sun Jan 24, 2016 7:25 am

If the UART is opened with a non-zero read_buf_len (the default is 64) then the characters are collected using an IRQ. However there is currently no callback associated with the UART.

The way that I normally deal with this is that I have a "process" routine which is called from the main loop. It checks if characters are available and runs them through a state machine and either calls a packet_received function if a complete packet was detected, or just buffers the characters if the packet is incomplete.

User avatar
EasyRider
Posts: 94
Joined: Wed Dec 30, 2015 8:17 am
Location: Land Down Under

Re: working with UART and Bytearrays

Post by EasyRider » Sun Jan 24, 2016 7:59 am

Thanks Dave,
If the UART is opened with a non-zero read_buf_len (the default is 64) then the characters are collected using an IRQ
OK, this is very important and useful info. on how the IRQ into buffer works, didn't see it in the documentation.
That's exactly how my setup is working at the moment, now I can fine tune the receiving/reading process.
However there is currently no callback associated with the UART.
I hope that this gets implemented down the track, to provide a useful option to polling the buffer for received characters.

Regards
John

donikuy
Posts: 14
Joined: Fri Feb 09, 2018 10:43 am

Re: working with UART and Bytearrays

Post by donikuy » Fri Feb 16, 2018 12:53 pm

Hi,

Is there any examples on UART IRQ? I would like to detect when certain characters are received.

Regards,
donikuy

User avatar
dhylands
Posts: 3009
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: working with UART and Bytearrays

Post by dhylands » Fri Feb 16, 2018 7:39 pm

There is no callback at the python level for the UART IRQ on the pyboard. I normally have my main loop be a polling loop and call the any function http://docs.micropython.org/en/latest/p ... b.UART.any to see if any characters are available to be read and then read the characters one-by-one.

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

Re: working with UART and Bytearrays

Post by pythoncoder » Sat Feb 17, 2018 8:06 am

It's worth considering the uasyncio approach which treats UARTs as stream devices. The following example demonstrates full-duplex concurrent input and output using line-structured data. Test using a loopback (link X1 and X2 on a Pyboard).

Code: Select all

import uasyncio as asyncio
from pyb import UART
uart = UART(4, 9600)

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

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

loop = asyncio.get_event_loop()
loop.create_task(sender())
loop.create_task(receiver())
loop.run_forever()
Peter Hinch

lnsri22
Posts: 53
Joined: Fri Aug 17, 2018 12:16 pm
Location: India

Re: working with UART and Bytearrays

Post by lnsri22 » Fri Jan 25, 2019 2:24 pm

Hi Dave and Peter!!

I am facing this issue of the byte order being changed or the bytearray is partially updated.


I am trying to interface a liquid level sensor that outputs a packet of length 9 bytes every 3 seconds.

'3E' being the start byte of the packet, various bytes represent the temperature and level of liquid along with the crc8 dallas checksum added at the end. Packet will look like '3E01071BBA01450EAB'(AB checksum)

I have tried the below so far with no success.

Code: Select all

idx = 0
bytes_read = 0
while idx < len(self.data):
	#print("Looking for self.data")
	if(self.uart.any()):
		bytes_read = self.uart.readinto(self.mv[idx:])
		print('Got {} bytes of self.data'.format(bytes_read), hexlify(self.data[idx:idx+bytes_read]))
		idx += bytes_read
This always prints

Got 9 bytes of self.data b'ab3e01071bba01450e'

The last byte is always placed at the beginning , it seems

Also the buffer is update partially(specific locations of the buffer is changed with the previous bytes being the native of previous instance of the buffer)

But I cross checked this with a serial terminal (Docklight) in my PC. It looks perfect

What am I missing??

Any help is greatly appreciated

Post Reply