Simulación de manejo de keypads (teclados) en arduino

En el uso de microcontroladores una de las aplicaciones mas usadas es la interacción humana con el dispositivo, ya sea bien para modificar valores, configuración o cualquier otra, por ello es necesario contar con dispositivos adecuados para ello como botones o sensores, en cualquier caso es necesario controlar la interfaz con estos dispositivos, en este pequeño tutorial mostraremos como utilizar un teclado de varias teclas y su interacción con un microcontrolador, arduino.

Keypad
En general un keypad (teclado), es un periférico de entrada o dispositivo, en parte inspirado en el teclado de las máquinas de escribir, que utiliza una disposición de botones o teclas, para que actúen como palancas mecánicas o interruptores electrónicos que envían información, muchas veces se ha interactuado con uno, ya que esta presente en una gran cantidad de aplicaciones.
En la siguiente imagen veremos como es una conexión común en un teclado matricial de 16 teclas.
Es obviamente un arreglo en forma de matriz donde se reutilizan varios pines para la ubicación de la tecla presionada. dependiendo de la cantidad de botones a controlar sera la distribución y cantidad de pines
si utilizáramos solo 1 pin por cada tecla necesitaríamos el doble de los utilizados en esta configuración, pues bien usar una configuración como esta trae otros problemas.
Si bien disminuimos el numero de pines solo se puede presionar uno a la vez, la razón radica en la forma que deberíamos utilizar para realizar la lectura de botones.
Para cada lectura activamos uno y solo uno de los pines de columna en secuencia de forma tal de que cuando la columna 1 este en activo las otras estarán en inactivo , y se leerá las cuatro filas a la vez, así, si una de las filas registra una entrada, pues esta relación columna-fila nos dará cual fue la tecla presionada.
Por ejemplo si activamos la tecla e la matriz [1,1] fila 1, columna 1, cuando se este barriendo de unos las columnas y se leerá la palabra de 4 bits de las filas se vera [1000] si no hubiese presionada ninguna tecla no habría ninguna señal presente y se leería [0000] en la palabra de filas, es fácil pensar como implantar un pequeño código que realice esta función.
En el IDE de arduino ya existe una función perfectamente diseñada para esta tarea, la librería keypad.h.
En esta librería bastara con configurar algunos parámetros como la cantidad de teclas, los pines a usar en arduino, y los valores que arrojara si esta presionada dicha tecla. y sera suficiente para controlar un pequeño teclado.
En el diagrama que mostramos a continuación montaremos un keypad de 16 teclas lo controlaremos con micro atmega328 corazón de arduino, y veremos los resultados en el puerto serie virtual.
 esta es la configuración, para mas información sobre como simular un arduino click AQUI.
el código que usaremos es el siguiente.

/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'7','8','9','F'},
  {'4','5','6','E'},
  {'1','2','3','D'},
  {'A','0','B','C'}
};
byte rowPins[ROWS] = {3, 2, 9, 8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  char customKey = customKeypad.getKey();
  
  if (customKey != NO_KEY){
    Serial.print("tecla ");
    Serial.println(customKey);
  }
}
Al final, como en todos nuestros tutoriales, encontraremos un vídeo con la simulación.
Esta configuración sin embargo tiene algunos pro y contras, si bien esta fácilmente implementada, utiliza un gran cantidad de pines del micro, en general, su utilización entonces dependerá de la aplicación a desarrollar.
Existen otras formas mas eficientes de manejar los teclados, con arreglos de diodos e incluso con una modificación de la técnica charlieplexing, vamos a utilizar la de divisor de voltaje.
Esta técnica utiliza un solo puerto del micro para realizar la lectura, pero este puerto debe ser un convertidor analógico  digital. La razón es que para la lectura y discriminación de teclas realzaremos un divisor de voltaje convenientemente diseñado para obtener los valores de las teclas presionadas.
En el siguiente diagrama vemos la configuración y montaje del circuito.
Con una hoja de calculo se pueden estimar los valores que arrojara el A/D
Esta es la tabla que utilizamos.
En esta tabla se estiman los valores de voltaje y conversión A/D asi como una guía para las teclas
Incluimos un valor extra de A/D solo para estimar los valores medios.
el código utilizado es.

