How to Make One Button Have the Functionality of Two or More with Arduino

Do you have an application where you want multiple buttons for different user inputs?  Maybe you have a timer and you want one button for minutes and another for hours.

But there is a problem – you only have room for one button!

In this tutorial, we are going to use Arduino to explore how to make one button have the functionality of two or more.

 

You Will Need:

(1) Momentary push button

(5) Jumper wires

(1) Solderless breadboard

(2) LEDs

(2) 220 Ohm resistors

Set Up The Circuit:

To demonstrate making one button have the functionality of two or more, we will set up a simple circuit with 2 LEDs and a button.  Based on how we press the button, different LEDs will illuminate.

Follow the instructions and schematic below to get the circuit set up before we dive into the mechanics of the Arduino code.

  1. Using a jumper wire, connect any GND pin from the Arduino, to the ground rail on your breadboard.
  2. Place an LED on your breadboard, make sure to note which way the long leg is facing.
  3. Using a jumper wire, connect pin 13 from your Arduino to the breadboard in the same channel where you have the long leg of the LED attached.
  4. Now connect one side of the 220 Ohm resistor to the short leg of the LED, and connect the other leg to the ground rail on the breadboard.  The orientation of the resistor doesn’t matter.
  5. Repeat this using pin 12, and another LED and resistor.
  6. Finally, place your push button on the breadboard.  Depending on the style of your pushbutton, they often fit well straddling the long trench that goes through the breadboard.
  7. Connect a jumper wire from one side of the button to pin 2 on the Arduino.
  8. Connect a jumper wire from the other side of the button to the ground rail on the breadboard.

That’s it for the circuit setup.  Now, when you press the push button (which will electrically connect both sides of the button), pin 2 to will have ground voltage applied.  We will use this ground voltage input to trigger our different functions.

One Button Functionality of Two

Examine the Sketch:

There are couple ways to implement the multi-function button press using Arduino.

One way is to have the number of presses determine the output.  For example, a single click might highlight the “hour” field of an LCD timer and a double click might highlight the “minute” field of the display.

Another way that we can implement multiple functions with one button is for the user to hold down the button for different lengths of time with the length of the hold determining the output.

For example, if the user holds the button for half a second and releases, something happens.  If she holds it for 2 seconds, something different happens.

This latter method of using button hold length time to determine separate functions is the strategy we will learn here.

Before I go any further though, I would like to thank Steve for creating the base Arduino code that we will be using.  Steve is a member of the Premium Arduino course (a couple of months ago, he was new to Arduino).

While creating a home automation project, he was in need of using a single button to do multiple things, and came up with a very simple way to make it happen.  Thanks Steve!

Here is the complete sketch, I recommend looking it over first, and then we will discuss it piece by piece below.

/*Using a Single Button, create mutliple options based on how long the button is pressed
 
 The circuit:
 * LED attached from pin 13 to ground through a 220 ohm resistor
 * LED attached from pin 12 to ground through a 220 ohm resistor
 * one side of momentary pushbutton attached to pin 2
 * other side of momentary pushbutton attached to Ground
 
 * Note 1: on most Arduinos there is already an LED on the board
 attached to pin 13.
 * Note 2: In this circuit, when the button is pressed, Ground Voltage is what will be applied. 
 
 Created DEC 2014 by Scuba Steve
 Modified JAN 2015 by Michael James
 Both members of https://www.programmingelectronics.com
 
 This code is in the public domain
 */


/////////Declare and Initialize Variables////////////////////////////

//We need to track how long the momentary pushbutton is held in order to execute different commands
//This value will be recorded in seconds
float pressLength_milliSeconds = 0;

// Define the *minimum* length of time, in milli-seconds, that the button must be pressed for a particular option to occur
int optionOne_milliSeconds = 100;
int optionTwo_milliSeconds = 2000;        

//The Pin your button is attached to
int buttonPin = 2;

