Lendo vários botões

Vamos aprender sobre a função analogRead(), e como utilizá-la para realizar a leitura de diferentes botões.

!Informações Importantes

Você pode estar pensando em qual seria a dificuldade de realizar a leitura de muitos botões, pois bastaria ligar cada um deles a um pino diferente do Arduino, e depois fazer a leitura do estado digital mesmos através da função digitalRead(). Porém, isso acarretaria no uso de vários pinos, e apesar dos 20 pinos presentes no Arduino parecerem muito, eles acabam bem rápido quando se aumenta a complexidade do projeto. Portanto, seria uma boa ideia se pudéssemos economizar o número de pinos utilizados, ligando vários botões no mesmo pino por exemplo. Mas será que isso é possível?

Isso é possível e é o que acontece no Nanoshield Interface. Todos os botões SEL, LEFT, UP, DOWN e RIGHT estão ligados ao pino A0 do Arduino, sendo possível de diferenciá-los através do valor de tensão lido neste pino.

!Identificando os Componentes

Na figura abaixo, podemos identificar os botões presentes no Nanoshield Interface.

Botões Interface

!Componentes de código

Analog Input: analogRead([pino])

Essa função realiza a leitura do valor de tensão analógico presente em um pino do Arduino. Diferentemente do valor digital, que só pode assumir estados de 0 ou 5 Volts, ou HIGH/LOW ou ainda 0/1, uma tensão analógica pode assumir qualquer valor entre 0 e 5 Volts. Desse modo, a função analogRead() irá mapear o valor de tensão entre 0 e 5 volts presente em um pino, para valores inteiros entre 0 e 1023. Pode parecer complicado, mas você vai entender melhor analisando o restante do projeto.

Assim como na função digitalRead(), há apenas um parâmetro para a função analogRead(), que é o número do pino de entrada que você quer ler, por exemplo analogRead(A0) para ler a tensão analógica presente no pino A0. Porém, devemos sempre lembrar que a função analogRead()funciona apenas para os pinos nomeados com a letra "A", ou seja, de A0 até A7.

Diferentemente de um botão normal, que pode somente pode assumir valores digitais como ABERTO/FECHADO ou 0/1, os botões do Nanoshield Interface estão ligados através de um divisor resistivo, gerando uma tensão diferente para cada botão que é pressionado. Dessa forma, pode-se detectar o botão com uma simples leitura analógica.

Para saber qual botão está sendo pressionado, é só verificar em qual intervalo de valores o pino A0 se encontra:

Botão Valor de Leitura
RIGHT 0 a 69
UP 70 a 230
DOWN 231 a 407
LEFT 408 a 630
SEL 631 a 896
Nenhum 897 a 1023
Tabela de equivalência

!Executando no Arduino

O código abaixo mostra no monitor serial do Arduino qual dos botões foi apertado. Para executar, faça o upload do código no Arduino, e depois abra o monitor serial, apertando o botão indicado na figura abaixo:

//Pino ligado ao push-button
int buttonPin = A0;
//Variavel para fazer a checagem
int buttonState;

void setup()
  {
  // Define o pino do botao como entrada
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // Verifica se o estado do botao foi alterado 
  buttonState = analogRead(buttonPin);
  // Limpa qualquer ruido      
  buttonState = 1023;
  // Enquanto nenhum botao está sendo pressionado realiza a leitura novamente
  while (buttonState >= 897)
  {
    buttonState = analogRead(buttonPin);
  } 
  // Se o valor  inferior a 897 significa que algum botão foi apertado
  if (buttonState < 897)
    { 
      // Se o botão Right está sendo apertado  
      if (buttonState < 69)
      {
        Serial.println("O botao RIGHT foi apertado!");       
      } 
      // Se o botão UP está sendo apertado
      if (buttonState >= 69 && buttonState <= 230)
      {
        Serial.println("O botao UP foi apertado!");
      }
      // Se o botão DOWN está sendo apertado
      if (buttonState >= 231 && buttonState <= 407)
      { 
        Serial.println("O botao DOWN foi apertado!");
      }
      // Enquanto o botão LEFT está sendo apertado
      if (buttonState >= 408 && buttonState <= 630)
      {
        Serial.println("O botao LEFT foi apertado!");
      }
      // Se o botão SEL está sendo apertado
      if (buttonState >= 631 && buttonState <= 896)
      { 
        Serial.println("O botao SEL foi apertado!");
      } 
    }    
    delay(100); 
}  

!Sua vez!

Tente modificar o código acima para que o buzzer também faça um barulho diferente para cada botão.

Resposta

//Pino ligado ao push-button
int buttonPin = A0;
//Pino ligado ao buzzer
int buzzer = 5; 
//Variavel para fazer a checagem
int buttonState;

void setup()
  {
  // Define o pino do botao como entrada
  pinMode(buttonPin, INPUT);
  // Define o pino do Buzzer como Saida
  pinMode(buzzer,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Verifica se o estado do botao foi alterado 
  buttonState = analogRead(buttonPin);
  // Limpa qualquer ruido      
  buttonState = 1023;
  // Enquanto nenhum botao está sendo pressionado realiza a leitura novamente
  while (buttonState >= 897)
  {
    buttonState = analogRead(buttonPin);
  } 
  // Se o valor  inferior a 897 significa que algum botão foi apertado
  if (buttonState < 897)
    { 
      // Se o botão Right está sendo apertado  
      if (buttonState < 69)
      {
        Serial.println("O botao RIGHT foi apertado!");
        // Se o botão está pressionado, aciona o Buzzer na frequência relativa ao Dó
        tone(buzzer,261);
        delay(200);
        noTone(buzzer);       
      } 
      // Se o botão UP está sendo apertado
      if (buttonState >= 69 && buttonState <= 230)
      {
        Serial.println("O botao UP foi apertado!");
        // Se o botão está pressionado, aciona o Buzzer na frequência relativa ao Ré
        tone(buzzer,293);
        delay(200);
        noTone(buzzer);
      }
      // Se o botão DOWN está sendo apertado
      if (buttonState >= 231 && buttonState <= 407)
      { 
        Serial.println("O botao DOWN foi apertado!");
        // Se o botão está pressionado, aciona o Buzzer na frequência relativa ao Mi
        tone(buzzer,329);
        delay(200);
        noTone(buzzer);
      }
      // Enquanto o botão LEFT está sendo apertado
      if (buttonState >= 408 && buttonState <= 630)
      {
         Serial.println("O botao LEFT foi apertado!");
        // Se o botão está pressionado, aciona o Buzzer na frequência relativa ao Fá
        tone(buzzer,349);
        delay(200);
        noTone(buzzer);
      }
      // Se o botão SEL está sendo apertado
      if (buttonState >= 631 && buttonState <= 896)
      { 
        Serial.println("O botao SEL foi apertado!");
        // Se o botão está pressionado, aciona o Buzzer na frequência relativa ao Sol
        tone(buzzer,392);
        delay(200);
        noTone(buzzer);
      } 
    }    
    delay(100); 
}