bclose

LCD Keypad Shield

Usando un Shield que nos ahorrará muchos dolores de cabeza

Objetivos

 

 

    • Conocer los Shields con LCD y botones.
    • Presentar un ejemplo sencillo de uso..

 
 

  

Material requerido.

 

 

  Tienda España Tienda Mexico
Imagen de Arduino UNO Arduino UNO o equivalente. Arduino UNO o equivalente.
Shield con LCD 16x2 y varias teclas Un LCD Keypad Shield Un LCD Keypad Shield

 

Los Keypads con Display LCD

 

Con mucha frecuencia, cuando estas montando algún circuito de prueba, necesitas un display para ver cómo van las cosas y en muchas ocasiones la consola de Arduino es una opción incomoda o simplemente no está disponible.

Necesitamos un display local y para ello ya vimos en las pasadas sesiones que basta con conectar un display del tipo que sea. Lo más fácil suele ser un LCD de 16×2 del tipo I2C, por aquello de no tener que conectar muchos pines, que además tienen la mala costumbre de soltarse en el peor momento.

Pero incluso en estas ocasiones los varios hilos del I2C son poco robustos y no es raro que se suelten, lo que suele provocar una de esas típicas imprecaciones por las que a electrónicos y técnicos en general se nos acusa de mal carácter (y hasta de hablar solos).

Por eso, hace tiempo que uso un pequeño Shield que ha mejorado mucho mis relaciones con los que me rodean, y que si no tienes problemas de pines, permite montar con seguridad un pequeño display con botones, ideal para muchas pruebas de campo e incluso como dispositivo final en cualquiera de esos perdidosa rincones de la casa por la que andas colocando Arduinos.

Por poco más de lo que vale un display LCD de 16×2, este pequeño Shield nos viene con un LCD más 5 botones, que podemos usar para nuestros proyectos. A cambio se queda bastante pines del Arduino UNO para sí mismo y la gestión del LCD, pero nos sigue dejando libres los pines digitales del 0 al 7, y las puertas analógicas del A1 al A5, más el ICSP.

La ventaja del LCD keypad Shield, es que se coloca rápidamente en su sitio y queda con una sujeción robusta a prueba de cables de protoboard bailando, lo que garantiza la estabilidad del asunto.

Vista frontal

El LCD está conectado de esta forma:

Detalle de conexiones

Para no tener que usar 5 pines digitales para reconocer los 5 botones, están conectados en serie con resistencias a un único puerto analógico de modo que reconocemos el botón pulsado mediante el valor de tensión que lee A0.

 
  • Aunque esto tiene el inconveniente que, si no podremos discriminar si se pulsan dos botones simultáneamente.
 

El programa de control

 

Como ya vimos en toras sesiones el manejo de los LCD de 16×2, no entraremos en el detalle de su gestión, y remitimos a los que sean nuevos con esta pequeña joyita de hardware al tutorial correspondiente: Displays LCD

 
  • También conviene recordar de que para que podamos ver correctamente el display LCD, dispone de un potenciómetro en la esquina superior derecha que nos ayudará a ajustar el contraste.
 

Dado que los pines están fijados por Hardware en el Shield, podemos presentar un programa tipo para manejarlo.  Como el LCD va directamente te conectado a los pines digitales de nuestro Arduino vamos a empezar incluyendo la librería LCD y definiendo las conexiones de los pines.

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

Algunas definiciones por comodidad

int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

int read_LCD_buttons()  // para leer los botones

Para leer los botones, vamos a definer una pequeña function:

int read_LCD_buttons()  
  { adc_key_in = analogRead(0);      // Leemos A0
    // Mis botones dan:  0, 145, 329,507,743
    // Y ahora los comparamos con un margen comodo
    if (adc_key_in > 900) return btnNONE;     // Ningun boton pulsado 
    if (adc_key_in < 50)   return btnRIGHT; 
    if (adc_key_in < 250)  return btnUP;
    if (adc_key_in < 450)  return btnDOWN;
    if (adc_key_in < 650)  return btnLEFT;
    if (adc_key_in < 850)  return btnSELECT; 

    return btnNONE;  // Por si todo falla
  }