//Pin your LEDs are attached to
int ledPin_Option_1 = 13;
int ledPin_Option_2 = 12;

void setup(){

  // Initialize the pushbutton pin as an input pullup
  // Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed
  pinMode(buttonPin, INPUT_PULLUP);     

  //set the LEDs pins as outputs
  pinMode(ledPin_Option_1, OUTPUT); 
  pinMode(ledPin_Option_2, OUTPUT); 

  //Start serial communication - for debugging purposes only
  Serial.begin(9600);                                     

} // close setup


void loop() {

  //Record *roughly* the tenths of seconds the button in being held down
  while (digitalRead(buttonPin) == LOW ){ 

    delay(100);  //if you want more resolution, lower this number 
    pressLength_milliSeconds = pressLength_milliSeconds + 100;   

    //display how long button is has been held
    Serial.print("ms = ");
    Serial.println(pressLength_milliSeconds);

  }//close while


  //Different if-else conditions are triggered based on the length of the button press
  //Start with the longest time option first

  //Option 2 - Execute the second option if the button is held for the correct amount of time
  if (pressLength_milliSeconds >= optionTwo_milliSeconds){

    digitalWrite(ledPin_Option_2, HIGH);     

  } 

  //option 1 - Execute the first option if the button is held for the correct amount of time
  else if(pressLength_milliSeconds >= optionOne_milliSeconds){

    digitalWrite(ledPin_Option_1, HIGH);  

  }//close if options


  //every time through the loop, we need to reset the pressLength_Seconds counter
  pressLength_milliSeconds = 0;

} // close void loop

Comments:

At the top of the sketch, we find the comments.  You should make it a habit to read the comments in a sketch before jumping into the mechanics of the code.  The comments should lay the groundwork for what is going to happen in the program and will help you interpret the intent of the code as you begin to analyze it.

Declare and Initialize Variables:

After the comments, we start initializing and declaring variables.  Since, we are going to be tracking time, we need to have a variable to record the length of time a button is being held.  We do that with the pressLength_milliSeconds variable:

//We need to track how long the momentary pushbutton is held in order to execute different commands

//This value will be recorded in seconds

float pressLength_Seconds = 0;

Now, you might think that the variable name is really long and annoying.  And I wouldn’t particularly argue with you – I mean, why would I include milliSeconds in the name of the variable?

The reason I do this is because I think including the unit of measurement in the variable name is helpful when other people are trying to read your code.  Writing code that other people can read is not only good for other people, but also future versions of yourself who forget what the heck you were thinking when you wrote the code! [End Rant]

The next thing we need to set up are the parameters for when options will get executed.  In this example, I have two variables for two options:

// Define the *minimum* length of time, in milli-seconds, that the button must be pressed for a particular option to occur

int optionOne_milliSeconds = 100;

int optionTwo_milliSeconds = 2000;

Each option is defined by the number of milliseconds that the button must be held for that specific option to get executed.  In order to get my first option to happen, I have to hold the button for at least 100 milliseconds which is pretty much a short tap on the button.

If I want the second option to happen, then I have to hold the button for at least 2000 milliseconds aka 2 seconds.

If you wanted more options, you would add more variables here with their corresponding hold times.

Our final initializations will be to specify pin numbers for our button and LEDs.

//The Pin your button is attached to

int buttonPin = 2;

 

//Pin your LEDs are attached to

int ledPin_Option_1 = 13;

int ledPin_Option_2 = 12;

Setup() the Sketch:

The setup() for this sketch is pretty straight forward (if it’s not straight forward to you, make sure to check out our free 12-part Arduino Course, after which this setup will be very familiar to you).

We want to make sure that the pin our push button is connected to is set as an INPUT_PULLUP:

// Initialize the pushbutton pin as an input pullup

// Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed

pinMode(buttonPin, INPUT_PULLUP);

We do this to make sure that the button pin is not floating (if you are wondering what the heck that means, you can read more on that here – but if you just roll with me until we get through this tutorial, you should be fine ).

