How to use non blocking functions, asynchronous tasks

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
dexterlabora
Posts: 3
Joined: Tue Jan 10, 2017 3:10 pm

How to use non blocking functions, asynchronous tasks

Post by dexterlabora » Tue Jan 10, 2017 3:25 pm

What's the easiest way to run a function as a non blocking task?

I'm used to writing in JavaScript where you can easily have long or infinite tasks running in the background or that can be triggered by event handlers.

```
setTimeout( function(){
console.log("my super long task");
}, 10000);
console.log("end of file");

results:
end of file
my super long task
```


Goal:
Run a simple web server to accept a command (this is an infinite loop, waiting on clients to connect).
Each command starts an infinite loop for an LED display routine (there are multiple LED displays).
I have several routines that can run simultaneously.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: How to use non blocking functions, asynchronous tasks

Post by deshipu » Tue Jan 10, 2017 9:34 pm

You might be interested in this thread just next to yours: http://forum.micropython.org/viewtopic.php?f=2&t=2837

dexterlabora
Posts: 3
Joined: Tue Jan 10, 2017 3:10 pm

Re: How to use non blocking functions, asynchronous tasks

Post by dexterlabora » Wed Jan 11, 2017 10:17 am

Thanks for the feedback. I looked at this, but it appears I have to install a third party library on my ESP8266 (WeMos D1), but the instructions were a little vague.

I also found this blog post, which uses the "threading" library. This sounds exactly like what I need, but it doesn't appear to be available on the ESP8266 version of micropython either.
https://www.pycom.io/qa-micropython-mul ... collector/

I thought this first project was just going to be a "Hello World" to run an infinite LED display loop, but still allow an HTTP interface to change the pattern. Its now become a journey to do this :/

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

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Wed Jan 11, 2017 4:13 pm

The uasyncio library is not a third party library: it's part of the official MicroPython library https://github.com/micropython/micropython-lib. Further asyncio is the standard Python way to achieve cooperative multi-tasking - uasyncio is a subset designed for MicroPython on microcontrollers. It has some enhancements to facilitate millisecond-level scheduling.

The _thread library supports pre-emptive multi tasking and is much more resource intensive. As I understand it the ESP8266 doesn't support it.

On a device as constrained as the ESP8266 uasyncio is the way to proceed.
Peter Hinch
Index to my micropython libraries.

dexterlabora
Posts: 3
Joined: Tue Jan 10, 2017 3:10 pm

Re: How to use non blocking functions, asynchronous tasks

Post by dexterlabora » Wed Jan 11, 2017 4:46 pm

Thanks for the detailed response, very appreciated.

Sadly, when I try to import this library, its not available.

MicroPython v1.8.7-7-gb5a1a20a3 on 2017-01-09; ESP module with ESP8266
Type "help()" for more information.
>>> import uasyncio
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: no module named 'uasyncio'
>>>

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

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Thu Jan 12, 2017 11:25 am

The README in the link to the MicroPython library tells you how to install it.
Peter Hinch
Index to my micropython libraries.

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Sat Dec 30, 2017 6:30 am

@pythoncoder,

Perhaps I could use your experience and knowledge. How can I simultaneously run two loops using uasyncio, something similar to _thread?
Example with _thread:
import _thread as th
def loop1():
while True:
#do something

def loop2():
while True:
#do something else

th.start_new_thread(loop1, ())
th.start_new_thread(loop2, ())
This works fine on pyboard, however there is no support for _thread on ESP8266. Please note that in the project I'm working on, the second loop, loop2 is using socket to check whether there is a connection to the server running on ESP8266

Thanks for your help.

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

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Sat Dec 30, 2017 7:48 am

I suggest you look at the unofficial uasyncio tutorial here. You'll find example code, including aledflash.py. This is a very simple Pyboard demo which runs four copies of a coroutine to flash the four onboard LED's asynchronously.
Peter Hinch
Index to my micropython libraries.

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Sat Dec 30, 2017 1:27 pm

Thanks for your suggestion. I'm digging into it.

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Sat Dec 30, 2017 3:45 pm

I have become familiar with cooperative multitasking using uasyncio library after digging into the example you posted for reference. However, I can't still achieve the desired goal. I'm using socket.socket object awaiting for a connection to happen and from what i read, its functions are blocking functions. Any suggestion will be appreciated

Post Reply