---
title: MicroPython Button Debounce
date: 2018-11-11T14:31:22+00:00
modified: 2018-11-14T12:15:24+00:00
image:: https://kaspars.net/wp-content/uploads/2018/11/wemos-micropython-button.jpeg
permalink: https://kaspars.net/blog/micropython-button-debounce
post_type: post
author:
  name: Kaspars
  avatar: https://reverse.kaspars.net/gravatar/avatar/92bfcd3a8c3a21a033a6484d32c25a40b113ec6891f674336081513d5c98ef76?s=96&d=mm&r=g
category:
  - Electronics
  - Home Automation
post_tag:
  - ESP8266
  - How to
  - MicroPython
  - Snippet
---

# MicroPython Button Debounce

![Wemos ESP8266 MicroPython Power Consumption](https://kaspars.net/wp-content/uploads/2018/11/wemos-micropython-button.jpeg?strip=all&quality=90&resize=800,534)

Reading and processing button presses with microcontrollers is a lot harder than one could assume because of the [signal noise](https://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-buttons-part-i/) for which we have hardware and software solutions.

I couldn’t find a performant software solution for ESP8266 running MicroPhython ([Wemos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini)) so I came up with an idea of listening for [a pin change interrupt](https://docs.micropython.org/en/latest/library/machine.Pin.html#machine.Pin.irq) and [starting a fixed “one-shot” timer](https://docs.micropython.org/en/latest/library/machine.Timer.html) for 200ms that restarts on every interrupt and triggers the final callback once the timer ends:

```
from machine import Pin, Timer

def on_pressed(timer):
    print('pressed')

def debounce(pin):
    # Start or replace a timer for 200ms, and trigger on_pressed.
    timer.init(mode=Timer.ONE_SHOT, period=200, callback=on_pressed)

# Register a new hardware timer.
timer = Timer(0)

# Setup the button input pin with a pull-up resistor.
button = Pin(0, Pin.IN, Pin.PULL_UP)

# Register an interrupt on rising button input.
button.irq(debounce, Pin.IRQ_RISING)
```

It delays the button press event for 200ms after the last interrupt trigger. There is no way of knowing if you’ve actually released the button so it will most likely trigger another event if the button press lasts for more than 200ms.

Are there better ways of doing this? Please share you ideas in the comments.