Вы находитесь на странице: 1из 8

This page was exported from - Recursos para programadores

Export date: Thu Sep 5 3:15:58 2019 / +0000 GMT

ARD13 - Teclados matriciales


En este artículo vamos a aprender a manejar un teclado matricial. Se trata de una matriz de pulsadores, dispuestos "en cuadro", de
forma que hay tantos hilos de conexión como filas más columnas. Por ejemplo, supongamos el teclado típico de un cajero
automático. Tiene 16 pulsadores distribuidos en cuatro filas y cuatro columnas. Por lo tanto, podemos identificar cada pulsador con
una coordenada de fila y columna. Con un total de ocho hilos podemos identificar cada pulsador de forma inequívoca.

Figura 13.1. Un teclado matricial de 16 teclas.


En este capítulo aprenderemos cómo funcionan este tipo de teclados, pero aprenderemos también mucho sobre Arduino, librerías
externas, etc.
En la figura 13.1 vemos uno de los típicos teclados matriciales que se emplean con Arduino. Salvo que necesitáramos un teclado
más "duro" (para intemperie, p.e.) este modelo nos valdrá perfectamente. Se vende en cualquier tienda de electrónica por cuatro o
cinco euros.
El esquema de conexionado interno de los hilos es tal que cada uno de los cuatro primeros (de la izquierda del conector) está
conectado a una fila de pulsadores. Cada uno de los cuatro últimos (de la derecha del conector) está conectado a una columna de
pulsadores. De este modo, al pulsar cualquiera de las teclas, se identifica inequívocamente en qué fila y columna está la tecla
pulsada. En la figura 13.2 puedes ver un esquema del conexionado interno de los ocho hilos en los dieciséis pulsadores.

Figura 13.2. Esquema de hilos de un teclado matricial de 16 teclas.


Por ejemplo, si pulsas la tecla marcada con el 8 se cerrará el circuito entre los hilos 6 y 3. No se cerrará ningún otro circuito, y no
hay ninguna manera de que se cierre el circuito entre esos dos hilos si no es pulsando exactamente esa tecla.

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 1/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:15:58 2019 / +0000 GMT

En este capítulo vamos a conectar un teclado matricial a nuestro Arduino Uno y veremos, en la consola serie cada tecla que
pulsemos.
EL MONTAJE
El esquema electrónico del montaje es muy simple. Se trata de conectar los cuatro hilos de las filas (por ejemplo) a pines de salida, y
los cuatro de las columnas a pines de entrada. Así, dando señal a cada pin de salida, y comprobando si la señal llega a cada pin de
entrada, sabremos que tecla está pulsada.
Lo que haremos es que Arduino reconozca cada pulsación de una tecla del teclado matricial empleado. En este primer ejemplo no
procesaremos las pulsaciones, es decir, no las usaremos para, por ejemplo, configurar una clave de acceso o ningún otro uso. Solo
las registraremos. Más adelante, en este mismo artículo, veremos otro ejemplo más elaborado con esas pulsaciones. En la figura
13.3 ves el esquema completo.

Figura 13.3. El esquema teórico de este montaje.


En la figura 13.4 ves el montaje físico.

Figura 13.4. El montaje físico de este artículo.


Como puedes ver, es simple y cómodo de montar. Ahora veamos el sketch.
EL SKETCH
Vamos a empezar como siempre, reproduciendo el listado completo y analizándolo teóricamente paso a paso. Si lo pruebas
directamente, no te funcionará, porque antes es necesario un paso del que hablaremos enseguida, así que no seas impaciente y sigue
leyendo.
El listado completo de este sketch aparece a continuación:
#include <Keypad.h>
const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {13, 12, 11, 10}; //Pines para las filas.
byte Pins_Cols[] = {7, 6, 5, 4}; // Pines para las columnas.

