He estado mejorando la shield del teclado para el Arduino, añadiendo un condensador de 100nF para mejorar las lecturas del pin de salida que va conectado al pin A0. Os pongo unas imagenes realizadas con el Eagle3D y un ejemplo de código para que veais como funciona, además os subo el esquemático, la pcb y el fotolito.
Esquemático de la Teclado Shield v1.1:
La imagen 3D realizada con Eagle3D:
Un ejemplo para utilizar el teclado con la placa Arduino:
/*Programa realizado para tallerarduino.wordpress.com por Javier Couto Rego (Regata) para apertura de puerta mediante password de 4 digitos*/ /* El circuito: * LCD RS pin a pin digital 12 * LCD Enable pin a pin digital 11 * LCD D4 pin a pin digital 5 * LCD D5 pin a pin digital 4 * LCD D6 pin a pin digital 3 * LCD D7 pin a pin digital 2 * LCD R/W pin a masa * Potenciometro de 10K: * patilla a +5V y la otra a masa * Patilla central al pin LCD VO (pin 3 del LCD) */ // #include <LiquidCrystal.h> // Indicamos los pines a los que tenemos conectado el lcd LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Indicamos los pines donde tenemos conectados los actuadores int buzzer = 6; //En el pin 6 tenemos un buzzer int puerta = 1; //En el pin 1 conectamos la salida para un relé int errores=0; //Variables para comprobar si hay errores int error=0; int i; //Arrays donde guardamos el pass y un pass por si bloqueamos el //circuito por pasarnos de intentos int pass[4] = {1,2,3,4}; int desbloqueo[4] = {4,3,2,1}; int password[4]; //Variable donde guardaremos el valor que nos devuelva la función de lectura de tecla int tecla=0; void setup() { // Indicamos numero de columnas y filas del LCD e iniciamos lcd.begin(20, 4); lcd.setCursor(0,0); //Mostramos en pantalla el mensaje Password: lcd.print("Password:"); //Indicamos como salidas el relé y el buzzer (pines 1 y 6) pinMode(1,OUTPUT); pinMode(6,OUTPUT); } void loop() { //Comprobamos si se han producir 3 intentos errores de introduccion de pass if (errores<3) { //Posicionamos el cursor en el LCD lcd.setCursor(8,1); for(i=0;i<4;i++) //Pass para cuatro caracteres { tecla=teclado(); //asiganmos a tecla el valor que nos devuelve la función teclado() if (tecla>=0 && tecla<=9) //Comprobamos que el valor de las teclas esten comprendidas entre 1 y 9 //para evitar introducir letras { password[i] = tecla; //En la posición correspondiente del array guardamos el valor introducido lcd.print("*"); //En pantalla mostramos un * para evitar que vean el código delay(20); //retardo de 20mseg } else //Si introducimos un valor que no este entre 1 y 9 restamos 1 a i, esto es para volver a //introducir el caracter en esa posicion otra vez { i=i-1; } } //En este bucle comprobamos que la contraseña que hemos introducido coincida con la que teniamos configurada for(i=0;i<4;i++) { if (pass[i]!=password[i]) //Se comprueba caracter a caracter y si no coinciden { i = 4; //Asignamos a i 4 para salir del bucle for error = 1; //Indicamos que hay error errores = errores + 1; //Sumamos 1 intento a errores } } if (error==0) //Si no hubiera error { //Mostrariamos en pantalla Pantalla Password: Done lcd.clear(); lcd.setCursor(0,0); lcd.print("Password:"); lcd.setCursor(8,1); lcd.print("Done"); //Activamos las salidas de buzzer y rele durante 500 mseg digitalWrite(buzzer,HIGH); digitalWrite(puerta,HIGH); delay(500); //Desactivamos las salidas de buzzer y rele digitalWrite(buzzer,LOW); digitalWrite(puerta,LOW); //Limpiamos el LCD y mostramos Password: lcd.clear(); lcd.setCursor(0,0); lcd.print("Password:"); lcd.setCursor(8,1); } else //Si hay error { //Mostramos ERROR en pantalla durante 50 mseg lcd.setCursor(8,1); lcd.print("ERROR"); delay(50); //Borramos pantalla y mostramos Password: lcd.clear(); lcd.setCursor(0,0); lcd.print("Password:"); lcd.setCursor(8,1); } } //Si se producen 3 intentos erroneos de introducir clave else { //Mostramos en pantalla BLOQUEADO lcd.setCursor(6,1); lcd.print("BLOQUEADO"); lcd.setCursor(8,2); //Bucle donde introducimos el pass para DESBLOQUEAR el sistema for(i=0;i<4;i++) { tecla=teclado(); //asiganmos a tecla el valor que nos devuelve la función teclado() if (tecla>=0 && tecla<=9) //Comprobamos que el valor de las teclas esten comprendidas entre 1 y 9 //para evitar introducir letras { password[i] = tecla; //En la posición correspondiente del array guardamos el valor introducido lcd.print("*"); //En pantalla mostramos un * para evitar que vean el código delay(20); //retardo de 20mseg } else //Si introducimos un valor que no este entre 1 y 9 restamos 1 a i, esto es para volver a //introducir el caracter en esa posicion otra vez { i=i-1; } } //En este bucle comprobamos que la contraseña que hemos introducido coincida con la que teniamos configurada for(i=0;i<4;i++) { if (desbloqueo[i]!=password[i]) //Se comprueba caracter a caracter y si no coinciden { i = 4; //Asignamos a i 4 para salir del bucle for error=1; //Indicamos que hay error } else { error=0; //Indicamos que no hay error en ese caracter } } //Si no hubiera error if (error==0) { //Reiniciamos el contador de intentos errores=0; //Mostramos por pantalla DESBLOQUEADO durante 50mseg lcd.clear(); lcd.setCursor(4,1); lcd.print("Desbloqueado"); delay(50); //Limpiamos el LCD y mostramos por pantalla Password: lcd.clear(); lcd.setCursor(0,0); lcd.print("Password:"); lcd.setCursor(8,1); } //Si hay error else { //Mostramos en pantalla Password: para seguir introduciendo pass de desbloqueo lcd.clear(); lcd.setCursor(0,0); lcd.print("Password:"); lcd.setCursor(8,2); } } } //Funcion que devuelve la tecla pulsada int teclado() { int tecla; int valoradc=analogRead(5); //Leemos el pin analogico 5 del arduino //donde tenemos conectado el teclado de 1 pin switch (valoradc) //Según el valor que nos da la lectura asignamos una tecla { case 865: return 7; //Devuelve tecla 7 break; case 650: return 8; //Devuelve tecla 8 break; case 508: return 9; //Devuelve tecla 9 break; case 339: return 10; //Devuelve tecla 10 break; case 803: return 4; //Devuelve tecla 4 break; case 614: return 5; //Devuelve tecla 5 break; case 486: return 6; //Devuelve tecla 6 break; case 329: return 11; //Devuelve tecla 11 break; case 735: return 1; //Devuelve tecla 1 break; case 574: return 2; //Devuelve tecla 2 break; case 460: return 3; //Devuelve tecla 3 break; case 317: return 12; //Devuelve tecla 12 break; case 698: return 14; //Devuelve tecla 14 break; case 551: return 0; //Devuelve tecla 0 break; case 445: return 15; //Devuelve tecla 15 break; case 310: return 13; //Devuelve tecla 13 break; default: return 16; //Devuelve tecla 16 } }
Y aquí os dejo los archivos de la Teclado Shield v1.1: http://www.mediafire.com/?xk8ake4e1x5gbd4
Espero que os sirva esta Shield.
Si te ha servido de ayuda esta entrada, puedes realizar un donativo para agradecer el tiempo que dedico al blog y ayudar a hacer más entradas.
Podrías explicar un tanto el código por favor..
Fabián código actualizado, si no entiendes algo no dudes en preguntar!
No comprendo bien la forma en que la programación recibe la tensión análoga que se produce al precionar una tecla
Hola Fabián, en esta shield lo importante es ahorrar pines, y para ello se han empleado simples divisores de tensión para determinar que tecla se ha pulsado, como tenemos en el Arduino un conversor analógico digital(CAD) de 10 bits de resolución, y la shield va alimenteda a 5V, vamos a tener un rango de tensiones para determinar dicha tecla entre 0 y 5V. Por tanto tendremos para cada bit del conversor un valor de 5V/1024 = 4,8828mV. Como podrás observar en la tabla que aparece en la entrada antigua del teclado, vienen tanto los valores de tensión como los valores correspondientes del conversor analógico digital de nuestro arduino para cada tecla pulsada. Por ejemplo la tecla correspondiente a la primera fila y a la primera columna tiene una tensión debido al divisor de tensión de 4,225V, y para obtener el valor del CAD tenemos que dividir dicha tensión entre los 4,8828mV y obtendremos un valor de 865, que será el valor que nos aparezca al leer dicha entrada analógica en nuestro arduino.
Esto lo explica muy bien David en el siguiente videotutorial de este blog, así como en el documento adjunto, correspondiente al capítulo 2 de la serie arduino tutorials: https://tallerarduino.wordpress.com/2011/12/14/cap-2-pins-analogicos/
Espero que así lo entiendas, si sigues sin entender ya sabes, aquí estamos.
Gracias por tu rápida respuesta. En verdad comprendía lo que me acababas de explicar, ahora bien cuando construí mi shield lamentablemente al presionar los pulsadores en ocaciones me reconoce la tecla pulsada y me aparece un * en el LCD (el mío es de 16×2 por lo cual modifiqué su tamaño en la programación) y en otras no.
Supuse que quizás las tensiones que me entrada la salida de mi teclado variaban en algunos milivolts haciendo que quizás mi arduino no reconociera el paso adecuando al hacer la conversión A/D. He probado asignando varios valores a una misma tecla (Ej: para el valor 4,225 puse valor 864, 865 y 866 en la programación mediante la función switch.. case) y aún así no me funciona. ¿Qué otro error podré tener?
Has puesto el condensador que aparece en este post? También puede ser debido a que las resistencias comerciales (no sé cuales usas) tienen una tolerancia de entre 1%-5% normalmente, por lo tanto se varia el valor que presentan como resistencia afectando a los cálculos teóricos que aparecen en la tabla de valores que aparece arriba. A mí tampoco me han valido exactamente esos valores, lo que hice ha sido que al poner la shield del teclado con el arduino hice un código básico para mostrar por el terminal serie de arduino el valor de lectura del pin analógico conectado al teclado y así ir guardando los valores de tecla exactos para ese teclado en concreto. Prueba con eso y mira a ver si te coinciden los valores.
Entiendo, probaré con ese método y te mantendré informador.. gracias =)
Al fin funcionó, me percaté de que arduino me preguntaba muy rápido si es que había presionado o no la tecla, lo hace a razón de 20 milisegundos según la programación que tienes disponible en esta web. Modificándola a medio segundo (500 ms) me funcionó a la maravilla.
Gracias por la oportuna reatroalimentación.
¿Hasta que distancia funciona? ¿Servirá para una alarma?
Hola, no probé la distancia a la cual los valores del adc no varian mucho. Es una cosa que tengo pendiente, además de cambiar las resistencias por unas que tengan menos tolerancia.
Yo el teclado lo he probado en un diseño de una incubadora, y con el teclado manejaba un menú, así como la introducción de tiempos de temperatura, de volteo de huevos, hora de encendido de luces, etc. También diseñe una cerradura electrónica de apertura con relé y el teclado funcionaba perfectamente para introducir clave de apertura y clave de desbloqueo.
Creo que si que valdrá para una alarma, si pruebo distancia te comento. Un saludo
¿y que LCD podria usar con esta programacion? ¿Alguna de facil comercializacion que vendan en Steren xfavor? y podrias pegar el programa para poder visualizar el valor de cada tecla? de antemano muchisimas gracias (:
Hola Char’s A.A!! Pues en principio cualquier LCD, los más usado con arduino son los que llevan el controlador HD44780 y que puedes encontrar a un precio muy económico en cualquier parte. He estado mirando en la página que comentas, pero no he encontrado ninguna pantalla LCD a la venta, si encuentras alguna puedes poner el link y te comento si te vale o no.
Para poder comprobar los valores de cada tecla, puedes hacerlo mediante el monitor serie del IDE de Arduino y con el siguiente código:
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(100); // delay in between reads for stability
}
Un saludo!!