Timers and/or uasyncio

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Timers and/or uasyncio

Post by mathieu » Thu Dec 17, 2020 3:38 pm

I have prior experience with pyboard Timers and I'm currently learning my way around the uasyncio library. Are there general recommendations as to how these two things work well (or not) together?

For example, suppose I wanted to repeatedly write to a UART device, wait for a fixed delay and read from that device, and repeat this sequence indefinitely at a given frequency. I guess I could just write an infinite loop and avoid Timer() altogether:

Code: Select all

async def readfoo():
	while True:
		uart.write('foo'.encode())
		await uasyncio.sleep(0.1)
		print('foo = ' + uart.read().decode())
		await uasyncio.sleep(0.9)

uasyncio.run(readfoo())
But I could also create a single-iteration version of the above function, and schedule it to run at a given frequency using pyb.Timer.callback(). At this point it's not obvious to me what is the "best" way to proceed, or at least what are the drawbacks and benefits of each approach.

Does anyone have advice/caveats/words of wisdom to share on this topic? I've been reading up on uasyncio but I'm just getting started, so forgive me if there is an obvious tutorial I managed to miss.

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

Re: Timers and/or uasyncio

Post by pythoncoder » Thu Dec 17, 2020 6:34 pm

The way to use UARTS with uasyncio is via the stream mechanism.
Peter Hinch
Index to my micropython libraries.

User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Re: Timers and/or uasyncio

Post by mathieu » Fri Dec 18, 2020 1:48 pm

Thanks Peter for pointing me to that. I'm trying to make this work but my UART device (MKS 910 pressure/vacuum gauge) seems to communicate without ever using newlines: all communications are of the form "@254_;FF", with the underscore replaced with the actual content of the message. I tried calling uasyncio.StreamReader.readuntil(';FF') but it looks like the readuntil method is not implemented. Am I missing something obvious?

Getting back to my original question, I will need the pyboard to handle various recurring tasks (temperature readings from SPI, some kind of PID control...), and I'm still wondering whether attempting to mix Timers and uasyncio is an obviously bad/fragile/challenging approach. Would you say that implementing everything using uasyncio exclusively is a natural way to go?

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

Re: Timers and/or uasyncio

Post by pythoncoder » Fri Dec 18, 2020 6:22 pm

If all messages are the same length you could look at readexactly. As you say, readuntil isn't implemented which is a pity. There are hazards with the readexactly approach: you need to ensure will initially synchronise and stay that way.

In general my view is that it's best to reserve interrupts and timers for situations where they are necessary. If you can meet your timing constraints with uasyncio that is the simplest approach. I don't know how familiar you are with asynchronous coding, but my tutorial has this section as an attempt to clear up some of the confusion on this topic.
Peter Hinch
Index to my micropython libraries.

User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Re: Timers and/or uasyncio

Post by mathieu » Fri Dec 18, 2020 9:28 pm

Thanks again Peter. I only very recently started to experiment with at asynchronous coding, so this is helpful. I'll be trying to implement all I need without timers, if only as a learning experience.

In case anybody is interested, I'm a stable isotope geochemist and this project aims to design from the ground up all the control hardware and software for an automated CO2 sample preparation line, where we trap and release very small amounts of gas in cryogenic traps cooled by liquid nitrogen. The system will continuously monitor up to 4 vacuum gauges and 4 temperature sensors, open and close various valves, drive a stepper motor, and communicate with a Raspberry Pi running a GUI based on pyglets. Everything (hardware and software) will be fully documented in a git repo, and I'll be sure to acknowledge the helpul (and patient) folks here at micropython.org whenever I publish the first scientific results out of this prep line.

Divergentti
Posts: 67
Joined: Fri Sep 04, 2020 9:27 am
Location: Hanko, Finland
Contact:

Re: Timers and/or uasyncio

Post by Divergentti » Sat Dec 19, 2020 12:03 pm

mathieu wrote:
Fri Dec 18, 2020 9:28 pm
Thanks again Peter. I only very recently started to experiment with at asynchronous coding, so this is helpful. I'll be trying to implement all I need without timers, if only as a learning experience.

In case anybody is interested, I'm a stable isotope geochemist and this project aims to design from the ground up all the control hardware and software for an automated CO2 sample preparation line, where we trap and release very small amounts of gas in cryogenic traps cooled by liquid nitrogen. The system will continuously monitor up to 4 vacuum gauges and 4 temperature sensors, open and close various valves, drive a stepper motor, and communicate with a Raspberry Pi running a GUI based on pyglets. Everything (hardware and software) will be fully documented in a git repo, and I'll be sure to acknowledge the helpul (and patient) folks here at micropython.org whenever I publish the first scientific results out of this prep line.
I am newbie programmer (started June this year) and I am interested to see what type of CO2 etc sensors you are using and how you implement asyncio and/or timing.

Currently I am testing MH-Z19 CO2 sensor and wait parts for my solarpanel system (rotates solarapanel towards the sun). Later I will add particle sensors etc.

My GitHub is here https://github.com/divergentti/airquali ... main/esp32 if you like to check it, but as mentioned, my code is not professional at all.

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

Re: Timers and/or uasyncio

Post by pythoncoder » Sat Dec 19, 2020 6:12 pm

mathieu wrote:
Fri Dec 18, 2020 9:28 pm
... I only very recently started to experiment with at asynchronous coding, so this is helpful. I'll be trying to implement all I need without timers, if only as a learning experience...
To explain the reasoning, cooperative schedulers have the great advantage that they are deterministic. This simplifies debugging. As soon as you introduce interrupts you have to consider the possibility that any piece of code may be pre-empted by an interrupt handler. For example a variable might suddenly change between one line of code and the next. This is covered here. Further, writing interrupt handlers needs care: see the official docs.

Interrupts are actually a wonderful feature of MicroPython, and on suitable hardware like a Pyboard can provide microsecond level response times. But an application which only needs to respond to an event in (say) 100ms has no need for them. If you're running a cooperative scheduler this section explains further why you may not need interrupts.
Peter Hinch
Index to my micropython libraries.

dukeduck
Posts: 22
Joined: Thu Aug 29, 2019 2:06 pm

Re: Timers and/or uasyncio

Post by dukeduck » Fri Jan 15, 2021 12:59 pm

Hi Peter,

I have a similar question. In my case, I need to sample at 100us interval with pyboard's ADC - what's the recommended way to have it work with my other codes using uasyncio?

Thanks in advance!

pythoncoder wrote:
Sat Dec 19, 2020 6:12 pm
mathieu wrote:
Fri Dec 18, 2020 9:28 pm
... I only very recently started to experiment with at asynchronous coding, so this is helpful. I'll be trying to implement all I need without timers, if only as a learning experience...
To explain the reasoning, cooperative schedulers have the great advantage that they are deterministic. This simplifies debugging. As soon as you introduce interrupts you have to consider the possibility that any piece of code may be pre-empted by an interrupt handler. For example a variable might suddenly change between one line of code and the next. This is covered here. Further, writing interrupt handlers needs care: see the official docs.

Interrupts are actually a wonderful feature of MicroPython, and on suitable hardware like a Pyboard can provide microsecond level response times. But an application which only needs to respond to an event in (say) 100ms has no need for them. If you're running a cooperative scheduler this section explains further why you may not need interrupts.

Post Reply