char Teclas [Filas][Cols] = {


{'1','2','3','A'},

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 2/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:00 2019 / +0000 GMT

{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

char pulsacion;

Keypad Teclado1 = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

void setup() {
Serial.begin(9600);
}

void loop() {
pulsacion = Teclado1.getKey();
if (pulsacion) Serial.println(pulsacion);
}

Lo primero que hacemos es incluir en el código una librería llamada Keypad, que implementa funcionalidades para facilitar la gestión
de teclados.
Como ya hemos tenido ocasión de comprobar (y tendremos más en lo sucesivo), existen librerías específicas para facilitar la gestión
de distintos dispositivos (servomotores, pantallas LCD y ahora los teclados son sólo algunos ejemplos).
En los casos anteriores, las librerías las incluíamos directamente, porque ya forman parte, por defecto, del IDE de Arduino. En el
caso de la librería Keypad, aunque es oficial de Arduino, no forma parte de la instalación del IDE, por lo que es necesario descargarla
e instalarla previamente. Por eso te decía hace unas líneas, que el sketch, si lo tecleas así, sin más, no te va a funcionar. En el
próximo apartado vamos a ver como obtener librerías adicionales (bien sean oficiales de Arduino o de otros desarrolladores) e
incorporarlas a nuestro IDE. Por ahora, para la explicación teórica, vamos a considerar que ya tenemos la librería instalada. Después
que tú la instales, como te explicaré en este mismo capítulo, podrás probar el sketch y ver que efectivamente funciona sin problemas.
En la primera línea, incluimos la librería (suponiendo que ya la hayamos instalado), del modo habitual:
#include <Keypad.h>
Tenemos que definir el número de filas y columnas de nuestro teclado. Ten en cuenta que, en nuestro ejemplo, estamos usando un
teclado matricial muy sencillito, para empezar a familiarizarnos con estas técnicas. Nuestro teclado es de dieciséis teclas, con cuatro
filas y cuatro columnas. Sin embargo, lo que aquí aprendamos es perfectamente válido para cualquier teclado. Por ejemplo, un
teclado de ordenador, con 108 teclas, distribuido en 10 filas y 11 columnas, podría gestionarse también de la misma forma (aunque
el código, por supuesto, sería más engorroso).
const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
SOBRE FILAS Y COLUMNAS. Cuando hablamos de un teclado matricial, con el conexionado de los cables en filas y columnas,
estamos hablando de la forma en que los cables se conectan con los pulsadores, es decir, de la distribución lógica de los cables. En el
ejemplo que estamos viendo, nuestro teclado tiene cuatro filas y cuatro columnas, y, físicamente, los botones están dispuestos de esa
forma, pero esto no tiene por qué ser siempre así. Aunque los botones estén conectados en m filas y n columnas, físicamente pueden
estar dispuestos en otra configuración. Tal es el caso de un teclado de ordenador. Suelen tener 106 o 108 teclas, y el cableado
responde a una conexión matricial de 10 x 11, pero el teclado físico no está distribuido en esa disposición, sino de una forma que sea
cómoda de manejar para el operador. A nosotros, a la hora de programar un teclado desde Arduino, la disposición física no nos
importa. Lo que nos importa es la disposición cableada (lógica), es decir, cada tecla, con que fila y columna está conectada, con
independencia de dónde esté físicamente.
Ahora debemos indicar a que pines de la placa Arduino irán conectados los hilos que corresponden a las filas, y los que
corresponden a las columnas del teclado.
byte Pins_Filas[ = {13, 12, 11, 10}; //Pines para las filas.
byte Pins_Cols[ = {7, 6, 5, 4}; // Pines para las columnas.

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 3/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:00 2019 / +0000 GMT

Esto lo hacemos en dos matrices (una para los pines de las columnas y otra para los pines de las filas), porque así lo va a requerir
luego el uso de la librería Keypad. Declararlo así nos facilitará luego enormemente la tareas de programación del teclado. Las
matrices son de tipo byte. Aunque, en muchos casos, cuando definimos un pin lo hacemos como de tipo int, en realidad un dato de
tipo byte es suficiente para almacenar números hasta 127 con signo, y ahorramos espacio en memoria (Arduino no tiene demasiada).
Presta especial atención al orden en que se disponen los números de los pines en las matrices. Si ves el conexionado del circuito,
empezamos por la izquierda, tanto en las filas como en las columnas.
Definimos una variable llamada pulsacion, que contendrá un registro de la tecla que pulsemos en cada momento
char pulsacion;
Ahora definimos una matriz con los distintos caracteres que incorpora el teclado, así:
char Teclas [Filas
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Presta atención. Se trata de una matriz de dos dimensiones, que, hasta ahora, no habíamos empleado. Es una matriz de datos de tipo
char, de modo que cada elemento de la misma tendrá un carácter. Como va a tener dos dimensiones, al declararla establecemos dos
índices:
char Teclas [Filas
Como las constantes Filas y Cols ya están previamente declaradas, esto sería equivalente a haber puesto:
char Teclas [4
La cuestión es que la declaración que hemos empleado en el sketch es más clara a la hora de leer nosotros el código.
Una matriz de dos dimensiones es una matriz de matrices. Cada elemento de la primera matriz es, a su vez, una matriz:
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
En cada una de estas matrices, cada elemento es un carácter. Si te fijas, la primera matriz contiene los caracteres de la primera fila
del teclado, la segunda matriz contiene los caracteres de la segunda fila del teclado, y así sucesivamente.
Para acceder a un elemento concreto de una matriz bidimensional debemos indicar el nombre de la matriz, y los dos índices, como
unas coordenadas, teniendo en cuenta que, al igual que en las matices unidimensionales, los índices empiezan a contar desde cero.
Por ejemplo, si accedemos al elemento Teclas[1, estaremos accediendo a la matriz unidimensional declarada en la posición uno, que
es {'4','5','6','B'} y, dentro de esta, al elemento que hay en la posición 0, es decir, el 4.
Dicho de otro modo. Cada matriz unidimensional es un elemento de otra matriz más grande, que podríamos llamar global. Al
especificar los índices, el primero se refiere a la matriz unidimensional dentro de la global, y el segundo se refiere al elemento dentro
de la matriz unidimensional.
Fíjate cómo están dispuestos los caracteres en la matriz. La matriz que representa a la primera fila, {'1','2','3','A'}, no es la primera por
casualidad. En la definición de pines, La primera fila es la que va conectada al pin 13, que, en la definición de pines de filas, es el
que ocupa la primera posición. La segunda fila, {'4','5','6','B'}, contiene los caracteres que corresponden a la segunda fila del teclado.
En el circuito, esta se halla conectada al pin 12, que es el que ocupa la segunda posición en la matriz Pins_Filas. El mismo criterio se
emplea para las columnas. Dentro de cada fila, el carácter que aparece en primera posición es el que en el teclado está conectado al
hilo de columna que va al pin que aparece en primera posición en la matriz Pins_Cols.
Este modo de disponer las definiciones del teclado y de cada tecla, en su sitio adecuado, puede parecer un poco engorrosa la primera
vez que se ve (a mí, al menos, me costó bastante llegar a comprender toda la estructura globalmente). Sin embargo, una vez que se
entiende es de una lógica tan simple como eficiente, y permite a la librería una buena gestión del teclado. Te recomiendo que, si no
lo tienes muy claro (sobre todo, si no estás familiarizado con el uso de matrices bidimensionales), dediques unos minutos a analizar
las declaraciones de datos y el texto, para que, al menos, pilles por donde van los tiros.
A continuación, debemos definir un objeto de la clase Keypad, que representará a nuestro teclado. Esto se hace empleando el
constructor de la clase, así:
Keypad Teclado1 = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 4/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:00 2019 / +0000 GMT

El objeto, en este ejemplo, lo hemos llamado Teclado1. El constructor recibe cinco argumentos:

El primero es la función makeKeymap que, a su vez, recibe como argumento el nombre de la matriz bidimensional que hemos
definido para los caracteres de las teclas. Esta función no es del núcleo del lenguaje Arduino, sino que se ha importado al incluir la
clase Keypad. Hablaremos de esta función más adelante, en este mismo capítulo.
- El segundo argumento en el nombre de la matriz que incluye los pines donde están conectadas las filas del teclado.
- El tercer argumento en el nombre de la matriz que incluye los pines donde están conectadas las columnas del teclado.
- El cuarto argumento es el número de filas.
- El quinto y último es el número de columnas.

De este modo el constructor de la clase Keypad define un objeto que contiene todos los datos relativos al teclado y a la conexión con
la placa Arduino.
Dentro de la sección setup no hay nada especial que no conozcamos ya. Sólo se abre una conexión serie con la consola. De este
modo, cuando nuestro montaje esté operativo, podremos visualizar cada tecla que pulsemos.
En la sección loop lo primero que encontramos es que le asignamos a la variable pulsación lo que se lee, en ese momento, en el
teclado. El método getKey() se ocupa de realizar esa lectura. Como ves, la notación es la típica de la programación orientada a
objetos: Objeto.método().
pulsacion = Teclado1.getKey();
Si, en el momento de ejecutarse esta instrucción, no se está pulsando ninguna tecla, el método getKey() devuelve un valor false. Si se
está pulsando una tecla, el método getKey() devuelve el carácter que aparece en la matriz que corresponda a la fila y columna de la
tecla pulsada. Pero el método getKey() hace algo más. Si la tecla pulsada permanece pulsada, ignora este hecho, de forma que se
evitan repeticiones. Así, cuando pruebes el montaje, verás que si pulsas, por ejemplo, el 5 y lo mantienes pulsado, en la consola te
aparece un sólo 5. Hasta que no sueltes y pulses otra tecla (o la misma), no te aparecerá nada más en la consola.
En la segunda línea la sección loop se comprueba si hay un valor en la variable pulsacion (recuerda que, si no se ha pulsado nada, el
valor es false). Si lo hay, se envía a la consola.
Como ves, el teclado es un poco engorroso de configurar pero, una vez configurado correctamente, la librería que empleamos hace
que sea muy fácil la lectura y gestión de las pulsaciones.
AÑADIENDO LIBRERÍAS A ARDUINO
Como ya hemos comentado, la librería Keypad no forma parte, por defecto, del núcleo del IDE de Arduino. Si queremos poder
disponer de ella, lo primero que debemos hacer (una sóla vez) es descargarla de Internet y añadirla a nuestro IDE.
La página oficial de descarga de Keypad es: http://playground.arduino.cc/uploads/Code/keypad.zip. Pulsa el enlace y se te descargará
un archivo comprimido zip, que puedes guardar en cualquier parte de tu ordenador (en el escritorio, por ejemplo). Da lo mismo
(mientras lo tengas localizado) porque, tras instalar la librería, podrás borrar este archivo.
El hecho de que, una vez instalada la librería, puedas borrar el archivo, no significa que debas hacerlo. Dado que Arduino es un
entorno de desarrollo de código abierto, el archivo que te has descargado incluye cosas interesantes. Por ejemplo, el código fuente,
en C++ de la librería. Si dominas este lenguaje, quizá sientas curiosidad por echarle un vistazo, pero eso está fuera de los objetivos
de este artículo.
Ahora abrimos el IDE de Arduino. En la barra de menús, en la parte superior, pulsamos sobre la opción Programa, y se nos abrirá un
menú como el de la figura 13.5.

Figura 13.5. El menú Programa del IDE de Arduino


Desplazamos el puntero del mouse a la opción Importar Librería... y se nos abrirá otro menú con todas las librerías que ya tenemos, y
con una opción, al principio, que pone Añadir librería..., y que es la que nos interesa. Vemos la parte superior de este menú en la
figura 13.6.

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 5/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:00 2019 / +0000 GMT

Figura 13.6. El menú Importar Librerías del IDE de Arduino


Si pulsamos sobre el nombre de cualquiera de las librerías que ya aparecen listadas, veremos que se incluye directamente en el
sketch. Nosotros pulsaremos ahora sobre la opción Añadir librería... y se abrirá un cuadro de diálogo para que busquemos el archivo
keypad.zip, que hemos descargado de Internet. Lo abrimos y ya queda la librería incluida en el IDE de Arduino. A partir de aquí, ya
podemos cargar el sketch que hemos visto antes. Lo subimos a la placa Arduino de la forma habitual. Abrimos la consola de
comunicación serie y vemos como aparecen los caracteres de las teclas que pulsemos en el teclado.
Como vemos, las librerías de Arduino proporcionan funcionalidades que el núcleo del lenguaje no incorpora. Existen librerías para
manejar todo tipo de dispositivos. Las oficiales de Arduino pueden encontrarse en http://playground.arduino.cc/Code/Code, donde
aparece la lista completa de librerías que puedes añadir a tu IDE Arduino. Como ves, es una gran cantidad que, seguro, satisfarán
todas las necesidades que puedas llegar a tener.
Y ¿Dónde se almacena la nueva librería que hemos importado? ¿En el directorio de instalación del programa? No. Se almacena en
un directorio llamado libraries que se crea en la ruta donde guardamos nuestros sketches.
LA LIBRERÍA Keypad
Ahora que ya sabemos como importar la librería, y como incluirla en nuestro sketch, que hemos probado el montaje, y vemos que va
bien, vamos a conocer la librería Keypad un poco mejor, para saber lo que podemos hacer con ella.
Como vemos, la librería es muy fácil de usar. Ya conocemos el constructor, y el método getKey(). Ahora vamos a conocer las otras
posibilidades que pueden interesarnos para otros montajes:
El método waitForKey(). No recibe ningún argumento. Actúa de un modo muy similar a getKey(), devolviendo el carácter de la tecla
pulsada. La diferencia es que bloquea la ejecución del sketch Arduino hasta que se pulse una tecla. Esto quiere decir que no se
cambiará el estado de ningún LED, ni se llevará a cabo ninguna operación aritmética, ni ocurrirá NADA hasta que se pulse una
tecla. La excepción a esto son aquellas operaciones de Arduino que provocan interrupciones, tema del que hablaremos más adelante.
El método getState(). No recibe ningún argumento y devuelve una constante que nos indica el estado del teclado. Hay cuatro
posibilidades:

IDLE. El teclado está en reposo.


PRESSED. Se acaba de detectar la pulsación de una tecla.
RELEASED. Se acaba de detectar la liberación de una tecla pulsada.
HOLD. Se está manteniendo pulsada una tecla.

El método keyStateChanged(). No recibe argumentos. Devuelve un valor booleano que será true si se ha producido algún cambio en el
estado del teclado, o false, en caso contrario.
El método setHoldTime(int). Se emplea para establecer el número de milisegundos necesarios para que se detecte una pulsación en el
teclado. Si, por ejemplo, usamos la instrucción ObjetoTeclado.setHoldTime(50); el sketch ignorará una pulsación si esta dura menos de
50 milisegundos. Resulta muy útil para ignorar esas pulsaciones "rápidas" que se producen por error cuando desplazamos el dedo
sobre un teclado con teclas muy sensibles.
El método setDebounceTime(int). Establece un periodo en milisegundos durante el cual se ignoran pulsaciones consecutivas. Por
ejemplo, si usamos la instrucción ObjetoTeclado.setDebounceTime(50); estaremos indicándole al sketch que, tras soltar una tecla, se
debe bloquear el proceso durante 50 milisegundos, antes de poder detectar otra pulsación.

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 6/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:01 2019 / +0000 GMT

UNA VARIANTE
Vamos a escribir un sketch que le permita al usuario teclear cuatro dígitos numéricos (como un PIN de teléfono o de cajero
automático). Durante el tecleo, el usuario podrá pulsar la tecla *, lo que eliminará el último dígito pulsado. También podrá pulsar la
tecla D, lo que dejará el PIN en blanco, para empezar a teclear de nuevo. Una vez pulsados los cuatro dígitos del PIN, podrá pulsar la
A, para comprobar si dicho PIN coincide con el que tiene el sketch almacenado en memoria. El sketch completo es el siguiente:
#include <Keypad.h>
const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {13, 12, 11, 10}; //Pines Arduino para las filas.
byte Pins_Cols[] = {7, 6, 5, 4}; // Pines Arduino para las columnas.
char pulsacion;
String PIN_Tecleado = "";
String ClaveCorrecta = "3105";
byte numeroDeDigitos = 0;

char Teclas [Filas][Cols] = {


{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

Keypad Teclado1 = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

void setup() {
Serial.begin(9600);
Serial.println("Introduzca codigo de acceso:");
Serial.println("(*) Para corregir el ultimo numero pulsado.");
Serial.println("(D) Para corregir todo el codigo.");
Serial.println("(A) Para validar el codigo.");
}

void loop() {
pulsacion = Teclado1.getKey();
if (pulsacion) { // Si se ha pulsado una tecla.
if (pulsacion >= '0' && pulsacion <= '9' && numeroDeDigitos < 4){ // Si la pulsación es un dígito de 0 a 9 y hay menos de 4
dígitos en la clave.
numeroDeDigitos ++;
PIN_Tecleado += pulsacion;
Serial.print(pulsacion);
}
if (pulsacion == '*' && numeroDeDigitos > 0){ // Si se ha pedido borrar el último carácter, y hay caracter que borrar
numeroDeDigitos --;
PIN_Tecleado = PIN_Tecleado.substring(0, numeroDeDigitos);
Serial.println();
Serial.print(PIN_Tecleado);
}
if (pulsacion == 'D'){ // Si se ha pedido borrar toda la clave.
numeroDeDigitos = 0;
PIN_Tecleado = "";

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 7/8 |
This page was exported from - Recursos para programadores
Export date: Thu Sep 5 3:16:01 2019 / +0000 GMT

Serial.println();
}
if (pulsacion == 'A'){ // Se ha pedido validar la clave introducida.
Serial.println();
if (numeroDeDigitos == 4){
if (PIN_Tecleado == ClaveCorrecta){
Serial.println("La clave es correcta");
} else {
Serial.println("La clave NO es correcta");
}
PIN_Tecleado = "";
numeroDeDigitos = 0;
} else {
Serial.println ("El codigo debe tener cuatro dígitos");
Serial.print(PIN_Tecleado);
}
}
}
}
No vamos a entrar en detalles, porque, a estas alturas, ya conoces lo necesario para analizar el código, y comprender como funciona.
Si quiero hacer una consideración final. La consola serial de Arduino ofrece bastantes limitaciones: no permite borrar el contenido,
no permite letras acentuadas, etc. En un artículo posterior veremos como resolver estos problemas.

Output as PDF file has been powered by [ Universal Post Manager ] plugin from www.ProfProjects.com | Page 8/8 |

Вам также может понравиться