12 de jun de 2011

Projeto básico - Utilizando um teclado com o arduino e exibindo o resultado em um display de LCD


Teclados

Teclados são dispositivos de entrada normalmente utilizados para realizar a interface do homem com a máquina. Os teclados matriciais como o usado neste projeto são os mais conhecidos devido a sua arquitetura simples e fácil integração com microcontroladores.
Figura 1 - Teclado matricial estilo membrana.

Lendo os dados enviados por um teclado

Existem vários métodos de se ler dados enviados por um teclado e estes basicamente se diferenciam pela maneira com que são conectados a um microcontrolador, mas a lógica permanece a mesma.

No micro controlador as colunas são definidas como pinos de entrada e as linhas como pinos de saída.

 Figura 2 - Detalhe das conexões de um teclado matricial.


Primeiro definimos as linhas como pinos de saída em nível alto (HIGH) e as colunas como pinos de entrada com nível baixo (LOW).
Para detectar qual tecla foi pressionada cada linha recebe individualmente nível lógico alto e todas as colunas recebem nível baixo, o micro controlador espera alguma mudança de estado nas colunas, se uma tecla foi pressionada o nível alto será enviado para a entrada do micro processador, pois as colunas foram definidas como pinos de entrada.
Para garantir níveis altos e baixos nos pinos de entrada do microcontrolador podemos utilizar resistores de pull-up ou pull-down.

 Figura 3 - Esquema de funcionamento individual.

Analisando a imagem acima, sabemos que não teremos tensão na coluna C1 pois ela está  ligada a uma resistência de 10K e ao terra, mas se pressionarmos a chave que interliga L1 com C1 teremos 5 volts em cima do resistor, estes 5 volts serão interpretados como lógica alta pelo arduino toda vez que a chave for pressionada.

Interface

Todas as linhas deverão ser conectadas diretamente ao arduino e as colunas devem ser ligadas a uma resistência aterrada como mostra a figura abaixo:


Figura 4 - Esquema de ligação simplificado

Infelizmente em um teclado comercial como o de membrana não é possível ver as conexões internas, portanto deveremos medir continuidade em todos os contatos de saída.
Fixa-se uma ponta do multímetro em um dos terminais e se pressiona uma tecla (mantenha a tecla pressionada) e coloque a outra ponta do multímetro em outro terminal. Veja se entre esses dois pinos há condutividade, se não houver coloque a segunda ponta do multímetro em outros terminais até confirmar condutividade. Fazendo isto você terá descoberto  a união entre uma linha e uma coluna, continue com este procedimento até descobrir todas as colunas e todas as linhas.

O teclado de 4 linhas por 3 colunas utilizado neste projeto terá um total  de 7 saídas, cada saída será ligada ao arduino através de um fio ou conexão, veja abaixo os resultados que encontrei depois da medição com o multímetro.
  • COLUNA 1 = Fio 4
  • COLUNA 2 = Fio 3
  • COLUNA 3 = Fio 2
  • LINHA 1 = Fio 1
  • LINHA 2 = Fio 5
  • LINHA 3 = Fio 6
  • LINHA 4 = Fio 7

Após descobrir a função de cada fio, vamos definir em quais pinos eles entraram no arduino:


#define col1 13 // Com resistor de pull down                                                                
#define col2 12 // Com resistor de pull down 
#define col3 6 // Com resistor de pull down 
#define l1 10
#define l2 9
#define l3 8
#define l4 7


Figura 5 - Esquema de ligação das colunas com os resistores. As linhas devem ser ligadas diretas no arduino.



O código


#include <LiquidCrystal.h>  // Biblioteca com funcoes para uso de um LCD baseado no Hitachi HD 44780 
LiquidCrystal lcd(1, 0, 5, 4, 3, 2);// Define os pinos de ligacao do LCD ao arduino com esta ordem LiquidCrystal(rs, enable, d4, d5, d6, d7)
#define col1 13 // Com resistor de pull down                                                                
#define col2 12 // Com resistor de pull down 
#define col3 6 // Com resistor de pull down 
#define l1 10 // Linha 1
#define l2 9
#define l3 8
#define l4 7 // Linha 4

void setup()
{
/*lcd.begin(cols, rows) */
lcd.begin(20, 4); /* Tipo de LCD usado no meu caso de 20 colunas por 4 linhas */
lcd.print("    Central AVR!");
   
// Declarando as colunas como INPUT, fios 4,3,2 do teclado
pinMode(col1,INPUT); /* Coluna 1, fio 4 */
pinMode(col2,INPUT); /* Coluna 2, fio 3 */
pinMode(col3,INPUT); /* Coluna 3, fio 2 */

// Declarando as linhas como OUTPUT fios 1,5,6,7 do teclado
pinMode(l1,OUTPUT); /* Linha 1, fio 1 */
pinMode(l2,OUTPUT);
pinMode(l3,OUTPUT); 
pinMode(l4,OUTPUT); /* Linha 4, fio 7 */  
}

