Reading multiple buttons

Let’s now learn about the analogRead() function, as well as how to use it for reading different buttons.

!Important Information

You may be thinking how difficult it would be to read several buttons, because you could just connect each of them to a different pin on Arduino and then read their digital states using digitalRead(). However, this would make you use a lot of pins and, even though 20 Arduino pins may seem a lot, they run out very quickly as the project gets more complex. Therefore, it’d be a good idea if we could use less pins, connecting various buttons to the same pin, for example. But is this possible?

This is possible and it is what happens on the Interface Nanoshield. All the buttons (SEL, LEFT, UP, DOWN and RIGHT) are connected to pin A0 on Arduino, being it possible to know which one is pressed just by reading the voltage value on this pin.

!Identifying the Components

On the figure below, we can see the buttons on the Interface Nanoshield.

Interface Buttons

!Code Components

Analog Input: analogRead([pin])

This function reads the analog voltage value present in an Arduino pin. Unlike the digital value, that can be only 0 or 5 Volts, or LOW/HIGH or 0/1, an analog voltage can have any value between 0 and 5 Volts. This way, analogRead() will map the pin’s voltage value from 0 to 5 Volts to integer values between 0 and 1023. This may seem complicated, but you’ll understand it better by analysing the rest of the project.

Like in digitalRead(), there is only one parameter for analogRead(), that is the input pin number you want to read. For example, analogRead(A0) to read an analog voltage at pin A0. However, we must always keep in mind that analogRead() works only for the pins that have the letter “A" in the name. That means from A0 to A7.

Unlike a normal button, which can only have digital values like OPEN/CLOSED or 0/1, the Interface Nanoshield’s buttons are connected through a voltage divider, which generates a different voltage for each button that is pressed. This way, you can detect the button with a simple analog reading.

In order to know which button is being pressed, you just have to know in which value range the pin A0 is:

Button Reading Value
RIGHT 0 to 69
UP 70 to 230
DOWN 231 to 407
LEFT 408 to 630
SEL 631 to 896
None 897 to 1023
Equivalence Table

!Running on Arduino

The code below shows on the serial monitor on Arduino’s IDE which button was pressed. To run the code, upload it to Arduino and then open the serial monitor, pressing the button indicated on the figure below:

//Pin connected to the pushbutton
int buttonPin = A0;
//Variable to check the button state
int buttonState;

void setup()
  {
  // Defines the button pin as input
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // Checks if the button state has changed 
  buttonState = analogRead(buttonPin);
  // Cleans the noise     
  buttonState = 1023;
  // While no button is pressed, reads again
  while (buttonState >= 897)
  {
    buttonState = analogRead(buttonPin);
  } 
  // if the value is lower that 897, no button was pressed
  if (buttonState < 897)
    { 
      // if button RIGHT is being pressed
      if (buttonState < 69)
      {
        Serial.println("The button RIGHT was pressed!");  
      } 
      // If the button UP is pressed
      if (buttonState >= 69 && buttonState <= 230)
      {
        Serial.println("The button UP was pressed!");
      }
      // If the button DOWN is pressed
      if (buttonState >= 231 && buttonState <= 407)
      { 
        Serial.println("The button DOWN was pressed!");
      }
      // If the button LEFT is pressed
      if (buttonState >= 408 && buttonState <= 630)
      {
         Serial.println("The button LEFT was pressed!");
      }
      // If the button SEL is pressed
      if (buttonState >= 631 && buttonState <= 896)
      { 
        Serial.println("The button SEL was pressed!");
      } 
    }    
    delay(100); 
}  

!Your Turn!

Try modifying the code above so that the buzzer also makes some different sounds for each button.

Answer

//Pin connected to the pushbutton
int buttonPin = A0;
//Pin connected to the buzzer
int buzzer = 5; 
//Variable to check the button state
int buttonState;

void setup()
  {
  // Defines the button pin as input
  pinMode(buttonPin, INPUT);
  // Defines the buzzer pin as output
  pinMode(buzzer,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Checks if the button state has changed 
  buttonState = analogRead(buttonPin);
  // Cleans the noise     
  buttonState = 1023;
  // While no button is pressed, reads again
  while (buttonState >= 897)
  {
    buttonState = analogRead(buttonPin);
  } 
  // if the value is lower that 897, no button was pressed
  if (buttonState < 897)
    { 
      // if button RIGHT is being pressed
      if (buttonState < 69)
      {
        Serial.println("The button RIGHT was pressed!");
        // if the button is being pressed, the buzzer plays the musical note C
        tone(buzzer,261);
        delay(200);
        noTone(buzzer);       
      } 
      // If the button UP is pressed
      if (buttonState >= 69 && buttonState <= 230)
      {
        Serial.println("The button UP was pressed!");
        // if the button is being pressed, the buzzer plays the musical note D
        tone(buzzer,293);
        delay(200);
        noTone(buzzer);
      }
      // If the button DOWN is pressed
      if (buttonState >= 231 && buttonState <= 407)
      { 
        Serial.println("The button DOWN was pressed!");
        // if the button is being pressed, the buzzer plays the musical note E
        tone(buzzer,329);
        delay(200);
        noTone(buzzer);
      }
      // If the button LEFT is pressed
      if (buttonState >= 408 && buttonState <= 630)
      {
         Serial.println("The button LEFT was pressed!");
        // if the button is being pressed, the buzzer plays the musical note F
        tone(buzzer,349);
        delay(200);
        noTone(buzzer);
      }
      // If the button SEL is pressed
      if (buttonState >= 631 && buttonState <= 896)
      { 
        Serial.println("The button SEL was pressed!");
        // if the button is being pressed, the buzzer plays the musical note G
        tone(buzzer,392);
        delay(200);
        noTone(buzzer);
      } 
    }    
    delay(100); 
}