Simplemente lee el valor de tensión en A0 y con esto reconocemos el botón pulsado. El Shield está diseñado para que cada botón provoque una lectura distinta de tensión en el convertidor A0. En cuanto un valor concuerda salimos de la función con el valor dado.

Tienes que comprobar que para el Shield del que dispones los valores son aproximadamente los mismos, pero no te confíes y compruébalo.

 
  • Cada botón está previsto sobre una serie de 0, 175, 350, 525, 700 ; Pero la fabricación de los componentes electrónicos tiene una dispersión amplia para esta calidad, por lo que podrían haber diferencias.
 

En cuanto al Setup, simplemente sacamos un mensaje en pantalla:

void setup()
   {  lcd.begin(16, 2);              // Inicializar el LCD
      lcd.setCursor(0,0);
      lcd.print("Prometec.net");     // print a simple message
   }

Y por último en el loop, gestionamos los valores en pantalla:

Contenido solo disponible para suscriptores. ¡Accede al contenido!

El programa es muy sencillo y muy fácil de adaptar a tus propios proyectos, lo que hace que estas placas sean muy prácticas cuando quieres lanzar un prototipo y no quieres liarte con los botones y displays.

El único inconveniente que tienen es que para engancharlo sensores externos tienes que soldarlos a la placa o al menos soldar conectores hembras como los que trae Arduino para sus pines, ya que estos Shields nunca los pasan, o al menos yo no he visto ninguno que lo haga.

Aquí os dejo un pequeño video para mostraros el Shield.

 

 

Resumen de la sesión

 

 
    • Hemos visto como estos Shields son muy sencillos de usar.
    • Encajan como cualquier otro Shield con firmeza, lo que nos haya a mejorar la robustez de los prototipos.
    • Son muy prácticos y nos permiten poner en marcha prototipos rápidamente sin preocuparnos por pelear con las pantallas y o botones de entrada

 
 
 

 

 

 

 

 

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login

