Feet wet with the Arduino: Debouncing
My lovely family got me for Xmas this year an Arduino Uno, and some associated bits like a breadboard. I’ve always been interested in how things work, but intimidated by component-level electronics, so I figured this would be a good place to get over it and learn something at the same time.
I’d already done a bunch of reading, including the Getting Started guide (thanks, Douggie, Hannah!), so next came a quick trip to RadioShack, where I rifled through their parts bins looking for anything interesting to hook up. Maybe not the cheapest solution, but it was a neat experience to be able to dig through and find stuff that might be fun to hook up, but not be sure what it’s useful for yet. In a world where everything you buy has an exact purpose, and generally only one way of hooking it up, it was an eyeopener!

Small beginnings
Among other things I ended up with a couple of plain old green LEDs, and a momentary switch (275-646). I had to crimp the switch’s legs with a pair of pliers to get them to fit into my breadboard, since in my RadioShack fugue I wasn’t savvy enough to imagine this might be something I’d want to do.
I’ve done some programming, and am comfortable digging and researching until I understand something, so I was happy enough with the coding side of it – which in fact is very similar to c#, given its c / c++ heritage. Something that fascinates me is that in coding, everything is very deterministic most of the time, but in hardware, there was a whole side I’d never guessed at; contacts can ‘bounce‘, or a potentiometer can flick back and forth between two values, or any number of other mysterious and distressing behaviours can manifest. I decided to combine the LEDs and a button, and explore the whole thing to get a better handle on it.
Every Arduino LED tutorial starts off with a LED (or two), and indicates you needed a resistor in line with each LED. A bit of digging turned up the underlying reason: the LEDs just don’t handle the current that results from a 5V source. That’s probably not exactly worded correctly, and of course there’s more to it than that, but the end result is that I needed 100 ohm resistors in series with each LED. The resistance calculation was pretty straightforward using a handy online calculator; doing it manually is a bit more work, but definitely useful. It took me a while to find a site that actually explains the calculation, which works out as follows:
The Arduino’s digital pins provide 5V, and my LEDs have a forward voltage (voltage level needed to make them light) of 2.1 volts. So we need to reduce the 5V DOWN to 2.1V, i.e. reduce it by 2.9V – this is the amount the resistor has to drop the voltage by. The LEDs have a forward current (how much current we want to drive through the LED) of 30 mA.
So for the resistor, since V=IR, i.e. 2.9 = (0.030 * R), then R = 2.9 ÷ 0.030 = 96.6667. The next ‘size up’ for resistors is 100Ω, so we select that. Whew!
The only other thing that I found non-intuitive is that I needed a resistor between the switch and ground. After some research to understand it, I found it helps to think of it this way: When the switch is open, the digital pin ‘sees’ the ground normally, through the resistor. In this case, the resistor is redundant; there’s only one path, so the digital pin is ‘low’. When the switch is closed, however, the pin can see two paths; one to ground, and one to the 5V source. The fact that one path (the ground path) has a resistor causes the pin to have a ‘preferred path’ the other way, through to the 5V source – i.e. the resistor on the ‘ground path’ makes it a less ‘desirable’ path. I’m sure that’s not technically accurate, but it makes it easier for me to remember!
So, the circuit looks like this in Fritzing:
And less attractive, but keepin’ it real:
The Arduino code to control all this is as follows:
const int led0Pin = 11; // LED1 is connected to pin 11
const int led1Pin = 12; // LED2 is connected to pin 12
const int btnPin = 2; // Momentary button is connected to pin 2
const int minTime = 30; // The minimum time the button must be pressed (in ms) before we consider it a valid press
int lastReadBtnState; // Used to store the last state that we read from the button (this could flop all over the place)
int acceptedBtnState; // Used to store the last ACCEPTED state that we read from the button (this should be very stable)
int ledLit = 0; // Which LED is lit; 0 = led0, 1 = led1
unsigned long lastChangeTime; // Used to store the last time that we observed a change in the button's state
boolean inTransition = false; // If this is true, we've observed a button change, and are waiting to see if it is stable
void setup()
{
Serial.begin(9600); // Initialise the serial output so that we can write out debug messages
pinMode(led0Pin, OUTPUT); // Set the LED0 pin as output
pinMode(led1Pin, OUTPUT); // Set the LED1 pin as output
pinMode(btnPin, INPUT); // Set the button pin as input
acceptedBtnState = digitalRead(btnPin); // Initialise the stable button state to whatever state it actually is
lastReadBtnState = acceptedBtnState; // Indicate that we're in a stable state
}
void loop()
{
lastReadBtnState = digitalRead(btnPin);
if (!inTransition && (lastReadBtnState != acceptedBtnState))
// Bam, we registered a button state change
{
lastChangeTime = millis(); // Mark the time we observed the change
inTransition = true; // Note that we're now in a transition state
Serial.println("Button state changed from " + StateToStr(acceptedBtnState) + " to " + StateToStr(lastReadBtnState) + ". Going into transition");
}
else if (inTransition && ((millis() - lastChangeTime) > minTime))
// The button state hasn't changed for at least minTime milliseconds, so assume we're stable now
{
Serial.println("Met minimum time requirement: going from " + StateToStr(acceptedBtnState) + " to " + StateToStr(lastReadBtnState));
if (lastReadBtnState == LOW)
// Only toggle the LED if the button is in a LOW state
{
Serial.println("New state is LOW; toggling LED");
ledLit = 1 - ledLit;
}
// Move the last-read value into the accepted state variable
acceptedBtnState = lastReadBtnState;
// Note that we're no longer in transition
inTransition = false;
}
// Turn on the appropriate LED
if (ledLit == 0)
{
digitalWrite(led0Pin, HIGH);
digitalWrite(led1Pin, LOW);
}
else
{
digitalWrite(led0Pin, LOW);
digitalWrite(led1Pin, HIGH);
}
}
String StateToStr(int AState)
// Given a pin state variable, returns a text equivalent of its value
{
return (AState == HIGH ? "HIGH" : "LOW");
}
The LEDs alternate smoothly when the button is pressed, so mission accomplished. Back to the sack of goodies to see what’s next!