We also want to specify the pins that our LEDs are attached to as OUTPUTs, because we will be applying voltages to these pins in order to illuminate them:

//set the LEDs pins as outputs

pinMode(ledPin_Option_1, OUTPUT);

pinMode(ledPin_Option_2, OUTPUT);

Finally, it never hurts to start serial communications for debugging purposes.

//Start serial communication - for debugging purposes only

Serial.begin(9600);

With setup() complete, now we can jump into the main loop of our sketch…

The Main Loop():

We know we are going to have to measure the length of time the button is pressed, and then record it.

To do this, we use a while statement whose condition requires the button pin to be in a LOW state (remember, when we push the button, pin 2 will have a ground voltage applied).

 //Record *roughly* the tenths of seconds the button in being held down

while (digitalRead(buttonPin) == LOW ){

Once the button is pressed and held, the while statement starts executing.  The first thing we do in the while statement is to delay 100 milliseconds, and then record that into our time tracking variable:

    delay(100);  //if you want more resolution, lower this number

    pressLength_milliSeconds = pressLength_milliSeconds + 100;

Keep in mind the first time through the loop, pressLength_milliSeconds will be equal to 0, so we are just adding 100 to the variable.

It can be handy to know how long the button has been pressed as you add options. To make this easy, we want to print the current value of the pressLength_milliSeconds variable to the serial monitor window:

//display how long button is has been held

    Serial.print("ms = ");

    Serial.println(pressLength_milliSeconds);

Let’s ignore the rest of the code for a second, and imagine what happens if we keep holding the button.

The first time through the while loop, we add 100 milliseconds to the time tracking variable and we print that value to the serial port.  The next time through loop, we add another 100 milliseconds to the timer counter variable, and print this new value to the serial monitor.

As long as the button is being held down, then we keep adding time to the pressLength_milliSeconds variable – this is the crux of the program.

When we release the button, the while statement stops, because the condition is no longer met, and we stop adding time to pressLength_milliSeconds.

So let’s pretend we held the button for three seconds, and then let go – what happens?

Well, as we discussed, the while statement ends and the next line of code we encounter is an if statement.

//Option 2 - Execute the second option if the button is held for the correct amount of time

if (pressLength_milliSeconds >= optionTwo_milliSeconds){

    digitalWrite(ledPin_Option_2, HIGH);

}

The condition of the if statement requires that the time we held the button be longer than or equal to the time we set for option number two.

If you recall, option number two was set to occur with at least 2 seconds of button press time. Since we held the button for three seconds, this if statement will get executed.

And all we do is write HIGH voltage to our “option 2” LED, making it illuminate.

What if we had only held the button for one second – then what would happen?

If this were case, then the first if statement condition would not have been met, but a subsequent else-if statement only requires the button hold time be 100 milliseconds or more – so the second else-if statement would get executed, which turns on the “option 1” LED.

//option 1 - Execute the first option if the button is held for the correct amount of time

else if(pressLength_milliSeconds >= optionOne_milliSeconds){

    digitalWrite(ledPin_Option_1, HIGH);

}//close if options

Basically, if we hold the button a long time, the second option gets executed.  If we hold the button a short time, the first option gets executed.

If we wanted to add more options, we add the longer hold options at the top, and the shorter hold options at the bottom.

I wouldn’t try to squeeze too many options in a small span of time or it might drive the end user crazy trying figure out the timing.

Nor would I try to add more than three options for a single button within a given context, or else you chance making your potential end user want to beat you up.

To finish up the sketch, we reset our button press timing variable to zero.  This ensures that next time the button is pressed and held, we will start from time zero again.

Try On Your Own Challenge:

  1. Add another option, which turns off both LEDs.  Try adding it before the first option (you will have to adjust the timing) and then after each option.
  2. How tight can you squeeze the option time together?  Experiment and determine what is a good rule of thumb.

Download:

PDF of this Arduino Tutorial

installing Arduino libraries

Installing Arduino Libraries | Beginners Guide

IoT sewage project

Pumping poo! An IoT sewage project

ESP32 webOTA updates

How to update ESP32 firmware using web OTA [Guide + Code]

error message Brackets Thumbnail V1

expected declaration before ‘}’ token [SOLVED]