(48) Comments

  • Avatar for Charly

    Para los botones Comparé con los siguientes parámetros:

    // Y ahora los comparamos con un margen comodo
    if (adc_key_in > 1023) return btnNONE; // Ningun boton pulsado
    if (adc_key_in < 50) return btnRIGHT;
    if (adc_key_in < 250) return btnUP;
    if (adc_key_in < 300) return btnDOWN;
    if (adc_key_in < 450) return btnLEFT;
    if (adc_key_in < 650) return btnSELECT;

  • Avatar for Charly
    • Ivan

    De todas formas si encuentro alguna forma de solucionarlo te aviso. UN saludo.

  • Avatar for Charly

    Gracias por la respuesta Ivan, lamentablemente lo he intentado pero nada. La única manera que pueda cargar nuevamente es sacando el lcd.

  • Avatar for Charly
    • Ivan

    Hola Esteban, por alguna razón yo uso un shield LCD que con el Arduino MEGA también me hace eso de vez en cuando. Lo que hago yo es soltar el cable USB del PC y volverlo a conectar, que es más sencillo que soltar y opner el shield. Un saludo.

  • Avatar for Charly
    • Esteban

    Hola, tengo este mismo lcd pero me da un error bastante extraño.
    Cuando cargo por primera vez el código no tengo ningún problema, pero una vez que intento cargar nuevamente el código con algún cambio o incluso cargar el mismo código me da el siguiente error:

    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_getsync(): timeout communicating with programmer
    An error occurred while uploading the sketch

    He intentado cambiando de puerto COM, cambiar de USB y nada, la única solucion para volver a cargar un código es desmontar el LCD keypad shield del arduino, cargar código y volver a montar. Alguna idea?

    Esta montado sobre un arduino 2560
    Gracias

  • Avatar for Charly
    • Ivan

    Hola Luis, puedes utilizar el protocolo i2c mientras utilizas también el shield, ya que te deja los pines SCL y SDA libres. Y también puedes seguir utilizando el puerto serie. Un saludo.

  • Avatar for Charly

    Hola muchas gracias por tu trabajo, no soy un experto en electrónica y quisiera saber si ¿pierdo la comunicación i2c usando la shield lcd-keypad para transmitir datos a otros dispositivos?, y si es así ¿puedo utilizar la comunicación serial a través de los pines 1 (TX) y 0 (RX)?, de nuevo muchas gracias.

  • Avatar for Charly
    • Admin

    Hay veces que algunos shield son incompatibles. Pero si el problema solo es el contraste, podrias doblar el pin 10 (Sacandolo del encaje del shield por fuera)del LCD y conectarlo manualmente a otro pin

  • Avatar for Charly
    • Diego

    Hola,

    Alguien uso este lcd kypad con un shield ethernet?

    El shield ethernet tiene reservado los pines 10 y 13, con lo cual, el pin 10 para el control del contraste no puede ser utilizado.
    hasta que no tendriamos problemas, se deja constante el contraste y listo.

    El problema que tengo es que al utilizar el shield ethernet solo funciona, el lcd keypad solo, funciona, pero si pongo las 2 placas juntas no.

    El monitor serial de arduino deja de funcionar, los botones del lcdkey pad tambien, alguna idea ?

    gracias

  • Avatar for Charly
    • Ivan

    Hola David, el problema es que declaras la variable int adc_key_in = 0; y luego usas la variable key que no has declarado. Simplemente sustituye lcd.print(key); por lcd.print(adc_key_in);

    Un saludo.

  • Avatar for Charly

    hola. me da error, no me entero de la pelicula!

    esto tengo:

    #include //importando biblioteca de LiquidCrustal
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //pines en los que se conecta
    int lcd_key = 0;
    int adc_key_in = 0;
    #define btnRIGHT 0
    #define btnUP 1
    #define btnDOWN 2
    #define btnLEFT 3
    #define btnSELECT 4
    #define btnNONE 5
    int read_LCD_buttons()
    {
    adc_key_in = analogRead(0); // Leemos A0
    // Mis botones dan: 0, 145, 329,507,743
    // Y ahora los comparamos con un margen comodo
    if (adc_key_in > 900) return btnNONE; // Ningun boton pulsado
    if (adc_key_in < 50) return btnRIGHT;
    if (adc_key_in < 250) return btnUP;
    if (adc_key_in < 450) return btnDOWN;
    if (adc_key_in < 650) return btnLEFT;
    if (adc_key_in < 850) return btnSELECT;

    return btnNONE; // Por si todo falla
    }
    void setup(){
    lcd.begin(16, 2);
    lcd.setCursor(0,0);
    lcd.print("HOLA,!");
    }

    void loop(){
    lcd.setCursor(9,1); // Cursor a linea 2, posicion 9
    lcd.print(millis()/1000); // Imprime segundos
    lcd.setCursor(13, 0); // Cursor a linea 1, posicion 13
    lcd.print(key);
    lcd.setCursor(0,1); // Cursor a linea 2, posicion 1
    lcd_key = read_LCD_buttons();
    if( lcd_key == btnRIGHT)
    lcd.print("RIGHT ");
    else if ( lcd_key == btnLEFT )
    lcd.print("LEFT ");
    else if ( lcd_key == btnUP)
    lcd.print("UP ");
    else if ( lcd_key == btnDOWN)
    lcd.print("DOWN ");
    else if ( lcd_key == btnSELECT)
    lcd.print("SELECT");
    else if ( lcd_key == btnNONE)
    lcd.print("NONE ");

    }

    y este el error:

    Arduino:1.8.0 (Windows 10), Tarjeta:"Arduino/Genuino Uno"

    CONDICIONALES_Y_BOTONES:34: error: 'key' was not declared in this scope

    lcd.print(key);

    ^

    Se encontraron múltiples librerías para "LiquidCrystal.h"
    Usado: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal
    No usado: C:\Users\david\Documents\Arduino\libraries\LiquidCrystal_I2C
    Usando librería LiquidCrystal con versión 1.0.5 en la carpeta: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal
    exit status 1
    'key' was not declared in this scope

  • Avatar for Charly
    • Admin

    Hola Esteve, deberian serlo sin problemas. Ten en cuenta que este display conecta en serie los botones con resistencias intermedias y usa un unico pin analogico para leerlos y saber que boton se ha pulsado. No recuerdo de memoria la caida de tension por cada boton pero aunque las tensiones estan proximas, tu arduino, UNO o Mega debe tener capacidad de sobra para reconocer correctamente el boton pulsado

  • Avatar for Charly
    • Esteve

    Buenas tardes, ¿las lcd keypad que vendéis son compatibles con clones arduino mega 2560? En UNO funciona correcta pero en Mega el analogRead devuelve valores muy parecidos y en algunas teclas iguales.
    Gracias de antemano

  • Avatar for Charly
    • Admin

    Hola Nevin, parece un pequeño problema de tu programa. Puedes revisarlo y cambiar lo que consideres

  • Avatar for Charly
    • Ivan

    Prueba a intercambiar en las definiciones el select y el left. Un saludo.

  • Avatar for Charly

    buenas tardes hice el proceso como tal, pero cuando presiono SELEC da LEFT y cuando presiono LEFT da DOWN.
    alguna sugerencia solo soy un curioso mas.

  • Avatar for Charly

    Sesion_84 funciona a la perfección, gracias por el aporte.

  • Avatar for Charly
    • Jose martin saavedra crisanto

    estoy aprendiendo de ustedes gracias, hice algunas correcciones y todo resulto ,gracias ingmartinsaavedra2016@gmail.com desde piura,peru

  • Avatar for Charly
    • Rafa

    Muchas gracias por el tutorial, me ha venido de maravilla para probar el lcd.
    un par de cosas,
    Los pines digitales disponibles, los de la parte de arriba, al menos en mi placa son
    d13, d12, d11, d3, d2, d1, 0a
    y por abajo estan los mismos pines de alimentacion del arduino
    rst, 3v3, 5v, gnd, gnd, vin
    Es que para mi es imprescindible usar esos pines para entradas y salidas, y en la placa no estan marcados.

  • Avatar for Charly
    • Gustavo

    hola. utlizo el mismo shield que estas probando vos. el error que encuentro en mi codigo es que al presionar (ejemplo) tecla para arriba, tambien se ejecuta tecla abajo, como que los valores de voltajes estan muy juntos. te paso mi codigo.
    int TLcdKey::keyPressed() {

    int nMeasuredVoltage = analogRead(PIN_READ_LCD);

    if (nMeasuredVoltage == 0) return KEY_RIGHT;
    if (nMeasuredVoltage <= 100) return KEY_UP;
    if (nMeasuredVoltage <= 300) return KEY_DOWN;
    if (nMeasuredVoltage <= 450) return KEY_LEFT;
    if (nMeasuredVoltage = 1023) return KEY_NONE;
    }

    esos valores los saque ponindo un Serial.println(nMeasuredVoltage, DEC); y «mas o menos» fui acomodando los valores.

    luego los utilice de esta forma:

    do{
    bKey = keyPressed();
    switch (bKey) {
    case 1:
    bSalir = false;
    Serial.println(«Arriba»);
    break;
    case 2:
    bSalir = false;
    Serial.println(«Abajo»);
    break;
    case 3:
    bSalir = false;
    Serial.println(«Izquierda»);
    break;
    case 4:
    nMenu++;
    Serial.println(nMenu, DEC);
    Serial.println(«derecha»);
    bSalir = false;
    break;
    case 5:
    Serial.println(«select»);
    bSalir = true;
    break;
    case 6:
    bSalir = false;
    break;
    }
    } while (!bSalir);

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login