Blog Devices and technologies

How to Implement Button Debouncing in MicroPython: Real-World Methods

business

Button debouncing is a common problem faced by electronics developers. When a mechanical button is pressed, the contact inside it can repeatedly close and open within the first few milliseconds. As a result, a single press can be mistakenly interpreted as multiple presses. There are several real and proven ways to eliminate this problem for the MicroPython platform.

Why is it important to suppress debouncing?

Without debouncing, the microcontroller may respond to false triggers. For example, a single button press may cause the device to run a function several times in a row, which is critical when controlling relays, LEDs, motors, interfaces, etc.
Basic methods of debouncing in MicroPython

  1. Software filtering with delay (polling)

This is the simplest method: the microcontroller regularly polls the button status with a short delay (usually 10–50 milliseconds). If the status is stable during this time, it is considered reliable. This method is widely used in educational projects and when controlling LEDs and displays.

Pros:

  • Easy to implement;
  • Does not require additional libraries.

Cons:

  • Delays can interfere with other parts of the program;
  • Not always effective at high speeds.
  1. Using interrupts with software delays

This method is more advanced. When the button is pressed, an interrupt is generated, but the event is only processed after a software delay—when the signal stabilizes. This method is considered reliable and is used in most professional developments on ESP32, Raspberry Pi Pico, and other platforms with MicroPython.

Pros:

  • Instant response to pressing;
  • High reliability;
  • Does not block the main program cycle.

Cons:

  • Requires careful configuration;
  • Requires understanding of how interrupts work.
  1. Using system time

This method uses the microcontroller’s internal time measurement function. Each time the button is pressed, a time stamp is saved, and subsequent presses are ignored if too little time has elapsed between them (less than 50 milliseconds, for example). This is a simple and effective method that does not require the use of timers.

Pros:

  • No additional components required;
  • Effectively filters out debounce.

Cons:

  • Time intervals must be taken into account manually;
  • Not suitable for all scenarios.
  1. Asynchronous processing using uasyncio

If your project uses asynchronous logic (e.g., Wi-Fi control or I2C/SPI interfaces), you can implement debouncing using the uasyncio library. This approach is especially good when working with multiple buttons and complex scenarios, such as button hold, double click, short/long press.

Pros:

  • High flexibility;
  • Support for complex interactions;
  • Suitable for scalable projects.

Cons:

  • Requires knowledge of asynchronous programming;
  • Complicates the project structure.

What developers recommend

On the Raspberry Pi and ESP8266.ru forums and in GitHub repositories, users most often use the second method — interrupts with a timer delay. It provides a balance between response speed and reliability. There are also many open libraries that implement this method.

In professional projects, uasyncio is increasingly being used, especially on ESP32, which has resources for asynchronous multitasking.

Conclusion

Debouncing is a mandatory step when working with physical buttons. MicroPython offers both simple and advanced solutions:

  • Software delay is suitable for beginners.
  • For reliable and responsive systems, use timer interrupts.
  • For complex interactive interfaces, use asynchronous processing with uasyncio.

The choice of approach depends on the project tasks, controller resources, and the developer’s level of experience.