implementation of interrupt : ISR-Handler-Asyncio...

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
User avatar
thierryp
Posts: 12
Joined: Mon Jan 31, 2022 5:55 pm
Location: Paris - France

implementation of interrupt : ISR-Handler-Asyncio...

Post by thierryp » Wed Feb 02, 2022 1:46 pm

Hello,
In this micropython tuto ==> MicroPython: WS2812B Addressable RGB LEDs with ESP32 and ESP8266:
https://randomnerdtutorials.com/micropy ... 2-esp8266/

At the middle of tuto in the part ==> WS2812B RGB LEDs with MicroPython: Project example
They build a simple circuit with 4 pushbutton to make different lighting effects.
They create an interrupt handling function that will run every time an interrupt happens – in this case, the button_handler() function.

Code: Select all

def button_handler(pin):
  global button_pressed
  button_pressed = pin
Then :

Code: Select all

button1 = Pin(15, Pin.IN)
button1.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button2 = Pin(14, Pin.IN)
button2.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button3 = Pin(12, Pin.IN)
button3.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button4 = Pin(13, Pin.IN)
button4.irq(trigger=Pin.IRQ_RISING, handler=button_handler)

But when you press the pushbutton to select an effect, it will only start when the effect that is running stops.
I tought that an hardware interrupt code should be interrupt but not and if you have long lighting effects ==> We wait : it's a problem.

My question is : what is the best way to control the push button (to interrupt the running interrupt task)
  • ISR interrupt Handler
    Asyncio
    A mix of two
    or others...
Thanks,

Thierry.

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by OlivierLenoir » Wed Feb 02, 2022 4:17 pm

I've recently read this, it's about writing interrupt handlers with micropython.schedule.

User avatar
thierryp
Posts: 12
Joined: Mon Jan 31, 2022 5:55 pm
Location: Paris - France

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by thierryp » Thu Feb 03, 2022 1:55 pm

Hello Olivier,

Thanks for this answer, I'm going to read that.

But since my question i have seen that :
viewtopic.php?f=15&t=11887&p=64751&hili ... upt#p64751
Re: uasyncio run cancel tasks interrupt
Post by pythoncoder » Fri Jan 28, 2022 5:02 pm
It is usually a bad idea to use interrupts for pushbutton inputs. Creating and cancelling tasks in an interrupt handler is very likely to cause problems. There is also the problem of contact bounce.

Thierry.

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

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by pythoncoder » Fri Feb 04, 2022 11:33 am

Please see this doc which covers the issues relating to interrupts and uasyncio.
Peter Hinch
Index to my micropython libraries.

User avatar
thierryp
Posts: 12
Joined: Mon Jan 31, 2022 5:55 pm
Location: Paris - France

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by thierryp » Fri Feb 04, 2022 9:52 pm

Hello Peter,

Thanks for your answer.

Thierry.

User avatar
thierryp
Posts: 12
Joined: Mon Jan 31, 2022 5:55 pm
Location: Paris - France

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by thierryp » Tue Feb 08, 2022 6:56 pm

Hello Peter,

I have read your tuto.
I have seen the interest to use Asyncio and the use of primitives.pushbutton (Pushbutton class) in my case.
If you have many task at the same time no problem to my understanding.

But in my case i run just one task sequentially by button.
You can declare the buttons for example:

Code: Select all

    pb1 = Pushbutton(pin1)
    pb1.press_func(func1, (var1,))
    pb2 = Pushbutton(pin2)
    pb2.press_func(func2, (var2,))
    pb3 = Pushbutton(pin2)
    pb3.press_func(func3, (var3,))
    ...
But if a task (funcx) is running I don't see how to implement code to cancel this task when an other button is press?

Regard,

Thierry.

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

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by pythoncoder » Tue Feb 08, 2022 7:16 pm

The press functions can be uasyncio tasks. One way to stop them is to use Event objects:

Code: Select all

my_event = uasyncio.Event
async def foo(evt):
    while not evt.is_set():
        print('foo')
        await asyncio.sleep(1)
    evt.clear()
pb3.press_func(foo, (my_event,))
The function or task that wants to stop foo() issues evt.set().
Peter Hinch
Index to my micropython libraries.

User avatar
thierryp
Posts: 12
Joined: Mon Jan 31, 2022 5:55 pm
Location: Paris - France

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by thierryp » Thu Feb 10, 2022 5:36 pm

Hello Peter,

Thanks for your reply,
I understood that the task that wants to stop foo() must issue an evt.set()

Code: Select all

my_event = uasyncio.Event
async def foo(evt):
    while not evt.is_set():
        print('foo')
        await asyncio.sleep(1)
    evt.clear()
pb3.press_func(foo, (my_event,))
But sorry i'am new to coding in python.
If you have three buttons for example I repeat your code above for button1 and button 2 (with different events and foo() tasks).
But how to write code to stop task foo() when i press button 1 or 2 (and possibly button 3) then start corresponding task button?

When you start the code we wait an action (push button) then you push a button and run the corresponding task button.
Finally each push button must stop (abort/cancel) the running task and after run his own task (and re run his own task (even if it's the same button)) and so on.


Thierry.

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

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by pythoncoder » Fri Feb 11, 2022 12:12 pm

Perhaps this doc might help. It explains keeping a reference to the currently running task so that any other task can cancel it.
Peter Hinch
Index to my micropython libraries.

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

Re: implementation of interrupt : ISR-Handler-Asyncio...

Post by pythoncoder » Fri Feb 11, 2022 5:09 pm

If I understand what you're trying to do, I think you need something like this

Code: Select all

import uasyncio as asyncio
from primitives.pushbutton import Pushbutton

task = None  # Reference to currently running task
pb1 = Pushbutton(pin1)
pb1.press_func(start, (func1, var1,))
pb2 = Pushbutton(pin2)
pb2.press_func(start, (func2, var2,))
pb3 = Pushbutton(pin2)
pb3.press_func(start, (func3, var3,))

async def start(func, var):
    global task
    if task is not None:
    	task.cancel()
    	await asyncio.sleep_ms(0)  # Allow cancellation to occur
    task = asyncio.create_task(func, var)

async def func1(var):
    # code omitted. Define func2 and func3 similarly.
Peter Hinch
Index to my micropython libraries.

Post Reply