# Buttons

For the most part, using the button on the Launchpad is pretty easy:

You run the code, press the button, and the light comes on.

We run into problems immediately, however, if we try to count the button pushes:

The program above does not work properly. You will find that the program sometimes prints "Three!" after only one or two button presses.

This is because mechanical buttons bounce when you push them. Each push connects the contacts in the button, but then they bounce away and disconnect before connecting again, often several times. The Launchpad is so fast that it can ask the state of the switch many times during this bouncing period, and get different answers as to whether the contacts are closed or not.

We need to add code to "debounce" the switch. This is not quite as simple as waiting until the bouncing has stopped. We need to make sure that we wait less than 50 milliseconds, so the response to the switch still seems instantaneous to a human, and we want to avoid triggering on electrical noise generated by static electricity or nearby motors causing spikes in voltage.

One way to do this is to examine the switch multiple times, and look for a pattern that has any number of 'true' states (the switch was closed when we looked) followed by 12 states in a row where the switch was definitely closed. We can do that by using some tricky bit-twiddling code in the function 'closed()' in the program shown below:

We have a variable called 's' that is static -- i.e. it retains the information in it across function calls. It can hold 16 states, one per bit.

We shift the variable left, so each new state is added as the lowest bit.

Then we 'or' in the value 0xE000. This makes the top three bits always be one bits. That will mean that we don't care whether they were on or off in the comparison on the next line.

The next line asks if the value in 's' is exactly 0xF000, in other words, any number of 1 bits followed by exactly 12 zero bits. If this is true, then we have detected when the switch stopped bouncing, and has been fully closed for 12 samples.

The next time we call closed() it will return false, because we are no longer at the precise point when the switch was closed. It may be closed, or still open, we don't care.

Note that we have to check closed() multiple times before we get a true. This is usually done in a loop (as we did here), or in a timer routine. You can call closed() every 4 milliseconds and still be inside our 50 millisecond response window.

Walk through the code in your head until you are sure you understand it. It is a bit tricky, but very useful.