3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

Arduino Button Tutorial

Arduino Button Tutorial
What's simpler and dumber than a button, you ask...

I say: behind a button, unexpected things can hide. And within a program that does various things, handling a button can be tricky. The nice thing is that interesting functions can be built with a simple dumb button.

This tutorial will address these aspects:
  • wiring and configuring pins, using pull-up/pull-down resistor,
  • deglitching,
  • detecting states versus events,
  • detecting long presses,
  • and some object-oriented programming.

The programming approach is based on polling, encouraged by the Arduino loop() principle, and which is perfectly acceptable for simple to moderately complex Arduino projects. We'll require the duration of each loop() execution to be "fairly" the same each time.

More advanced implementations, not covered here, may include the usage of interrupts and timers. They are more accurate, but also harder to understand.

This tutorial is intended to people with a basic first Arduino experience (i.e. with knowledge of the IDE, and of the compilation, flashing and running of sketches).

In the following ZIP file, the four sketches used in this tutorial can be found.
 
Remove these adsRemove these ads by Signing Up
 

Step 1Connecting the Button

Connecting the Button
The Button

This is a momentary switch, with one stable position (open) when no force is exerted, and conducting (closed) when pressed. It is one of the simplest electro-mechanical sensing device.

Connect the button like illustrated in the photo of this step.

(Don't be impressed by the size of my breadboard. A small one will be actually handier.)


The I/O Pin

The AVR (aka ATmega, i.e. the Atmel chip powering the Arduino board) has several I/O pins. I/O means that they can be freely configured by software as input or output.

Pin 2 will be a good choice for our example. It will be used to measure the state of the button: pressed or released.


Pull-up Resistor

The pin has to be connected to somewhere via the button. The question is: where.

A first idea would be to go to VCC. VCC is the usual denomination for the supply voltage, here 5V.
So when the button is pressed, the pin would be connected to VCC, and the software would read HIGH. But when the button is released, the pin is connected to nowhere, aka "floating", and will be exposed to noise, and the software will read HIGH and LOW in an erratic way.

So the solution is to use a so-called pull-up or pull-down resistor. Such a resistor ensures that the pin is always connected to GND or VCC, directly or via the resistor, depending on the button position.

Fortunately, the AVR chip has, internally, a 20 kOhm pull-up resistor that can be connected to the pin (internally). The pin must be configured as input, and its value, in this situation, tells whether the pull-up is connected (otherwise the value defines, when the pin is configured as output, its output state).

With this pull-up, we'll connect the pin to GND through the button, and have these situations when the button is released, respectively pressed:
  Button not pressed:

               VCC
                |
           20K | |
      internal | |
       pull-up |_|
                |
                |                 _____
      input ––––*––––––o–––––––––o     o––––– GND
                      pin       released
                                 button

Input is isolated from GND, so only connected to VCC via the resistor. No current flows.
Without the pull-up resistor, the input would be "floating".

  Button pressed:
	
               VCC
                |    :
           20K | |   :
      internal | |   :
       pull-up |_|   :  some current flows
                |     `- - - - - - - - - ->
                |
      input ––––*––––––o–––––––––o–––––o––––– GND
                      pin        pushed
                                 button

Input is now directly connected to GND. Some current flows through the resistor.

In both cases, we now have a clearly defined situation.


Consumption

When the button is pressed, the resistor gets a voltage difference equal to VCC, and a current I is flowing:

I = VCC / R
  = 5 / 20,000 = 0.25 mA

Corresponding to consuming the power P:

P = VCC2 / R
   = 52 / 20,000 = 1.25 mW

This is not much, and is consumed only when the button is pressed. Often, pull-up and pull-down resistors have even greater values, consuming hence less power. If you don't have particular reasons, use this handy 20k internal pull-up.


Polarity

Had we a pull-down at our disposal, we would have connected the pin to VCC instead of GND, and read HIGH upon press, which is more logical. But since we have a pull-up only, we'll have to reverse the polarity by software, at pin sampling.

For more about I/O pins, follow http://www.arduino.cc/en/Tutorial/DigitalPins.


Programming

The configuration of the AVR pin (as input and with pull-up enabled) is described in the code below.


Code

––––––––––8<––––––––––
#define BUTTON_PIN 2

void setup()
{
  ...
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // connect internal pull-up
  ...
}

void loop()
{
  ...
}
––––––––––>8––––––––––
    
« Previous StepDownload PDFView All StepsNext Step »
5 comments
Feb 19, 2012. 6:17 AMarduino-tester says:
I have changed code to lit led and display serial communication something different but when i press button, it just stops displaying 1 and displays blank till i keep pressed button. What is wrong i'm doing i can't get it.

////////////////////////////////////////////////////////////////////////////// // Arduino button tutorial 1. // // Demonstrates: // - detection of pressing state // // Push-button must be connected as follows: // __,__ // Pin2 ------o o------ GND // // (C) 2011 By P. Bauermeister // This example code is in the public domain. // ////////////////////////////////////////////////////////////////////////////// // Adapt these to your board and application timings: #define BUTTON_PIN 2 // Button #define DELAY 1000 // Delay per loop in ms #define LED_PIN 7 ////////////////////////////////////////////////////////////////////////////// void setup() { pinMode(BUTTON_PIN, INPUT); pinMode(LED_PIN, OUTPUT); digitalWrite(BUTTON_PIN, HIGH); // pull-up Serial.begin(9600); } boolean handle_button() { int button_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed return button_pressed; } void loop() { // handle button boolean button_pressed = handle_button(); // do other things if (button_pressed==0) { Serial.print("1"); digitalWrite(LED_PIN, HIGH); } else { digitalWrite(LED_PIN, LOW); Serial.print("2"); } //Serial.print(button_pressed ? "0" : "1"); // add newline sometimes static int counter = 0; if ((++counter & 0x3f) == 0) Serial.println(); delay(DELAY); }
Sep 18, 2011. 3:42 PMSinAmos says:
Inspired!
Sep 17, 2011. 2:42 PMSwishercutter says:
Great work explaining and demonstrating switch bounce. Good work showing how to program around it. For those who don't want to have to include all the extra code there is an arduino library you can include in your sketch which does the same thing. I am using it in a sketch currently.

http://www.arduino.cc/playground/Code/Bounce
Sep 16, 2011. 9:46 PMDUlschm says:
Great information. Thanks especially for the introduction to OO programming. I ran right over to the Wiki and read up. I was initially skeptical about using a delay loop instead of a debounce function, but after seeing how you used it as a prescaler for your long press counter, it totally makes sense. Yay Arduino! If I had not read this article, I wouldn't have been aware that you could take it to this level.

David

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
221
Followers
35
Author:laxap
I like things that are cool, useful, efficient and well executed. At best, all that in the same time. Subscribe to me! If I inspired you, share it: post photos in a comment, and you'll get a patch. ...
more »