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.
EasyRider
Posts: 94
Joined: Wed Dec 30, 2015 8:17 am

Re: working with UART and Bytearrays

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

x
Last edited by EasyRider on Wed Mar 13, 2019 12:56 pm, edited 1 time in total.

User avatar
dhylands
Posts: 3821
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.

EasyRider
Posts: 94
Joined: Wed Dec 30, 2015 8:17 am

Re: working with UART and Bytearrays

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

x
Last edited by EasyRider on Wed Mar 13, 2019 12:56 pm, edited 1 time in total.

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: 3821
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: 5956
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
Index to my micropython libraries.

lnsri22
Posts: 75
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
lnsri22 :)

kurtsvl
Posts: 1
Joined: Sun Oct 14, 2018 7:00 am

Re: working with UART and Bytearrays

Post by kurtsvl » Tue Mar 12, 2019 4:05 pm

In micropython 1.10 UART.any() not works.

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

Re: working with UART and Bytearrays

Post by dhylands » Tue Mar 12, 2019 10:10 pm

Are you sure that the AB isn't from the previous packet?

If the sender sent most of the packet followed by a slight pause and then sent the AB, you could be picking things in a seeming incorrect order.

The sensor has no idea when you're reading the data, so if your code happened to start mid-packet then this would occur.

Normally, most packets have some type of start byte which is used to synchronize things. When you first start, you generally wind up throwing away characters until you get to a packet boundary. I always write my packet parsers to deal with one character at a time.

User avatar
ta1db
Posts: 53
Joined: Mon Sep 02, 2019 12:05 pm
Contact:

Re: working with UART and Bytearrays

Post by ta1db » Mon Sep 30, 2019 1:49 pm

pythoncoder wrote:
Sat Feb 17, 2018 8:06 am
Test using a loopback (link X1 and X2 on a Pyboard).
Worked flawlessly on Nucleo_F401RE as well with a single modification UART 4 -> 6 and with link PC6 to PC7 accordingly.

Code: Select all

import uasyncio as asyncio
-  uart = UART(4, 9600)
+ uart = UART(6, 9600) #or any other valid baudrate
Thank you very much.

Post Reply