void loop() 
{
int l[]={l1, l2, l3, l4}; // Array de 4 posições contendo os 4 pinos de linhas
int i=0;  
int k=0;
int tecla_apertada=0;
for (i=0; i<4; i++)
{
digitalWrite(l1,LOW); 
digitalWrite(l2,LOW);
digitalWrite(l3,LOW);
digitalWrite(l4,LOW);
digitalWrite(l[i],HIGH); // Torna uma linha alta por vez
   k=i*3; // Responsavel pela mudança de valores nas linhas após cada ciclo do for
  if(digitalRead(col1)==HIGH) // Se alguma tecla da coluna 1 for apertada executa o código abaixo
  {
    delay(10);
    tecla_apertada=k+1;
    lcd.setCursor(0, 1); /* O Cursor iniciara na coluna zero linha 3 */
    lcd.print("Coluna 1: ");
    lcd.print(tecla_apertada);
    k=0; 
  }

  if(digitalRead(col2)==HIGH)
  {
    delay(10);
    tecla_apertada=k+2;
    lcd.setCursor(0, 2); /* O Cursor iniciara na coluna zero linha 3 */
    lcd.print("Coluna 2: ");
    lcd.print(tecla_apertada); 
    k=0;
  }
 if(digitalRead(col3)==HIGH)
  {
    delay(10);
    tecla_apertada=k+3;
    lcd.setCursor(0, 3); // O Cursor iniciara na coluna zero linha 3 
    lcd.print("Coluna 3: ");
    lcd.print(tecla_apertada);
    k=0; 
  }
}

}


Algumas explicações sobre o funcionamento do programa.

A parte mais "complexa" deste código reside no laço do for onde utilizei um array para organizar a mudança para lógica HIGH das linhas, lembrando que o mesmo deve ser feito individualmente.


for (i=0; i<4; i++)
{
digitalWrite(l1,LOW); 
digitalWrite(l2,LOW);
digitalWrite(l3,LOW);
digitalWrite(l4,LOW);
digitalWrite(l[i],HIGH); // Torna uma linha alta por vez
   k=i*3; // Responsavel pela mudança de valores nas linhas após cada ciclo do for
.
.
.
.
.
}


Supondo i=0 a condição do for será verdadeira e o código dentro do laço será executado, todas as linhas são setada em nível LOW e apenas a linha 1 será setada em nível HIGH pois i=0 e no array l[] posição zero temos l1.
 digitalWrite(l[0],HIGH); // Torna uma linha alta por vez

O código executará até o final das condições(IF) e se não não for pressionada nenhuma tecla novamente todas as linhas receberão nível lógico LOW e somente a linha 2 será setada em nivel HIGH pois i=1 e no array l[] posição um temos l2.
digitalWrite(l[1],HIGH); // Torna uma linha alta por vez

k=i*3 é uma jogada para retornar um valor condizente com a linha com lógica HIGH, novamente supondo  i=0 ou seja a primeira execução do for temos k=0*3 portanto k=0 se a primeira coluna foi acionada o valor a ser impresso será 1 pois tecla_apertada=k+1;
Supondo i=1 ou seja a segunda execução do for temos k=1*3 portanto k=3 se a terceira coluna foi acionada o valor a ser impresso será 6 pois  tecla_apertada=k+3;
 

 
Resultado final

4 comentários:

  1. Obrigado por compartilhar,
    sou iniciante e vai me ajudar a montar o meu teclado.

    Grande Abraço

    ResponderExcluir
  2. Que bom que foi útil, elaborei esse código quando estava fazendo meu tcc, li diversos exemplos na internet, mas não conseguia gostar deles, essa maneira que fiz IMHO é a mais didatica (tirando os vetores).

    ResponderExcluir
  3. Um codigo simples pra me dar uma ajuda: Quero apertar determinada tecla do meu teclado e na linha do display aparecer o * ao inves do numero. Obg

    ResponderExcluir
    Respostas
    1. Faça um IF

      if(tecla_apertada)==3) // por exemplo quando a tecla 3 é apertada imprime o *
      {
      delay(10);
      tecla_apertada=k+1;
      lcd.setCursor(0, 1); /* O Cursor iniciara na coluna zero linha 3 */
      lcd.print("Coluna 1: ");
      lcd.print("*");
      k=0;
      }

      Não testei mas deve resolver sua dúvida.

      Excluir