For beginners: The simple way to program for multiple buttons

Beginners usually run into the following troubles:

  • floating input issue
  • chattering issue
  • detecting the pressed and released events
  • managing timestamp when debouncing for multiple buttons

With the ezButton library, the beginners do NOT need to worry above problems.

ezButton features:

  • Uses the internal pull-up resistor to avoid the floating value
  • Supports debounce to eliminate the chattering phenomenon
  • Supports the pressed and released events
  • Supports the counting (for FALLING, RISING and BOTH)
  • Easy to use with multiple buttons
  • All functions are non-blocking

Installation Instruction and Library Reference

Example code:
Multiple Buttons: debouncing + state + counting + detecting the pressing and releasing events

#include <ezButton.h>

ezButton button1(6);  // create Button object that attach to pin 6;
ezButton button2(7);  // create Button object that attach to pin 7;

void setup() {
  Serial.begin(9600);
  button1.setDebounceTime(50); // set debounce time to 50 milliseconds
  button2.setDebounceTime(50); // set debounce time to 50 milliseconds
  button1.setCountMode(COUNT_FALLING);
  button2.setCountMode(COUNT_FALLING);
}

void loop() {
  button1.loop(); // MUST call the loop() function first
  button2.loop(); // MUST call the loop() function first

  int btn1State = button1.getState();
  int btn2State = button2.getState();
  Serial.print("button 1 state: ");
  Serial.println(btn1State);
  Serial.print("button 2 state: ");
  Serial.println(btn2State);

  unsigned long btn1Count = button1.getCount();
  unsigned long btn2Count = button2.getCount();
  Serial.print("button 1 count: ");
  Serial.println(btn1Count);
  Serial.print("button 2 count: ");
  Serial.println(btn2Count);

  if(button1.isPressed())
    Serial.println("The button 1 is pressed");

  if(button1.isReleased())
    Serial.println("The button 1 is released");

  if(button2.isPressed())
    Serial.println("The button 2 is pressed");

  if(button2.isReleased())
    Serial.println("The button 2 is released");
}

When using many buttons, we can puts buttons into an array

Example of 5 buttons using array.

#include <ezButton.h>

const int BUTTON_NUM = 5;

const int BUTTON_1_PIN = 2;
const int BUTTON_2_PIN = 3;
const int BUTTON_3_PIN = 4;
const int BUTTON_4_PIN = 5;
const int BUTTON_5_PIN = 6;

ezButton buttonArray[] = {
	ezButton(BUTTON_1_PIN), 
	ezButton(BUTTON_2_PIN), 
	ezButton(BUTTON_3_PIN), 
	ezButton(BUTTON_4_PIN), 
	ezButton(BUTTON_5_PIN)
};

void setup() {
	Serial.begin(9600);

	for(byte i = 0; i < BUTTON_NUM; i++){
		buttonArray[i].setDebounceTime(50); // set debounce time to 50 milliseconds
	}
}

void loop() {
	for(byte i = 0; i < BUTTON_NUM; i++)
		buttonArray[i].loop(); // MUST call the loop() function first

	for(byte i = 0; i < BUTTON_NUM; i++) {
		if(buttonArray[i].isPressed()) {
			Serial.print("The button ");
			Serial.print(i + 1);
			Serial.println(" is pressed");
		}

		if(buttonArray[i].isReleased()) {
			Serial.print("The button ");
			Serial.print(i + 1);
			Serial.println(" is released");
		}
	}
}

The library is also useful in the case of using a single button.

If you have any comment or suggestion, please feel free to comment here.

I've seen several tutorials on how to read a group of switches, and output something that indicates which switch has been pushed.

I'm trying to write a sketch that will allow me to read 3 switches as a binary value of 0-7, and output different text to an LCD for each of the 8 results.

Is there a tutorial for such a project?

It can be as simple as this code:

btn1State = button1.getState();
btn2State = button2.getState();
btn3State = button3.getState();

binaryState = btn1State | (btn2State << 1) | (btn3State << 2)

DyfedPugh:

binaryState = btn1State | (btn2State << 1) | (btn3State << 2)

This line might be more intuitive for the OP:

theNumber = (1 * digitalRead(lowPin)) + (2 * digitalRead(midPin)) + (4 * digitalRead(highPin));

Great! Thank you for the additional tip.

Since beginners may get into trouble because of the floating input and chattering issue. I recommend using the library instead of digitalRead() function. The library used the internal pull-up resistor to avoid the floating value and implemented the debouncing to eliminate the chattering phenomenon.

Your code can be modified to:

btn1State = button1.getState();
btn2State = button2.getState();
btn3State = button3.getState();

binaryState = (1* btn1State)  +  (2 * btn2State) + (4 * btn3State)

IoT_hobbyist: Great! Thank you for the additional tip.

Since beginners may get into trouble because of the floating input and chattering issue. I recommend using the library instead of digitalRead() function. The library used the internal pull-up resistor to avoid the floating value and implemented the debouncing to eliminate the chattering phenomenon.

Your code can be modified to:

btn1State = button1.getState();
btn2State = button2.getState();
btn3State = button3.getState();

binaryState = (1* btn1State)  +  (2 * btn2State) + (4 * btn3State)

Thank you so much for the reply!

