Pushbutton with LED

Hey Everyone!

I have recently bought the Arduino Uno R3 and began experimenting with it, trying to learn some of the basics. Looking through some of the examples, I came across the "pushbutton" project which uses the button's state to turn the LED on/off accordingly. At first, I connected one leg of my pushbutton to GND (and the other to the digital Input pin on the Arduino) and I received the reverse of the result I was expecting; the button unpressed would turn the LED on and the button pressed would turn the LED off. After re-reading the project schematic, I realized I needed to connect this leg to the 5V power supply and the leg that was connected to the input pin also needed to be connected to a 10k resistor. When I didn't use the 10k resistor, the LED was never completely off and the pushbutton just affected whether it was slightly lit or completely lit. After making these changes, the button works as expected.

However, I am confused as to some of the thoery behind the circuity. If someone could please explain this, I would really appreciate it.

My questions are as follows:

  • How does the current flow through the button and to the 10k resistor to GND when the switch is unpressed and the current is unable to pass?
  • Why does the function of the button reverse when the leg is connected to GND?
  • What purpose does the 10k resistor serve and why does it allow for the state to be either completely off or completely on?

Thanks! :slight_smile:

anujent:
How does the current flow through the button and to the 10k resistor to GND when the switch is unpressed and the current is unable to pass?

That's a good question. It doesn't. Why? More on that in a moment.

Why does the function of the button reverse when the leg is connected to GND?

The Arduino digitalRead checks to see if there is or isn't voltage present at the pin. No voltage = LOW, voltage = HIGH. With the button leg connected to ground, there is 0 volts when the button is pressed and digitalRead returns LOW. With the button leg connected to +5VDC, there is 5 volts when the button is pressed and digitalRead returns HIGH.

What happens in either case when the button is unpressed is interesting. More on that next.

What purpose does the 10k resistor serve and why does it allow for the state to be either completely off or completely on?

This is the strange and un-intuitive thing about Arduino input pins. Let's examine what happens without the resistor. Arduino pins are connected to transistors that have not just two states, but are in fact tri-state. Aside from HIGH and LOW, they can also be "high Z" or "floating". When a pin is floating, it is susceptible to faint electromagnetic fields that are everywhere (well, at least on Earth's surface). This electromagnetic "noise" causes the transistor to go HIGH and LOW, sometimes very quickly, and seemingly at random.

Your dimly lit LED was in fact flashing full ON and full OFF, because the input pin was frequently changing between HIGH and LOW -- but so quickly that your eyes could not detect the flicker, so it merely appeared dim.

Now with a resistor -- (called a pulldown resistor if connected to ground), all that electromagnetic noise is sent through the resistor to ground before that floating transistor has a chance to go high. The transistor reliably reads LOW because it can't "see" the noise any more. When you press the button, voltage comes in but the resistor does not allow all of the current to go to ground -- enough of it leaks into the transistor to turn it HIGH.

If you choose a pulldown resistor with too few ohms, your button stops working because too much of the current goes through the resistor and not enough is left over for the transistor to see. If you choose a resistor with too many ohms, the noise starts to find its way into the transistor again because not all of it is bled out through the resistor.

For convenience, the Arduino has built in pullup resistors. These do the opposite as pulldowns and make your digitalRead always return HIGH until the button, connected to ground, is pressed. To make this easier to deal with in your code, you can do

#define UP HIGH
#define DOWN LOW

pinMode(inputPin, INPUT_PULLUP);

if(digitalRead(inputPin) == DOWN)
  { Serial.println("Button pressed down."); }

if(digitalRead(inputPin) == UP)
  { Serial.println("Button not pressed."); }

Thank you so much! I have a much clearer understanding of the pull-down resistor and EM noise now

Having said this, you should have the button connected from the input pin to ground; you enable the "pull-up" in the chip so you do not need an external resistor and you alter the program code to set the LED output to the opposite state to the button input - if that is what you wish it to do.

Wiring buttons in this way is much more convenient - and safer in general since you are not bringing the supply voltage connection out to wherever the button may be located and risking it being short-circuited. If a short circuit to ground occurs when the button is already connected between the input and ground, it simply appears as if the button was pressed.

Now after you have all this in hand, you will next need to learn about "de-bouncing". :slight_smile:

I have done that and the circuit works as expected. I am however curious as to how the voltage is being supplied across the button. Does the input pin supply power through the button and to ground? If so, how does the input pin behave when one leg of the pushbutton is connected to 5V instead?

anujent:
I am however curious as to how the voltage is being supplied across the button. Does the input pin supply power through the button and to ground?

Yes. The internal pullups are about 20Kohm, so they don't supply much power. That's good, though, as such limited power generally doesn't fry things when mistakes are made.

If so, how does the input pin behave when one leg of the pushbutton is connected to 5V instead?

Nothing happens, I believe. It should still read HIGH just as it did with the button unpressed. But I'll defer to someone with more experience...

The "pull-up" is a transistor (FET) within the chip which - when you enable it in the software - feeds a current (if the pin is externally pulled low) from Vcc to the input pin, as if you had connected your 10K resistor between Vcc and the input pin.

If you connect the pushbutton to Vcc instead with no external resistor, well, the pull-up will be pulling the pin high and your pushbutton will be doing the same, so no difference whether the button is pushed or not.

As previously mentioned, if you have neither an external resistor, or the pull-up enabled, then unless the button is pressed, the voltage on the input pin will be quite random and - if your wires are reasonably long - will probably detect the electrostatic field radiated from all the mains wiring in the room and fluctuate high and low. (The internal clamp diodes in the chip, on which you should never rely, will restrict the pin voltage between ground and Vcc.)

For a slightly more complex, if not confusing, explaination....

Here's what the "inside" of the pin looks like in schematic form.