Using a Push Button with Arduino
Français
Watch the Video Tutorial
Push buttons and Switches are digital inputs and are widely used in electronic projects as most systems need to respond to user commands or sensors. Reading a push button is very useful because a push button is widely used and can also represents a wide range of digital devices in real world like switches, limit sensors, level switches, proximity switches, keypads (a combination of switches) etc.
In this case, we’re going to use the simplest form of sensor: a push button switch. A push button is basically two bits of metal kept apart by a spring, and a plastic cap that when pressed brings the two bits of metal into contact to close the electric circuit. When the bits of metal are apart, there is no circulation of current. when you press it, you make a connection.
Pull-up Resistors
Connecting a switch or a push button to Arduino Uno is straight forward, all we need is a pull-up or pull-down resistor.
Figure 1: A switch with a Pull-up resistor Figure 2: A switch with a Pull-down resistor
The pull-up or pull-down resistor is very important, if there is no resistor it will be difficult to determine the state of the pin, this is called floating.
Let’s say the arduino pin is configured as an input. If there is nothing connected to the pin and the program reads the state of the pin, will it be high (pulled to VCC) or low (pulled to ground)? It is difficult to tell. But with a resistor connected to VCC (pull-up) as in figure 1, or connected to ground (pull-down) as in figure 2, will ensure that the pin is in either a high or low state.
Pull-up resistors are the more common so we will focus on them. As shown figure 2, if the push button is open, the input D4 will be high (+5V) and when the push button is closed, the input D4 will be low as all current will flow from +5V to ground. If there was no resistor, then it could have been a short circuit. Generally a value of 10KΩ should do the job fine.
Figure 1: A push button connected to pin D4 with external push-up resistor and an LED connected to D7
Figure 2: Push button connected to pin D4 with external push-up resistor and an LED connected to D7 Circuit diagram
Internal pull-up resistors can also be enabled in software if external resistors are not going to be used as shown on figure 3 and 4 below.
Figure 3: A push button connected to pin D4 with internal push-up resistor and an LED connected to D7
Figure 4: Push button connected to pin D4 with internal push-up resistor and an LED connected to D7 Circuit diagram
Switch Debouncing
As mechanically the metal contacts of the switch are not perfectly smooth, when a switch is closed, it doesn’t perfectly close immediately, in fact in bounces open and close so fast before it can stabilise and stay open. Figure 5 below shows the operation of a bounce-less switch, when the switch is closed, it closes immediately and the current flowing through it rises immediately from 0 to maximum. In reality this kind of switch doesn’t exist, with a close-up look with an oscilloscope, it revealed that, in practice, the switch bounces close and open for a short period of time before stabising as shown on figure 6.
In normal situation, this bouncing period is so short that it won’t even be noticed, but a microcontroller/arduino can detect it, and if high speed switching is involved, the circuit won’t be accurate if this bouncing effect is not taken into consideration.
Figure 5: A Bounce-less Switch operation. Figure 6: A normal real Switch operation
There are many ways this can be eliminated in software, one can use a counting algorithm where the switch is read periodically (e.g. every 1 ms) and it can only be considered to have changed state if it has been in the new state for some number of successive samples (e.g. 10), by which time it is considered to have settled.
The other method and the easiest one is to read a switch then after a short delay, let say 10ms, read it again, if the state of the switch is still the same, then the switch is considered to have settled in that state.
Sketch using an external pull-up resistor
Now let us write a simple Sketch to switch ON an external LED connected to a digital pin 7 of Arduino for 5 seconds when the push button is pressed. After 5 seconds, the LED will switch OFF again. An external pull-up resistor is used as on figure 2.
const int Pushbutton = 4; //Pushbutton connected to pin D4 const int LED = 7; //LED connected to pin D7 int value = 0; // Variable for reading pushbutton status void setup() { // put your setup code here, to run once: pinMode (LED, OUTPUT); //LED pin is Output pinMode (Pushbutton, INPUT); //pushbutton pin is Output with external Pull-up resistor } void loop() { // put your main code here, to run repeatedly: value = digitalRead(Pushbutton); //Reads the status of the pushbutton if (value == LOW) //If the Pushbutton is pressed { delay(10); //10 milliseconds debouncing Delay if (value == LOW) //check again if the Pushbutton is still pressed { digitalWrite(LED, HIGH); //LED ON delay(5000); //5 Second Delay digitalWrite(LED, LOW); //LED OFF } } }
To monitor the state of a push button/switch or any input sensor, there’s a new Arduino instruction that we’re going to learn: the digitalRead() function. digitalRead() checks to see whether there is any voltage (+5V) applied to the pin that you specify between parentheses, and returns a value of HIGH or LOW, depending on its findings and stores it in value variable.
The other very important statement we’ve introduced here, is the IF Statement. The if statement is one of the most important instruction in a programming language, because it allows a computer like an Arduino to make decisions. After the if keyword, you have to write a “question” inside parentheses in our example check if value is LOW (button is pressed), and if the “answer”, or result, is true, the first block of code will be executed; otherwise, the block of code after else will be executed. You must notice that the == symbol is very different from the = symbol. The former is used when two entities are compared, and returns true or false; the latter assigns a value to a constant or a variable.
We used a short 10ms delay as a debouncing delay and check again, if after this short delay the button is still found to be pressed, then we know for sure that the button was pressed and it has settled.
Sketch using an internal pull-up resistor
Now let us write the same Sketch as above but now using the internal pull-up resistor is used as on figure 4.
const int Pushbutton = 4; //Pushbutton connected to pin D4 const int LED = 7; //LED connected to pin D7 int value = 0; // Variable for reading pushbutton status void setup() { // put your setup code here, to run once: pinMode (LED, OUTPUT); //LED pin is Output pinMode (Pushbutton, INPUT_PULLUP); //pushbutton pin is Output with internal Pull-up resistor } void loop() { // put your main code here, to run repeatedly: value = digitalRead(Pushbutton); //Reads the status of the pushbutton if (value == LOW) //If the Pushbutton is pressed { delay(10); //10 milliseconds debouncing Delay if (value == LOW) //check again if the Pushbutton is still pressed { digitalWrite(LED, HIGH); //LED ON delay(5000); //5 Second Delay digitalWrite(LED, LOW); //LED OFF } } }
You can download the full project files (Arduino and Proteus project) below here. All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).
Download Pushbutton_Arduino
Download Arduino_Pushbutton Proteus