As a newb to programming, this is a great explanation of reading the switches as a group, rather than individual switches. That's been a major stumbling block to this project so far.

I've been able to find the setup (using the buttons library and the above explanation), and display the result (using the "case" reference and experimenting with null inputs for the LCD), but the gap between the two is how to read (you recommended not using the digitalRead function?) and manage the data. I'm kinda stumped at this point.

I hate to sound like I'm asking the experts to solve my equation for me. I'd really like to figure it out myself. What I am asking the experts is if they can point me to the reference to a statement or group of statements that I can research to figure out the answer.

Thanks again!

Rob

@RDF_MIDI, you can figure it out by yourself by referring to these tutorials:

smithhennry: Thank you for this information for the new members in the forum, I am also a new member in this forum.

You are welcome!

Hmmm nice info, button debouncing has always been a headache for me. I will check out your code.

Thank you, nice tips :)

I was just looking for something to simplify button reading, and this looks like it would be great! I will look into this!

This is great mate! but im currently in some odd problem, when i list more than 10 buttons it gives me compiling errors...

What (else) im doing wrong? jaja

canguroso: This is great mate! but im currently in some odd problem, when i list more than 10 buttons it gives me compiling errors...

What (else) im doing wrong? jaja

What was shown in error log?

andrewsness: I liked the detailed explanation, thank you very much for that and respect!

I am very happy to hear that.

louise-t: Hello Thanks for posting so good for new members.

I am happy to hear that. Thank you for your feedback.

Hi There.

I get a compile error when i try to compile your array example.

Your first example compiles and runs without issue...

Any help appreciated.

Thanks

Here is the error output:

"C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86_mdqgnx93n4wtt\hardware\tools\avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino" "-IC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86_mdqgnx93n4wtt\hardware\arduino\avr\variants\standard" "-IC:\Users\dragy\OneDrive\Documents\Arduino\libraries\ezButton\src" "C:\Users\dragy\AppData\Local\Temp\arduino_build_612579\sketch\Relay_Test_Setup1.ino.cpp" -o "C:\Users\dragy\AppData\Local\Temp\arduino_build_612579\sketch\Relay_Test_Setup1.ino.cpp.o" C:\Users\dragy\OneDrive\Documents\Arduino\Relay_Test_Setup1\Relay_Test_Setup1.ino: In function 'void setup()': Relay_Test_Setup1:23:17: error: request for member 'setDebounceTime' in 'buttonArray', which is of non-class type 'ezButton [5]' buttonArray.setDebounceTime(50); // set debounce time to 50 milliseconds ^~~~~~~~~~~~~~~ C:\Users\dragy\OneDrive\Documents\Arduino\Relay_Test_Setup1\Relay_Test_Setup1.ino: In function 'void loop()': Relay_Test_Setup1:29:17: error: request for member 'loop' in 'buttonArray', which is of non-class type 'ezButton [5]' buttonArray.loop(); // MUST call the loop() function first ^~~~ Relay_Test_Setup1:32:21: error: request for member 'isPressed' in 'buttonArray', which is of non-class type 'ezButton [5]' if (buttonArray.isPressed()) { ^~~~~~~~~ Relay_Test_Setup1:38:21: error: request for member 'isReleased' in 'buttonArray', which is of non-class type 'ezButton [5]' if (buttonArray.isReleased()) { ^~~~~~~~~~ Using library ezButton at version 1.0.3 in folder: C:\Users\dragy\OneDrive\Documents\Arduino\libraries\ezButton exit status 1 request for member 'setDebounceTime' in 'buttonArray', which is of non-class type 'ezButton [5]'

Please post your code. Do not forget to put the code inside code tag

HI thanks for replying… I used a direct copy of your array example (I’ve copied it out of my sketch in case I dropped a character on the initial copy).

#include <ezButton.h>

const int BUTTON_NUM = 5;

const int BUTTON_1_PIN = 2;
const int BUTTON_2_PIN = 3;
const int BUTTON_3_PIN = 4;
const int BUTTON_4_PIN = 5;
const int BUTTON_5_PIN = 6;

ezButton buttonArray[] = {
  ezButton(BUTTON_1_PIN),
  ezButton(BUTTON_2_PIN),
  ezButton(BUTTON_3_PIN),
  ezButton(BUTTON_4_PIN),
  ezButton(BUTTON_5_PIN)
};

void setup() {
  Serial.begin(9600);

  for (byte i = 0; i < BUTTON_NUM; i++) {
    buttonArray.setDebounceTime(50); // set debounce time to 50 milliseconds
  }
}

void loop() {
  for (byte i = 0; i < BUTTON_NUM; i++)
    buttonArray.loop(); // MUST call the loop() function first

  for (byte i = 0; i < BUTTON_NUM; i++) {
    if (buttonArray.isPressed()) {
      Serial.print("The button ");
      Serial.print(i + 1);
      Serial.println(" is pressed");
    }

    if (buttonArray.isReleased()) {
      Serial.print("The button ");
      Serial.print(i + 1);
      Serial.println(" is released");
    }
  }
}

You need to change all buttonArray. to buttonArray[i].
For example buttonArray[ i ].setDebounceTime(50);

And success..

Now to insert my code to see what I can break :)

thanks for that... perhaps you could change that in the given example...

Peace

Oh, some characters are escaped. I am going to update it