Learn to code

Arduino Home

Lessons 1
Arduino - Getting Started
Lessons 2
Arduino - Basics
Lessons 3
Arduino - Serial Communication
Lessons 4
Arduino - Digital / Analog
Lessons 5
Arduino - Visual Output
Lessons 6
Arduino - Motor Control
Lessons 7
Arduino -LCD Displays
Lessons 8
Arduino -LCD Displays

Using a toggle switch or pushbutton with Arduino

in Arduino Digital / Analog

We have learned in earlier tutorials how to blink an LED with Arduino automatically.  That program will run as long as there is power for the Arduino. Let’s go a bit further and try to control the LED with a button. We use a pushbutton to control the Blinking. In other words, we will make a simple program that allows you to control the LED by pushing a button.

Unfortunately, many of the guides never go beyond the very basic first sketch. In this guide, I hope to help new users take the next step. The process for switching any digital device on and off is quite the same.

We are going to use polling techniques for reading the switches/pushbuttons. This means that in the example sketches below, we constantly check the pin state with digitalRead(). Only when we look at the pin, do we know if the state has changed. It is like checking if the window is open every minute.

The switch pin is connected to a 10K resistor, GND, and button switch in the example codes below. This means that the pin is being pulled LOW. The other side of the switch is connected to VCC (in the case of an Arduino Uno 5V), so when the switch is closed, the VCC overpowers the 10K resistor and connects the switch pin to 5V, making it HIGH.

It is usually is not wise to connect an Arduino Pin directly to 5V. We can do this here since the Arduino digital pins are set for INPUT with the function pinMode(). This means a resistor in front of the pin allows us to connect the pin directly to the 5V.

There are a couple of examples that we will examine.

The first example is a simple button press. In this example, the LED will come on when the button is pressed. When the button is released, the LED goes off.

The second example is a toggle switch. Here you will learn about button states. This means that you can press the button to turn the LED on and press the button a second time to turn the LED off.

The third example shows how you can reliable detect if the pushbutton/switch is pressed/closed with the debounce method.

Example 1, Simple button press

the first example is very simple. When the pushbutton is open (unpressed), there is no connection between the two legs of the pushbutton, so the pin is connected to the ground (through the pull-down resistor), and we read a LOW. When the button is closed (pressed), it makes a connection between its two legs, connecting the pin to 5 volts so that we read a HIGH.

Parts you will need

Arduino Uno Rev3 Arduino Uno Rev3 × 1
Breadboard 400 point Breadboard 400 point × 1
Dupont Wires Dupont Wires × 7
LED LED × 1
Tactile Push Button Tactile Push Button × 1
10K Resistor 10K Resistor × 1
220 ohm resistor 220 ohm resistor × 1
Arduinoplatform is a participant in several affiliate programs. This means that I will earn a commission if you buy a product from the affiliated websites by clicking on the links provided above.

BreadBoard Layout

Led Button Debounce

Example 1, Code

/*
 * Simple on/off button sketch
 * If the button is pressed the led will turn on
 * if the button is unpressed the led will turn off
*/

// the number of the pushbutton pin
const int buttonPin = 2;
// the number of the LED pin     
const int ledPin =  10;      

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // check if the pushbutton is pressed. 
  if (digitalRead(buttonPin) == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

Example 1, Code Explanation

When declaring the Arduino Pins that we want to use, it is wise to name them. You can also just use the relevant number. Using bare numbers works fine but can lead to readability issues in the code, especially in large sketches or code that takes a while to develop. You may think it is clear that pin 10 is the LED, but at some point, you are likely to forget. To make the code better readable (or easier to follow), it is better to use variables with meaningful names instead of the actual PIN numbers. In the following example, buttonPin and ledPin are declared. From the variable names, it is obvious where the pins are used for.

// the number of the pushbutton pin
const int buttonPin = 2;
// the number of the LED pin     
const int ledPin =  10;  

Void setup(): We need to set the button variable to an input mode and set the LED to an output mode. This tells the Arduino Board to use pin 2 as an input and pin 10 as an output.

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

In the void loop () part, we will control the LED by using an If statement and the command digtalRead(). The if statement in the sketch will check whether Pin 2, the buttonPin, is sending a HIGH value. We use a comparison operator “==” to check if the Pin is set HIGH since the circuit is closed when the switch is pressed.

if (digitalRead(buttonPin) == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  }

If that condition is not met, the loop goes to the Else Statement, where the LED is turned off.

else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }

