❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Debouncing switches can be a challenge

By: Dan KB6NU
29 March 2024 at 15:31
A photo of the PicoMite Keyer board.
The PicoMite Keyer hardware has five pushbuttons and uses two I/O pins for the dit and dah paddle contacts.

One of the challenges that I faced when I started my Micropython keyer project was debouncing the switch closures. There are seven in all: five pushbuttons and the dit and dah inputs.

So, I did what everybody does nowadaysβ€”perform an internet search. I searched for β€œswitch debouncing with Micropython” and got about a zillion references.

One of the first references is actually part of the Micropython documentation. The documentation suggests that one read the current value of a given pin, wait for the value to change, and then verify that the new value is stable for at least 20 ms. They give the following example code:

import pyb
def wait_pin_change(pin):
    # wait for pin to change value
    # it needs to be stable for a continuous 20ms
    cur_value = pin.value()
    active = 0
    while active < 20:
        if pin.value() != cur_value:
            active += 1
        else:
            active = 0
        pyb.delay(1)

And, here’s how you would use this function:

import pyb
pin_x1 = pyb.Pin('X1', pyb.Pin.IN, pyb.Pin.PULL_DOWN)
while True:
    wait_pin_change(pin_x1)
    pyb.LED(4).toggle()

pyb, by the way, is a library of functions that support the PyBoard, a small microcontroller board that was designed specifically to run MicroPython. Pin is one of the classes in the pyb library that provides I/O pin functions.

More stuff from the internet

This is a simple solution, and really too simple for my project. So, I kept looking and found a bunch more solutions:

  • Jack Ganssle, a long time embedded systems consultant, has published a couple of pages on debouncing on his blog, A Guide to Debouncing, or, How to Debounce a Contact in Two Easy Pages. Being a hardware guy, Ganssle gives a nice explanation of the problem before he goes on to show us his solution.
  • Hack-a-Day has also tackled this issue with two posts, Embed with Elliot: Debounce Your Noisy Buttons, Part I and Part II.

What I ended up using is the asyncio library that was developed for MicroPython. This allows a programmer to implement a form of multi-tasking called β€œcooperative multi-tasking,” which is widely used in embedded systems. It’s more complicated programming this wayβ€”you have to keep in mind all the various things that can be running at the same timeβ€”but there are definite advantages as well.

For example, I think when I get to the point of implementing accepting commands via the USB port, it will be easier to do this. Commands will be arriving asynchronously, after all.

Another advantage to using this library is that it has drivers for switches, pushbuttons, ADCs, and incremental encoders. The switch drivers, for example, include functions that detect both short and long presses. This is a feature that I’m using in this project.

Hardware solution

There is also hardware solutions to debouncing switches. These range from simply soldering a capacitor across the switch to connecting the switch to a Schmitt trigger. Β For more information on these solutions, and how to make the tradeoff between hardware and software solutions, see Ultimate Guide to Switch Debounce by Max Maxfield.

❌
❌