Normal view
Debouncing switches can be a challenge
![A photo of the PicoMite Keyer board.](../themes/icons/grey.gif)
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.