I am certain there is a way to solve this problem:
> I have a number of hardware interrupts that are served as follows (only one IRQ displayed for example purposes)
> When a button press is detected I need the function ACT_Now_R() to run
- when it begins running it sets the variable hs_status_r to "Running" such that the IRQ will not call the function if it is already running
- this function takes many minutes to complete
- when the function has completed it sets hs_status_r back to "Ready" such that the IRQ should again be able to trigger the function to run?
--- This is however not happening
--- I fear I am not properly implementing uasyncio
How does one, using uasyncio, call a function to run asap and return immediately, and then also be able to again call that same function, sometime much later, once it has completed running?
- In layman terms, I want the function ACT_Now_R() to run and then "cancel itself" when complete such that can be called again afresh by the IRQ polling which will run continuously.
Perhaps even more useful to the community, and which would answer my question, would be a very simple example of how a single button may be used to start a time consuming function (if not already running) repeatedly on button press.
Code: Select all
########################################################
#### IRQ Handlers ####
def IRQ_handler_tip_right(pin):
global IRQ_flag
global flag_tip_right
print ("Right tip SW pressed...")
IRQ_flag = 1
flag_tip_right = 1
########################################################
########################################################
#### IRQs #####
irq_tip_right.irq(trigger=machine.Pin.IRQ_RISING, handler=IRQ_handler_tip_right)
########################################################
########################################################
#### IRQ polling ####
async def IRQ_poll():
global system_ready
global IRQ_flag
global flag_tip_right
while True:
await asyncio.sleep_ms(100)
if (IRQ_flag == 1) and (system_ready == 1):
if (flag_tip_right == 1) and (hs_status_r == "Ready"):
flag_tip_right = 0
irq_loop = asyncio.get_event_loop()
irq_loop.create_task(ACT_Now_R()) ## Will require update of this function
else:
flag_tip_right = 0
####################
IRQ_flag = 0
########################################################
########################################################
#### Run through initial test sequence #####
## Load settings from file:
loop = asyncio.get_event_loop()
loop.run_until_complete(json_get_settings())
## Attempt connect to Wifi:
loop.run_until_complete(wifi_connect())
## Start persistent loops:
loop.create_task(get_temperatures())
loop.run_until_complete(snooze_ms(1000))
loop.create_task(PID_heater_control())
## Installation sequence:
loop.run_until_complete(test_sequence())
loop.create_task(home_screen())
loop.create_task(IRQ_poll())
## Now run the actual ACT process:
system_ready = 1
loop.run_forever()
EDIT:
> It now seems to work. I changed something small and now the function returns and can be called repeatedly
> I will leave the question up such that perhaps it may be followed by a succinct, simple example of how to handle bulky functions that should be run as async tasks when triggered by IRQ's....