Python properties ...

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
kif
Posts: 3
Joined: Fri Apr 13, 2018 7:13 am

Python properties ...

Post by kif » Fri Apr 13, 2018 7:27 am

Dear all,

I am pretty new to MicroPython (but I write Python code for a couple of decades) and my code locks on something pretty simple. I may be missing something stupid:

There are two devices connected via serial lines to an ESP32 board running micropython. The code lock in this loop waiting for initialization.
sds.last_value and gps.position are actual attributes of their respective classes. gps.date is a property (formatting the date). Whenever I interrupt the loop, all devices look properly initialized. Is there an caching of properties ?

'''
def wait_data():
print("Wait for data to come from the GPS and from the SDS")
while True:
time.sleep_ms(10)
update_all()
if (sds.last_value is not None) and (gps.position != NO_POSITION) and (gps.date != "2000-00-00"):
print("GPS and SDS initialized")
break
'''

The complete code is https://github.com/kif/dustair/blob/mas ... 32/main.py

Any comment are welcome.

Cheers,
Jerome

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

Re: Python properties ...

Post by pythoncoder » Sat Apr 14, 2018 11:29 am

I have used MicroPython properties in device drivers and found them to work as expected.
Peter Hinch

kif
Posts: 3
Joined: Fri Apr 13, 2018 7:13 am

Re: Python properties ... and serial lines management

Post by kif » Tue Apr 17, 2018 12:36 pm

Thanks, I checked and apparently it works.

The bugs are rather in the serial-lines interfaces. One of the device is sending short datagrams (10 bytes) and I got it working reliably.
The second is a GPS module sending NMEA strings which can be pretty long (~80 bytes). About 80% of the datagrams are not read properly (checksum errors mainly).

There are two ways I see to read those lines:
* read byte by byte, but it is likely to be slow and will be polling all the time on the UART line.
* use the "readinto buffer" method from the serial line and re-build the datagram asynchronously.

Is there any preferred way to accessing those datagram ?
I use the second and it could be related to the amount of bad datagrams
Can I increase the buffer size on the UART port to capture more in one go ? (the device is an ESP32)

Thanks for your ideas
Jerome

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

Re: Python properties ...

Post by pythoncoder » Wed Apr 18, 2018 8:29 am

The uart.readinto method with a suitable size buffer is one solution.

The approach I would adopt is to use uasyncio as per this example. This performs concurrent I/O via a loopback - clearly you could discard the sender.

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()
A tutorial on uasyncio may be found here.

You might also be interested in micropyGPS.
Peter Hinch

kif
Posts: 3
Joined: Fri Apr 13, 2018 7:13 am

Re: Python properties ...

Post by kif » Fri Apr 20, 2018 6:17 pm

Thank you Peter,

I am already using micropyGPS. It helps a lot.
I will dig into asyncio, I never used it on Python and will investigate there before switching to micropython.

Cheers,

Jerome

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

Re: Python properties ...

Post by pythoncoder » Sat Apr 21, 2018 7:33 am

kif wrote:
Fri Apr 20, 2018 6:17 pm
...I will dig into asyncio, I never used it on Python and will investigate there before switching to micropython...
For learning most Python modules that is the approach I would recommend.

Alas Python's asyncio library has changed substantially over the years. Despite experience with cooperative multi-tasking I found asyncio quite confusing. As it developed different ways of declaring coroutines emerged. Concepts such as Futures only appeared in later versions. Consequently tutorials use different coding methodologies depending on when they were written. As an asyncio newbie every tutorial seems to accomplish the same thing in different ways. Further, uasyncio is a subset of asyncio. Futures are unsupported and the Task name represents a function rather than a class. So if you did thoroughly learn asyncio you'd then need to unlearn a few concepts...

Which is why I wrote the tutorial referenced above. This aims to describe a single, consistent, way of writing uasyncio code and describes only features supported in the uasyncio subset.

By all means try asyncio on CPython. But if you find confusion setting in (and I appreciate this sounds like blowing my own trumpet) you might find it simpler to use my tutorial. The code samples can be run on the Unix version of MicroPython or on CPython version 3.5 or newer.
Peter Hinch

Post Reply