Page 1 of 1

Using uasyncio.Event in an interrupt handler or no go

Posted: Wed Nov 04, 2020 3:14 pm
by ltmerlin
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?

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

Posted: Thu Nov 05, 2020 6:54 am
by pythoncoder
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.

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

Posted: Thu Nov 05, 2020 1:13 pm
by ltmerlin
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.")

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

Posted: Thu Nov 05, 2020 4:25 pm
by kevinkk525
don't forget some await asyncio.sleep(x) in there ;)

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

Posted: Thu Nov 05, 2020 4:29 pm
by ltmerlin
@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)

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

Posted: Fri Nov 06, 2020 7:41 am
by pythoncoder
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.