char teclado;
char ultecla;
void setup() {
  Serial.begin(9600);
}
void loop() {

  int entradateclado = analogRead(A0);

  if ( entradateclado > 834 ) 
    teclado='7';//
  else if ( entradateclado > 769 )
    teclado='4';//
  else if ( entradateclado > 716 )
    teclado='1';
  else if ( entradateclado > 674 )
    teclado='A';//
  else if ( entradateclado > 632 )
    teclado='8';//
  else if ( entradateclado > 594 )
    teclado='5';
  else if ( entradateclado > 562 )
    teclado='2';//
  else if ( entradateclado > 529 )
    teclado='0';//
  else if ( entradateclado > 496 )
    teclado='9';//
  else if ( entradateclado > 472 )
    teclado='6';//
  else if ( entradateclado > 452 )
    teclado='3';
  else if ( entradateclado > 392 )
    teclado='B';
  else if ( entradateclado > 334 )
    teclado='F';//
  else if ( entradateclado > 323 )
    teclado='E';
  else if ( entradateclado > 313 )
    teclado='D';
  else if ( entradateclado > 305 )
    teclado='C';

  if (ultecla != teclado){
    Serial.print("Tecla ");
    Serial.println(teclado);
    delay(500);
    ultecla=teclado;
  }
}
Este es un código básico pero expresa la idea de la función de esta técnica.
La desventaja de utilizar un A/D radica en la discriminación de teclas. también en la sensibilidad a variaciones de voltaje, y finalmente en la selección y valor real de los valores de resistencias a tomar.
El vídeo de la simulación...

En la próxima entrega veremos este circuito funcionando en protoboard.
Hasta la próxima...

7 comentarios:

  1. sabias que el valor de las resistencia que tomaste, y el programa que utilizas, funcionan pésimo en la vida real, las tolerancias de las resistencias y el factor térmico producen variaciones importantes en los valores esperados produciendo traslapes, sumado al hecho de que en contacto real el valor digital asciende hasta llegar al valor final y después desciende, esto produce que al presionar una tecla de un alto valor digital, el programa que tu tienes muestre que presionas una tecla de menor valor ya que como dije anteriormente el valor asiende antes de asentarse, produciendo posibles falsas pulsaciones, afortunadamente con una cuidadosa programacion y valores de resistencias conseguidas con potenciometros es posible distanciar lo suficiente cada valor asociado a cada tecla y lograr un funcionamiento aceptable.


    aun asi gracias por darme la idea de usar este método para integrar un teclado

    ResponderEliminar
  2. Ciertamente asus, tus comentarios son 100% acertados, la programación para la implantación real es mucho mas compleja, sin contar que se debe realizar un muestreo previo para visualizar los valores precisos, es necesario también incluir una rutina para discriminar los errores, Gracias por tus comentarios.
    AngelX

    ResponderEliminar
  3. agradezco tu respuesta si quieres cuando tenga tiempo, porque estoy hasta la cabeza con trabajo adjunto en el comentario la parte del código que utilice para el teclado y los valores de resistencias tomadas

    ResponderEliminar
  4. Gracias, asus, tus revisiones y código serán bien recibidos, y publicados junto con este tópico con su respectiva autoría...

    ResponderEliminar
  5. buen aporte.....tengo una pregunta.....
    como hago para controlar un video juego con arduino usando teclas y potenciometros?

    ResponderEliminar
    Respuestas
    1. Saludos Davier, Primero gracias por leernos, bueno lo de controlar los juegos pues depende de que juego es, tiene la ventaja de la comunicación serial, y hay algunas personas que han dedicado tiempo a integrarlos con MAME para otras plataformas es tal vez mas complejo, por ejemplo PPJoy se puede por serial pero debes hacer el programa y formatear para hacer la lectura correcta ese es un buen proyecto, si tengo tiempo le dedico algo la semana que viene...

      Eliminar
  6. ¡Muy buen artículo!

    He comprendido las diversas formas de conectar una matriz de teclas.
    Ahora bien, estoy intentando reciclar el teclado de un piano de juguete, y no acabo de entender la forma en que esta conectado y como distribuir las salidas a los pines de entrada del Arduino.
    Imagino que debería conectar las ocho salidas de uno de los conectores a 8 pines analógicos del Arduino (tendria que usar un Mega)y leer los valores en cada pin, aunque hay 4 teclas (de 33 a 37) que pienso repetirian valores, por estar conectadas directamente, sin pasar por resistencias.
    ¿He de conectar las otras cuatro salidas a otras cuatro entradas del microprocesador? Estoy muy confuso, no se por donde encararlo... a ver si me podeis ayudar.

    ¡Mil gracias!

    Esquema del teclado:
    http://i1250.photobucket.com/albums/hh526/arduinoxino/teclat_imaginarium_zpsryw8t9ac.png

    ResponderEliminar