IRQ and re-setting the flag issue

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

IRQ and re-setting the flag issue

Post by davef » Wed May 11, 2022 8:12 pm

Running this code:

Code: Select all

from machine import Pin
import utime


radar_interrupt = False

def handle_interrupt(xyz): #  needs something
    global radar_interrupt

    radar_interrupt = True

pir = Pin(18, Pin.IN, Pin.PULL_UP)
pir.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)

#  main loop
while True:
    radar_interrupt = False #  1st one works

    while True:
        if (radar_interrupt == True):
            break

#    radar_interrupt = False #  2nd doesn't work

    print ('got got an interrupt')
    utime.sleep(1)
I only get one interrupt. If I reduce the last statement down to utime.sleep(.05) I know I will get further interrupts due to contact bounce.

However, if I comment out the 1st radar_interrupt = False and put in the 2nd one I get two interrupts. It seems even though I have broken out of the test loop for interrupts that radar_interrupt has not been made False and that I have to wait at least 0.1 seconds before it is reset..

Can someone identify my knowledge gap?

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

Re: IRQ and re-setting the flag issue

Post by pythoncoder » Thu May 12, 2022 10:57 am

After you get the interrupt you need to wait out the contact bounce before clearing down the flag

Code: Select all

while True:
    while not radar_interrupt:  # Wait for an interrupt
        pass
    utime.sleep_ms(200)  # Wait out contact bounce
    radar_interrupt = False
    print ('got got an interrupt')
The 200ms delay could be made shorter. Note that unless you are going to do something else while waiting for the interrupt, there is no reason to actually use an interrupt:

Code: Select all

while True:
    while not pin():  # Wait for pin to go high
        pass
    utime.sleep_ms(200)  # Wait out contact bounce
    while pin():  # Wait for pin to go low
        pass
    utime.sleep_ms(200)  # Wait out contact bounce
    print ('got got a low level')
The "grown up" way to do this sort of thing is to use uasyncio. See this reference.
Peter Hinch
Index to my micropython libraries.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: IRQ and re-setting the flag issue

Post by davef » Thu May 12, 2022 8:54 pm

I wrongly assumed that when one broke out of the while loop then any further interrupts would not be processed :(

Both projects where I use interrupts could be done with a pin-change as you suggest. I don't need to be doing anything else while I process whatever "changed".

After several uasyncio suggestions I did play with some code examples. When I need to have a "heartbeat" LED flashing while I am doing something else then I will incorporate uasyncio in my code.

Thanks for taking the time to explain and the two examples.

Post Reply