OBJETIVOS
MATERIAL REQUERIDO
Un Arduino Mega. | |
Un shield TFT LCD 3.5″ táctil. |
INTRODUCCIÓN
Nuestra intención con esta sesión es crear una interfaz en la pantalla que simule un control de acceso mediante clave. Es decir, dibujaremos en la pantalla los botones necesarios del 0 al 9 y esperaremos a que se introduzca la clave correcta.
En caso de hacerlo cambiaremos de pantalla y mostraremos el mensaje «PUERTA ABIERTA», y en caso contrario mostraremos la palabra«Incorrecto» y daremos una nueva oportunidad para introducir la clave correcta. Además incluiremos una tecla para borrar lo que haya escrito, por si nos equivocamos.
Si habéis seguido las sesiones anteriores, ya os habréis dado cuenta de que uno de los ejemplos que viene con la librería, y que ya hemos probado, puede servirnos como base. Pero de todas formas vamos a cambiarlo para adaptarlo al tamaño de nuestra pantalla y para que incluya las nuevas funcionalidades que queremos.
La manera de inicializar y hacer funcionar correctamente el display ya lo hemos visto varias veces,así que no haremos hincapié en ello, pero siempre podéis echar un ojo a las anteriores sesiones
DIBUJAR LOS BOTONES
La primera función con la que vamos a trabajar será la que dibuje el interfaz principal con los botones para introducir la clave, para lo que reciclaremos la función drawButtons() del ejemplo del que hablábamos.
Como queremos adaptarla al tamaño de nuestra pantalla, vamos a calcular, un poco más o menos, el tamaño de los botones. Como la pantalla mide 420 pixeles de ancho y queremos que las líneas que muestran los números muestren 5 cada uno, nos sale que, con una separación entre botones de 15 píxeles, cada botón debería medir 78 píxeles de ancho. Y como queremos que sean cuadrados, lo mismo de ancho.
Teniendo eso en cuenta, la primera parte de la función quedaría así:
void drawButtons() { myGLCD.clrScr(); // Draw the upper row of buttons for (x = 0; x < 5; x++) { myGLCD.setColor(0, 0, 255); myGLCD.fillRoundRect (15 + (x * 93), 15, 93 + (x * 93), 93); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (15 + (x * 93), 15, 93 + (x * 93), 93); myGLCD.printNumI(x + 1, 47 + (x * 93), 47); } // Draw the center row of buttons for (x = 0; x < 5; x++) { myGLCD.setColor(0, 0, 255); myGLCD.fillRoundRect (15 + (x * 93), 108, 93 + (x * 93), 186); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (15 + (x * 93), 108, 93 + (x * 93), 186); if (x < 4) myGLCD.printNumI(x + 6, 47 + (x * 93), 142); } myGLCD.print("0", 419, 142); // Draw the lower row of buttons myGLCD.setColor(0, 0, 255); myGLCD.fillRoundRect (15, 201, 155, 260); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (15, 201, 155, 260); myGLCD.print("Clear", 45, 222); myGLCD.setColor(0, 0, 255); myGLCD.fillRoundRect (325, 201, 465, 260); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (325, 201, 465, 260); myGLCD.print("Enter", 355, 222); myGLCD.setBackColor (0, 0, 0); }
Ahora mismo deberíamos tener un interfaz como este:
DETECTAR Y TRATAR LAS PULSACIONES
Ya hemos visto como podemos detectar las pulsaciones y saber en que área de la pantalla se han producido, pero en esta ocasión además de eso tenemos que guardar los valores de las teclas que mostramos en una cadena que luego compararemos con la contraseña que hayamos elegido.
Y como además querremos mostrar un ‘*’ cada vez que se puse una tecla, tendremos que jugar con otra cadena auxiliar que trataremos de forma paralela. Así que crearemos las variables necesarias y una función en la que las iremos actualizando y mostrando un ‘*’ por cada tecla pulsada:
int x, y; char stCurrent[10] = ""; int stCurrentLen = 0; char staux[10] = ""; int stauxLen = 0; char password[10] = "1234"; void updateStr(int val) { if (stCurrentLen < 10) { stCurrent[stCurrentLen] = val; stCurrent[stCurrentLen + 1] = '\0'; stCurrentLen++; staux[stauxLen] = '*'; staux[stauxLen + 1] = '\0'; stauxLen++; myGLCD.setColor(0, 255, 0); myGLCD.print(staux, CENTER, 275); } }
La última función que usaremos para estos propósitos servirá para recuadrar en rojo la tecla que se haya pulsado, de forma que nos aseguremos visualmente de la tecla que se haya pulsado:
// Draw a red frame while a button is touched void waitForIt(int x1, int y1, int x2, int y2) { myGLCD.setColor(255, 0, 0); myGLCD.drawRoundRect (x1, y1, x2, y2); while (myTouch.dataAvailable()) myTouch.read(); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (x1, y1, x2, y2); }
En el loop será donde detectemos las pulsaciones y usemos las funciones que hemos creado para manejar las cadenas. Vamos a dejar fuera de momento las teclas para borrar y confirmar la introducción de la contraseña, que funcionarán un poco diferentes a las demás. por lo demás, las de los números funcionarán todas iguales:
if (myTouch.dataAvailable()) { myTouch.read(); x = myTouch.getX(); y = myTouch.getY(); if ((y >= 15) && (y <= 93)) // Upper row { if ((x >= 15) && (x <= 93)) // Button: 1 { waitForIt(15, 15, 93, 93); updateStr('1'); } if ((x >= 108) && (x <= 186)) // Button: 2 { waitForIt(108, 15, 186, 93); updateStr('2'); } if ((x >= 201) && (x <= 279)) // Button: 3 { waitForIt(201, 15, 279, 93); updateStr('3'); } if ((x >= 294) && (x <= 372)) // Button: 4 { waitForIt(294, 15, 372, 93); updateStr('4'); } if ((x >= 387) && (x <= 465)) // Button: 5 { waitForIt(387, 15, 465, 93); updateStr('5'); } } if ((y >= 108) && (y <= 186)) // Center row { if ((x >= 15) && (x <= 93)) // Button: 6 { waitForIt(15, 108, 93, 186); updateStr('6'); } if ((x >= 108) && (x <= 186)) // Button: 7 { waitForIt(108, 108, 186, 186); updateStr('7'); } if ((x >= 201) && (x <= 279)) // Button: 8 { waitForIt(201, 108, 279, 186); updateStr('8'); } if ((x >= 294) && (x <= 372)) // Button: 9 { waitForIt(294, 108, 372, 186); updateStr('9'); } if ((x >= 387) && (x <= 465)) // Button: 0 { waitForIt(387, 108, 465, 186); updateStr('0'); } }
BORRAR Y CONFIRMAR LA CONTRASEÑA
Ahora vamos con las dos teclas que hemos dejado fuera antes. Primero la tecla «Clear» que nos servirá para borrar lo que hayamos introducido hasta el momento. A parte de borrar el contenido de las dos cadenas con las que estamos trabajando, vamos a utilizar un pequeño truco para borrar los ‘*’, que haya en la pantalla. Simplemente haremos que pinte los mismos ‘*’ pero de color negro y sobre fondo negro, así será como si borrásemos los que estaban.
En cuanto a la tecla «Enter» con la que confirmamos la entrada de la contraseña, compararemos el contenido de la cadena de números que hayamos introducido con la que hemos configurado como password. Además mostraremos «Incorrecto» y borraremos todo si está equivocada.
Por el contrario, si es correcta, mostraremos «Correcto» y llamaremos a la función abierto() de la que hablaremos más adelante.
if ((y >= 201) && (y <= 260)) // Last row { if ((x >= 15) && (x <= 155)) // Button: Clear { waitForIt(15, 201, 155, 260); myGLCD.setBackColor(0, 0, 0); myGLCD.setColor(0, 0, 0); myGLCD.print(staux, CENTER, 275); stCurrent[0] = '\0'; stCurrentLen = 0; staux[0] = '\0'; stauxLen = 0; } if ((x >= 325) && (x <= 465)) // Button: Enter { waitForIt(325, 201, 465, 260); if (strcmp(stCurrent, password) == 0) { myGLCD.setColor(0, 0, 255); myGLCD.print("Correcto", CENTER, 300); stCurrent[0] = '\0'; stCurrentLen = 0; staux[0] = '\0'; stauxLen = 0; abierto(); myGLCD.setBackColor(0, 0, 255); myGLCD.setColor(255, 255, 255); drawButtons(); } else { myGLCD.setColor(255, 0 , 0); myGLCD.print("Incorrecto", CENTER, 300); delay (1000); myGLCD.setBackColor(0, 0, 0); myGLCD.setColor(0, 0, 0); myGLCD.print(stCurrent, CENTER, 275); myGLCD.print("Incorrecto", CENTER, 300); stCurrent[0] = '\0'; stCurrentLen = 0; staux[0] = '\0'; stauxLen = 0; } } }
En la función abierto(), borraremos la pantalla actual y mostraremos una en la que diga «PUERTA ABIERTA», para después volver al inicio:
void abierto() { myGLCD.clrScr(); myGLCD.fillScr(VGA_WHITE); myGLCD.setBackColor(VGA_WHITE); myGLCD.setColor(VGA_GREEN); myGLCD.print("PUERTA ABIERTA", CENTER, 160); delay (5000); }
Os recomendamos descargar el programa completo Control_acceso para trabajar con él, porque andar copiando y pegando puede ser un poco difícil en este caso; y os dejamos un vídeo con el resultado.
Resumen de la sesión
En esta sesión hemos aprendido varias cosas importantes: