Skip to content

Instantly share code, notes, and snippets.

@SpotlightKid
Last active January 23, 2023 17:51
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save SpotlightKid/0a0aac56606286a80f860b116423c94f to your computer and use it in GitHub Desktop.
Save SpotlightKid/0a0aac56606286a80f860b116423c94f to your computer and use it in GitHub Desktop.
Debounced switch using pin and timer IRQs on MicroPython
#
# inspired by: https://forum.micropython.org/viewtopic.php?t=1938#p10931
#
import micropython
try:
from machine import Timer
timer_init = lambda t, p, cb: t.init(period=p, callback=cb)
except ImportError:
from pyb import Timer
timer_init = lambda t, p, cb: t.init(freq=1000 // p, callback=cb)
# uncomment when debugging callback problems
#micropython.alloc_emergency_exception_buf(100)
class DebouncedSwitch:
def __init__(self, sw, cb, arg=None, delay=50, tid=4):
self.sw = sw
# Create references to bound methods beforehand
# http://docs.micropython.org/en/latest/pyboard/library/micropython.html#micropython.schedule
self._sw_cb = self.sw_cb
self._tim_cb = self.tim_cb
self._set_cb = getattr(self.sw, 'callback', None) or self.sw.irq
self.delay = delay
self.tim = Timer(tid)
self.callback(cb, arg)
def sw_cb(self, pin=None):
self._set_cb(None)
timer_init(self.tim, self.delay, self._tim_cb)
def tim_cb(self, tim):
tim.deinit()
if self.sw():
micropython.schedule(self.cb, self.arg)
self._set_cb(self._sw_cb if self.cb else None)
def callback(self, cb, arg=None):
self.tim.deinit()
self.cb = cb
self.arg = arg
self._set_cb(self._sw_cb if cb else None)
def test_pyb(ledno=1):
import pyb
sw = pyb.Switch()
led = pyb.LED(ledno)
return DebouncedSwitch(sw, lambda l: l.toggle(), led)
def test_machine(swpin=2, ledpin=16):
from machine import Pin
sw = Pin(swpin, Pin.IN)
led = Pin(ledpin, Pin.OUT)
return DebouncedSwitch(sw, lambda l: l.value(not l.value()), led)
@adamoell
Copy link

adamoell commented Oct 2, 2021

Ah, that's fantastic Christopher. I'll copy & paste that into the header :-)

@edwinm
Copy link

edwinm commented Aug 8, 2022

This is the best Micropython debounce code I could find. Others are using delays inside IRQ’s (wrong) or calling the callbacks directly, without using schedule (wrong). Thank for sharing! Maybe, one day, it will have its own repo with documentation and demo code 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment