SHIELD TECLADO V1.1 PARA ARDUINO CON 1 PIN


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.

donativo_paypal

12 comentarios en “SHIELD TECLADO V1.1 PARA ARDUINO CON 1 PIN”

  1. 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.

  2. 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?

  3. 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.

  4. 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.

  5. 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

  6. ¿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 (:

  7. 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!!

Deja un comentario