IRQ debounce

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
newb
Posts: 43
Joined: Wed Jan 10, 2018 8:19 pm
Location: Bulgaria

IRQ debounce

Post by newb » Sat May 29, 2021 7:02 am

Hi,

I have a rainfall sensor which I've hooked to a Raspberry Pi Pico. My testing code is the following:

Code: Select all

from machine import Pin, disable_irq, enable_irq
import utime

rain_count=0
rain_sensor=Pin(7, Pin.IN, Pin.PULL_UP)

def a(p):
    global rain_count
    state=disable_irq()
    utime.sleep_ms(50)
    if p.value():
        rain_count+=1
    enable_irq(state)

rain_sensor.irq(handler=a,trigger=Pin.IRQ_FALLING)

while True:
    print(rain_count)
    utime.sleep(0.1)
I read in older topics, that in order to get the debounce working I need to disable the IRQ, read the pin state and then re-renable it. However my code hangs and IRQ is not re-enabled. Any ideas why?

newb
Posts: 43
Joined: Wed Jan 10, 2018 8:19 pm
Location: Bulgaria

Re: IRQ debounce

Post by newb » Sat May 29, 2021 7:50 am

I think I solved the problem with the following code

Code: Select all

from machine import Pin,Timer
import utime

rain_count=0
rain_sensor=Pin(7,Pin.IN, Pin.PULL_UP)

timer = Timer()

def tipped(timer):
    global rain_count
    rain_count+=1

def debounce(pin):
    timer.init(mode=Timer.ONE_SHOT, period=200, callback=tipped)

rain_sensor.irq(handler=debounce,trigger=Pin.IRQ_FALLING)

while True:
    print(rain_count)
    utime.sleep(0.1)

Credit to this post: https://kaspars.net/blog/micropython-button-debounce

Jackli
Posts: 80
Joined: Thu Apr 29, 2021 9:11 am

Re: IRQ debounce

Post by Jackli » Tue Jun 01, 2021 7:53 am

Thanks for sharing, it always helps some people who also have the same problem.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: IRQ debounce

Post by dhylands » Tue Jun 01, 2021 4:37 pm

newb wrote:
Sat May 29, 2021 7:50 am
I think I solved the problem with the following code

Code: Select all

from machine import Pin,Timer
import utime

rain_count=0
rain_sensor=Pin(7,Pin.IN, Pin.PULL_UP)

timer = Timer()

def tipped(timer):
    global rain_count
    rain_count+=1

def debounce(pin):
    timer.init(mode=Timer.ONE_SHOT, period=200, callback=tipped)

rain_sensor.irq(handler=debounce,trigger=Pin.IRQ_FALLING)

while True:
    print(rain_count)
    utime.sleep(0.1)

Credit to this post: https://kaspars.net/blog/micropython-button-debounce
There is a subtle problem that I would personally address here. When the debounce handler is called, it should disable interrupts for the sensor pin, and then the tipped callback should re-enable them. Otherwise you wind up re-initializing the timer for each edge that you're trying to debounce.

I think that you can disable the interrupt by doing: rain_sensor.irq(handler=None)

Post Reply