Using uasyncio.Event in an interrupt handler or no go

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ltmerlin
Posts: 39
Joined: Fri Jun 28, 2019 12:34 pm

Using uasyncio.Event in an interrupt handler or no go

Post by ltmerlin » Wed Nov 04, 2020 3:14 pm

For my project I am using a MCP23008 GPIO expander (over I2C). I want to use the MCP23008 interrupt pin that tells me that some pin changed state. Since I am building a uasyncio application I was wondering how to readout this interrupt "event". Can I set an uasyncio.Event in a irq handlert? Or should I just poll the chip interrupt pin manually in a separate uasyncio task?
I heard that uasyncio.Events in interrupt handlers should be avoided. Any advice on this?

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

Re: Using uasyncio.Event in an interrupt handler or no go

Post by pythoncoder » Thu Nov 05, 2020 6:54 am

Currently this is not supported and will probably lead to crashes. It is intended that events can be triggered from soft ISR's (or micropython.schedule) but this has not yet been implemented.

My Message class can be triggered from a hard or soft ISR and uses similar syntax to Event, but it is just syntactic sugar over polling - see the code.

So the short answer is currently to use polling. This isn't as bad as it sounds. See polling vs interrupts.
Peter Hinch
Index to my micropython libraries.

ltmerlin
Posts: 39
Joined: Fri Jun 28, 2019 12:34 pm

Re: Using uasyncio.Event in an interrupt handler or no go

Post by ltmerlin » Thu Nov 05, 2020 1:13 pm

OK thanks for the information, Peter. Since I am working on an ESP32, polling it is.

So a simple asyncio polling task works:

Code: Select all

async def poll():
    while True:
        if MCP.read_pin():
            print("Pin changed state.")

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: Using uasyncio.Event in an interrupt handler or no go

Post by kevinkk525 » Thu Nov 05, 2020 4:25 pm

don't forget some await asyncio.sleep(x) in there ;)
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

ltmerlin
Posts: 39
Joined: Fri Jun 28, 2019 12:34 pm

Re: Using uasyncio.Event in an interrupt handler or no go

Post by ltmerlin » Thu Nov 05, 2020 4:29 pm

@kevinkk525 indeed! Thanks for correcting the example snippet. It should be something like this:

Code: Select all

async def poll():
    while True:
        if MCP.read_pin():
            print("Pin changed state.")
        await uasyncio.sleep_ms(10)

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

Re: Using uasyncio.Event in an interrupt handler or no go

Post by pythoncoder » Fri Nov 06, 2020 7:41 am

Indeed. For the quickest possible polling it is entirely valid to have sleep_ms(0). If multiple tasks do this, they will be scheduled in "fair round robin" fashion.
Peter Hinch
Index to my micropython libraries.

Post Reply