You should be able to see that the sketch is constantly checking the switch and turning the LED on or off accordingly. This means not only is the switch pin being constantly checked but the LED is constantly being turned on and off. For this short simple sketch, this is fine and works well but may run into issues when used in larger more complex sketches.

If you want to let the LED stay on we need to determine the state of the button. To do this, we will use the button as a switch and determine the last state it was in.

Although we cannot get away from continuously checking the button switch pin (this is what polling is) we can stop setting the LED pin every time and only set it if the state of the button switch has changed.

Example 2, Toggle Switch

In the previous tutorial, we already learned how to turn a LED on with a button. The problem arises that if the button is unpressed, the LED turns off. If you would like to keep the LED on after the button is pressed, we need to remember the state of the button. We can use the boolean function for this. We will use and modify the code we already made in the first example. 

What if we do not want to hold the button switched closed to keep the LED on. What if we want to press once to turn on the LED and press again to turn it off. To do this, we need to know when the button switch is pressed but was not pressed before (we have already done this in the previous example), and we also need to know the status of the LED; is it on or is it off? We can keep track of the LED status by adding a new variable LEDstatus. LEDstatus will be LOW for off and HIGH for on.

For remembering the button state, we can declare a variable called SwitchState, where we remember the old and the new state of the button/switch.

Example 2, Code

/*
 * "Toggle Switch State"
 * This sketch uses a switch to turn a LED on or off.
 * The LED keeps on untill the switch is pressed again.
*/

// declaring pins for LED and the switch
int pinLed = 10;
int pinSwitch = 2;

// declaring boolean variables to hold
//the new and old switch states
boolean oldSwitchState = LOW;
boolean newSwitchState = LOW;
boolean LEDstatus = LOW;

void setup()
{
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, LOW);
  pinMode(pinSwitch, INPUT);
}
void loop()
{
  // read the status from the switchpin
  newSwitchState = digitalRead(pinSwitch);
  //if the switch is pressed or unpressed 
  //compare with the previous state
  if ( newSwitchState != oldSwitchState )
  {
    // has the button switch been closed?
    if ( newSwitchState == HIGH )
    {
      //check if what the status is of the LED.
      if ( LEDstatus == LOW ) {
        digitalWrite(pinLed, HIGH);
        LEDstatus = HIGH;
      }
      // if the LED is on and the switch is pressed again
      else                    {
        digitalWrite(pinLed, LOW);
        LEDstatus = LOW;
      }
    }
    // save the state of the switch so It can be compared
    oldSwitchState = newSwitchState;
  }
}


Example 2, Code Explanation

The first part of the sketch is the same as the first example. Here we declare the variables that hold the LED pin and the pin for the switch input.

// declaring pins for LED and the switch
int pinLed = 10;
int pinSwitch = 2;

As you can see, three variables hold the current and new state of the button. Boolean variables hold/remember the state of the object, in our case, the button. If the program is run for the first time, both states should be LOW. We can now transform the button into a switch.

// declaring boolean variables to hold
//the new and old switch states
boolean oldSwitchState = LOW;
boolean newSwitchState = LOW;
boolean LEDstatus = LOW;

In comparison to example 1 we are turning the LED off at the beginning of the sketch.

void setup()
{
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, LOW);
  pinMode(pinSwitch, INPUT);
}

In the void loop() part of the sketch, the first thing to do is read the pin connected to the switch/button. If it’s pressed, the value will be HIGH. When the switch is not pressed, the value will be LOW.

// read the status from the switchpin
  newSwitchState = digitalRead(pinSwitch);

The next step is to check whether the button has been pressed or released before. In other words, did the state of the switch changed? The comparison operator != is used to see if the new state of the switch is not the same as the old state of the button/switch.

if ( newSwitchState != oldSwitchState )
  {

Next, we check whether the switch is pressed and execute the code that belongs to it.

// has the button switch been closed?
    if ( newSwitchState == HIGH )
    {

If the switch is pressed, we check whether the LED is on or off. If the LED is off (LEDstatus memorize the status), the pin is set HIGH, which turns on the LED. Furthermore, the Boolean variable LEDstatus is set HIGH to let the program know that the LED is on.

//check if what the status is of the LED.
      if ( LEDstatus == LOW ) {
        digitalWrite(pinLed, HIGH);
        LEDstatus = HIGH;
      }

If the condition is not true that the LEDstatus is LOW while you have pressed the switch/button, the LED will be turned off. Remember that the testing conditions if the LED is on are inside the if function that is only executed when the status of the pinSwitch is HIGH.

// if the LED is on and the switch is pressed again
      else                    {
        digitalWrite(pinLed, LOW);
        LEDstatus = LOW;
      }
    }

At the end of the sketch, we save the status of the switch into the oldSwitchState. This is important since we arrived at the end of the sketch and we need to know the old state of the switch for the next time in the loop().

// save the state of the switch so It can be compared
    oldSwitchState = newSwitchState;
  }

