12 de abril de 2021

Do bit Ao Byte

Embarcados, Linux e programação

Menu com teclado matricial com Arduino

Menu com teclado matricial

Vi que alguém procurou por menu com teclado matricial no Arduino e não por coincidência (já que fiz a maquineta do Banco Imobiliário usando um), pensei nas formas de usar o teclado matricial. Apesar de ser um artigo bem simples, não deixa de ser interessante por abordar duas formas de usar o teclado matricial: chamando-o constantemente em um loop, e a segunda, chamando uma função de leitura do teclado que só é executada através de um evento, seja ele qual for. Vamos ver as duas formas de implementar.

Wiring do teclado matricial 4×4

A conexão é extremamente simples, bastando definir em série os pinos correspondentes. Por exemplo, do pino 6 ao pino 13. Como fiz no mega, usei números diferentes, mas tanto faz se é ESP8266, Arduino UNO, Mega ou outra coisa. Para habilitá-lo, siga o procedimento desse artigo. Com o código desse artigo referenciado já temos uma leitura contínua na função loop(), mas isso não é o suficiente para constituir um menu, então vamos incrementar o código de exemplo, criando agora um menu.

Leitura contínua do teclado

Nesse primeiro exemplo, vamos definir o teclado como principal componente do programa. Assim sendo, ele estará constantemente disponível para interação direta com o programa. Vamos definir apenas 3 chamadas, mas podemos inserir quantos itens quisermos, inclusive ter submenus. Vamos usar a serial para interagir, mas se deseja usar display, basta enviar as mensagens da serial para o display escolhido.

Teremos então:

1 – Levantar o pino 13

2 – Baixar pino 13

3 – Blink no pino 13

Vamos usar o LED do pino 13 apenas para servir como atuador. A opção 1 do menu fará o LED ligar.

A opção 2 do menu fará o LED desligar. Não tem problema se já estiver desligado, porque simplesmente vamos colocar o pino em LOW.

Leitura limitada do teclado

A opção 3 do menu fará o LED piscar. Por quanto tempo? – Bem, deixemos o usuário decidir o intervalo e o número de vezes, capturando os valores dentro da função de blink:

– Seleciona intervalo do blink.

– Seleciona número de piscadas.

Com isso temos as duas formas de operar o teclado: na primeira, lemos o valor que entrar e procuramos por ele no menu. Se for válido, chamamos a função correspondente.

Se for selecionada a opção 3, então devemos chamar uma função que leia em millis o intervalo do blink, e em seguida leia o número de piscadas. Para concluir cada item do menu, usaremos cerquilha (#) como finalizador de operação – como se fosse o Enter. Ao terminar a primeira leitura, a função deverá ser reentrante, para assim alimentar a segunda variável, que armazenará o número de vezes que o LED deve piscar.

Código do menu com teclado matricial

Já temos definido como desejamos que o teclado funcione, agora resta implementar o código. A parte de configuração do teclado será sempre a mesma, então atenha-se às funções de controle e operação do menu com teclado matricial:

#include <Arduino.h>
#include <Keypad.h>

const byte ROWS = 4; 
const byte COLS = 4; 

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {32, 34, 36, 38}; 
byte colPins[COLS] = {40, 42, 44, 46}; 

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

char menuChoice = '-';

void ledOnOff(uint8_t value);
void ledBlink();

String readKeyPad();

void setup(){
    Serial.begin(9600);
    delay(2000);
    Serial.println("-=-= MENU =-=-");
    Serial.println("1 - ligar LED");
    Serial.println("2 - Desligar LED");
    Serial.println("3 - Blink");

    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);
}

void loop(){
  char customKey = customKeypad.getKey();
  
  if (customKey){
    if (customKey-48 == 0 || customKey-48 == 1){
        ledOnOff(customKey-48);
    }
    else if (customKey-48 == 3){
        ledBlink();
    }
  }
}

String readKeyPad(){
    char customKey = customKeypad.getKey();
    
    String value = "";
    while (customKey != '#'){ 
        if (customKey){
            if (customKey == '*'){
                Serial.println("matriz limpa");
                value = "";
            }
            else{
                Serial.print(customKey);
                value = value + customKey;
            }   
        }
        customKey = customKeypad.getKey();
    }
    return value;
    
}

void ledOnOff(uint8_t value){
    digitalWrite(13,value);
    Serial.println(value > 0 ? "LED ligado" : "LED desligado");
    Serial.println(value);
}

void ledBlink(){
    Serial.println("\nEscolha o intervalo em ms (# para finalizar)");
    String interval = readKeyPad();
    Serial.println("\nEscolha o numero de ciclos (# para finalizar)");
    String blinks   = readKeyPad();
    uint8_t pin_state = digitalRead(13);
    for (uint8_t i=0; i< blinks.toInt();i++){
        pin_state = !pin_state;
        digitalWrite(13, pin_state);
        delay(interval.toInt());
    }
}

Como comentei, é um artigo simples, mas deve ajudar quem está iniciando ou quer pegar um atalho. Não tem tratamento de exceções também, o que é fundamental para não haver falhas como, por exemplo, o usuário entrar com um valor inválido para piscar o LED. A saída na serial:

Menu com teclado matricial

Onde comprar o teclado matricial?

Esse teclado matricial você encontra na CurtoCircuito, cujo link para o keypad é esse.

Até a próxima!

Revisão: Ricardo Amaral de Andrade