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.