With many kinds of switches, you do not get clean closed contact. You get a very short transition period where the switch very quickly closes, opens, closes, opens, and closes before settling down and becoming closed. The contacts bounce a bit before becoming fully closed.

This will be the third example that we will examine—namely, a toggle switch with debouncing.

Example 3, Debounce Switch

We can finetune the above code with the debounce method. The debounce method checks to see if it gets the same reading from the switch after a slight delay that needs to be long enough for the switch contacts to stop bouncing. You may require longer intervals for “bouncier” switches (some switches can require as much as 50 ms or more). The function works by repeatedly checking the state of the switch for as many milliseconds as defined in the debounce time. If the button remains stable for this time, the state of the switch will be returned (true if pressed and false if not). If the switch state changes within the debounce period, the counter is reset so that the checks start over until the switch state does not change within the debounce time. This debounce() function will work for any number of switches, but you must ensure that the pins used are in input mode.

A potential disadvantage of this method is that the sketch is blocked for the time that you set the debounce. This means that the sketch is waiting for the debounce function the be completed until it can do something else in the sketch.

Example 3, Code 

/*
   Debounce sketch which puts on a LED
   a switch connected to pin 2 lights the LED on pin 13
   debounce logic prevents misreading of the switch state
*/
// the number of the input pin
const int inputPin = 2;
//the number of the output pin
const int ledPin = 10;
// milliseconds to wait until stable
const int debounceDelay = 10;

// debounce returns true if the switch in
//the given pin is closed and stable
boolean debounce(int pin)

{
  boolean state;
  boolean previousState;

  // store switch state
  previousState = digitalRead(pin);
  for (int counter = 0; counter < debounceDelay; counter++)
  {
    // wait for 1 millisecond
    delay(1);
    // read the current pin value
    state = digitalRead(pin);
    // if the current value of the pin is differ
    if ( state != previousState)
    {
      // reset the counter if the state changes
      counter = 0;
      // and save the current state
      previousState = state;
    }
  }
  // here when the switch state has been stable
  return state;
}
void setup()
{
  pinMode(inputPin, INPUT);
  pinMode(ledPin, OUTPUT);
}
void loop()
{
  // if debounce function is true
  if (debounce(inputPin))
  {
    // send HIGH signal to ledPin
    digitalWrite(ledPin, HIGH);
  }
}

Example 3, Code Explanation

To detect the state of the switch, we first need to declare the variables that hold the pins. And a constant integer for the delay that we will use in our debounce function.

// the number of the input pin
const int inputPin = 2;
//the number of the output pin
const int ledPin = 10;
// milliseconds to wait until stable
const int debounceDelay = 10;

The debounce function returns TRUE if the switch is closed and stable. The Boolean function starts by defining some variables that will hold the states of the button/switch.


// debounce returns true if the switch in
//the given pin is closed and stable
boolean debounce(int pin)

{
  boolean state;
  boolean previousState;

  // store switch state
  previousState = digitalRead(pin);

In the for loop, we start the counter with zero and increases it by one until it reached the number 11. The for loop will then return the value of the state. The loop will repeat itself 10 times, the value of debounceDelay. It will start with a delay of 1 ms and then read the pin that is connected to the button/switch.

The if statement that follows checks whether the state of the button/switch is the same as the previousState when it entered the if statement. This is vital to know whether the button is pressed or not.

for (int counter = 0; counter < debounceDelay; counter++)
  {
    // wait for 1 millisecond
    delay(1);
    // read the current pin value
    state = digitalRead(pin);
    // if the current value of the pin is differ
    if ( state != previousState)
    {
      // reset the counter if the state changes
      counter = 0;
      // and save the current state
      previousState = state;
    }
  }
  // here when the switch state has been stable
  return state;

Void loop ():  another if statement is used to check if the function “debounce” returns a true value for the inputPin. If this is true, a HIGH signal is sent to the ledPin. When the button is pressed, the LED will now be turned on.

void loop()
{
  // if debounce function is true
  if (debounce(inputPin))
  {
    // send HIGH signal to ledPin
    digitalWrite(ledPin, HIGH);
  }
}

Now we know how to reliably detect the switch, to control multiple LEDs with one switch.

Previous Post
Logic level shifting with Arduino
You must be logged in to post a comment.
Menu