So… I’ve been doing a little more work on the multi-threading library I blogged about earlier, and I decided that it would be a good idea to add some interrupt-like functionality to handle switches. Thus, the
SwitchInput class was born. This class has several nice features that make working with switches easier.
Wiring Switches to the Arduino
The simplest and easiest way to connect a switch is to just wire a dry contact switch directly from the input pin to the ground pin taking advantage of the Arduino’s internal 20k pull up resistor. That way, when the switch is open, the input will read
HIGH, and when it’s closed, the input will read
LOW (although, this is a little counter-intuitive for most people).
NOTE: Pull-up resistors usually don’t work well for pin 13 because of the built-in LED (see below).
The next way is to supply your own pull-up resistor by wiring the switch the same way, but also running a resistor between the 5V power output pin and the input pin. I’m not sure why anyone would choose this option over the former, but you could if you really wanted to. The logic for reading this switch would be the same as in the previous case.
The last way is to supply a pull-down resistor. In this case, you hook your dry contact from input to the 5V supply, and your resistor from the input to the ground pin. In this case, the logic makes more sense, where a
LOW input level is an open switch and a
HIGH input level is a closed switch. This option works well with pin 13.
SwitchInput is intended to provide a layer of abstraction for a switch. Instead of thinking of a switch input in terms of
LOW logic levels, it allows you to think of the switch in terms of open and closed states, which is a little easier on the brain. The
SwitchInput class has
is_closed() member functions that will return
true when the switch is open or closed respectively (and
false otherwise… obviously).
That’s hardly the best feature of the
SwitchInput class however. Another handy feature of this class are the
on_close() functions. These are virtual member functions that are automatically called when the state of the switch changes, and can be overridden to perform tasks in an interrupt-like manner when these events occur.
As their names would imply, the
on_open() function is called when the state of the switch transitions from closed to open, and the
on_close() function is called when the switch changes from from open to closed.
That brings us to our third feature: automatic debounce filtering. This helps to clean up “dirty” input signals. With most switches, when you close or open them, they don’t transition cleanly from one state to another; the voltage tends to “jitter” back and forth. Without some kind of filtering, this would cause
on_close() to be called repeatedly for no reason, which needless to say, would be undesirable.
This feature operates transparently. When the voltage level of the input changes, the object will wait for a pre-determined number of milliseconds (50 by default) before doing anything. If at the end of this time period, the level is different from what it was at the beginning, the appropriate function (
on_close()) will be called. Otherwise, the input change will be treated as a spike and be ignored.
A Note about
This class is derived from the
Thread class since it needs to do logic in the background for the debouncing and edge-detection. As such, it must be added to a
ThreadList object (such as
main_thread_list) just as any other
Thread object would. Don’t expect your switch to work if you forget to do this.
Source and Documentation
As of version 0.4, the
SwitchInput class now has
time_closed() member functions which will return the time for which the switch has been open or closed (in milliseconds).