Compilation SOLVED | 1

Compilation error: expected ‘;’ before [SOLVED]

Learn how to structure your code

33 Comments

  1. akash on January 21, 2015 at 3:56 pm

    sir can we use 5v instead of applying ground voltage making some changes in code like while(digitalRead(pushbutton==HIGH))

    • MICHAEL JAMES on January 21, 2015 at 10:49 pm

      Absolutely! Except that you will need to add an external pull-down resistor to keep pin 2 at ground when the button is not being pressed. It would go from the same side of the button that pin 2 is connected to, and then to ground (a 10K resistor would work). You would also need to the the pinMode function from INPUT_PULLUP just to INPUT, for pin 2. Hope this helps!

      • akash on January 22, 2015 at 3:47 pm

        Thank you sir it was really helpful..

  2. Musashi on July 17, 2016 at 5:39 pm

    Thanks, this was very helpful!

  3. IVDV on August 5, 2016 at 7:21 am

    Hello, nice for my as a beginner and I’m totally blind but I’m verry handy because I was doing a job before with verrry high handy skills and I'”ve a friend that has me help to make the environnement of the software of arduino total accessible. Onto the arduino uno and the breadboard, the shields on my UNO I’ve perfect connected the wires and it works well!
    But, when I press first the button for one function and then I want to activate the other, the first will be actif. Thier is not a reset whyle prssing the next time the button. Pls, could you give tips to add this function in the code pls? Many thanks for the helpfull instructions and the accessible video, fantastic you explaine all of the steps by your voice!

  4. A Bruxa Avaria on November 22, 2016 at 5:54 am

    Fantastic explanation, thanks a lot for that
    How would you code a double click trigger?

  5. Imam on January 19, 2017 at 10:12 am

    Sir, please help. How to do this:
    If switch 1 is pressed, led on in 10 minutes, If switch 2 is pressed, led on in 20 minutes, If switch 3 is pressed, led on in 30 minute.
    Thank you.

  6. Bob on April 20, 2017 at 12:33 pm

    Can I make a button do one function the first time it is pressed, and then a different function the second time it is pressed? Thank you in advance.

  7. GeertVc on October 31, 2017 at 3:59 am

    Having a delay in the code is not really nice and efficient. Why not measure the time passed each time the loop is executed (compare previous to current time) instead? This allows you to do even more other stuff in the mean time…

  8. Srinivasa Reddy on July 27, 2019 at 1:49 am

    I am new to the Arduino and have yet to use one. I understand a little about how to program the Arduino
    I want to turn on 5 leds with 5 push buttons and 1common relay for buzzer. when any led ON buzzer also on
    1 push button for OFF any led and relay
    pls give me code for this cause

    • Michael James on July 29, 2019 at 3:16 pm

      Sounds like a neat project Srinivasa!

      A bit detailed to get into here, but you’ll need code to capture all the button presses (maybe an interrupt, or a tight loop that looks for the button states), then maybe a switch case, or a series if/else to execute the appropriate action.

  9. Stephen Mann on August 16, 2019 at 9:38 am

    Volume? Is your microphone in another room? I have to turn the volume on my PC up all the way to 100% to hear you.

    • Michael James on August 16, 2019 at 9:57 am

      It’s in the same room. This video in particular had an issue with volume leveling – my apologies!

  10. Victoria W. on December 6, 2019 at 7:44 pm

    Hi, I’m new to Arduino and really confused. I’m not a tech person, but am being forced to make a project with Arduino for a class final due next week. I attached everything correctly and copy/pasted the code. However, the first LED is just constantly lit up without any button pressing. Is there a reason for this? Also does this code have included how we can turn the second LED off after its been activated? I would really appreciate some help. I don’t have a lot of time and am freaking out. Thanks.

  11. Dotan Cohen on March 24, 2020 at 11:41 am

    Note that the method of determining how long the button has been pressed is blocking. That means that the Arduino cannot do other things (such as blink lights or advance a clock display) while the button is being pressed.

    A non-blocking method would be to use interrupts.

  12. patrick on September 1, 2020 at 11:19 pm

    just in time i needed that

  13. meme on October 23, 2020 at 1:24 pm

    Sir, can you connect one resistor to one LED, another one to the button? (meaning you will be using two resistors and also connect to the 5V) will it still work? and why?

  14. Tom Stenger on April 21, 2021 at 10:39 am

    I would like to setup a program using the first method you described, where the number of presses determine the output. Can you please refer me to the sketch and programming required to make that happen?

    Thank you.

    • mina on November 26, 2021 at 9:23 am

      Hi! Did you find a sketch and code referring to the first method they mentioned? I’m setting up a program similar to yours, from what you said in this comment.

  15. kristjan cof on May 17, 2021 at 6:01 am

    I have a problem. I added another button and two led this works for me. But when I add a third button and add two more led, the thing doesn’t work for me at all.
    thank you

    • Michael James on May 17, 2021 at 8:13 am

      Hi Kristjan, how did you change your code?

  16. biiancaa on June 7, 2021 at 8:02 am

    Hello!
    I have read some articles from this site, especially those which included pushbuttons, but i can not solve my problem. I have little experience with Arduino and I am trying to solve a problem. I am making an alarm using DS3231 and LCD1602 i2c, 2 LEDs and a pushbutton. For the first alarm the first LED is turning on, and when the pushbutton is pressed, the LED turn off. But for the second alarm, the second LED turn on, but if I press again the pushbutton, it won’t turn off. How can I turn off the second LED?

    • Michael James on June 7, 2021 at 9:28 am

      Hi Biiancaa – great question, there are a lot of ways to do this, but it is hard to say what might be the issue without seeing code. It may be a timing, or logic issues, or any number of things.

      • biiancaa on June 8, 2021 at 3:02 am

        maybe a problem should be with the button, should I reset it?

  17. Moise Livius Florian on August 26, 2022 at 5:29 am

    you are a gold man! esti un om de aur !

  18. David Smith on January 12, 2023 at 4:22 am

    Hey there! It works fabulous with LEDs, thank you.
    Is it possible to control 2 relays with long press / short press?

    Thanks for any help you can offer.
    — David

    • Michael James on January 12, 2023 at 2:12 pm

      Thanks David! Per your question, yes, that is totally doable.

      In the code where we talk about the options, you’d have your code for controlling the relays. So you would be digitalWrite() to the different relays.

  19. David Smith on January 13, 2023 at 7:42 am

    I did as you suggested and it worked fabulously!

    I believe I tried every hard way / wrong way possible, I should have seen your easy way / successful way. I can only blame it on having having a “seniors moment”.

    Thank you sir, you are a friend and a scholar!

    — David

  20. David Smith on January 13, 2023 at 9:32 am

    I believe I may have a challenge for you this time: I have relay output on my short press / long press Arduino and now want to put relay input in place of the button. But when the relay coil is activated it freezes the short press / long press program, even when the relay was on a separate board controlled by a separate Arduino.
    If a relay is nothing more then a computer controlled switch I can not make this issue compute in my head.

    When I get free time again next winter I believe I will be taking your course.

    In the mean time any help you can offer would be greatly appreciated.

    — David.

    • Michael James on January 16, 2023 at 8:06 pm

      Good questions! Hard to say exactly what is up, but here are some general thoughts…

      When the you do a digitalWrite(), the pin state “latches”, so the pin stays HIGH, or LOW, or whatever you wrote it last…until, you do another digitalWrite() changing the state.

Leave a Comment