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.

Imagen de Arduino UNOArduino UNO o equivalente.
Shield con LCD 16x2 y varias teclasUn 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: Sesion_84

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);                  // Imprime el valor leido en la puerta A0
      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  ");
   }

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

El único inconveniente que tienen es que para engancharle 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

 
 
 

 

 

 

 

 

(27) Comments

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

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

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

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

    • Jose martin saavedra crisanto

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

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

    • 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);

    • Gustavo

    Hola
    Estoy probando sobre mi Shield pero los valores son totalmente diferentes, quiero ver cuales son los valores y pongo asi:
    Serial.println(adc_key_in, “DEC”);
    pero no me quiere compilar. dice: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]

    y no se porque…
    podrias ayudarme? gracias.

    • Gustavo, no se que shiled usas ni que programa y asi poco te puedo decir

    • Miguel Angel

    Buenos días.

    En primer lugar decir que soy nulo en programación y estoy intentando montar un arduino que me controle el acuario.
    Mi arduino es el mega 2560 y con ayuda de un amigo he conseguido medir las temperaturas del deposito, acuario y cajon de las luces pero ahora me llega el problema de que quiero montar la pantalla que es como esta y no se como hacerlo.

    • Hola Miguel Ángel, con como esta te refieres a que es exactamente esta u otro modelo. Si es esta misma este mismo tutorial te tendría que servir, y sino aquí tienes un tutorial con un display LCD sin el shield http://www.prometec.net/displays-lcd/ Un saludote.

    • Se bienvenido a nuestra pequeña aficion Miguel Angel. No se que problema tienes pero veras que es de lo mas sencillo de montar si sigues el tuto. Quizas si me especificas un poco mas el problema….

  • Perdona pero ahora tengo otro problema que no soy capaz de solucionar, pretendo controlar dos variables de enteros para incrementar o decrementar mediante los botones der-izq y up-down. Y bueno mi pregunta es como haríais para concatenar variables y que se muestren por el LCD y que el mensaje se mantenga pues usando el tipo CONST, no me deja concatenar estas variables. Adjunto el codigo:

    char * text=”dif”;

    int D=1;//dificultad
    int NR=1;//numero rondas

    char * D_C=( char *)D;
    char * NR_C=( char *)NR;

    …//variables glob.
    …//setup
    …//loop
    case btnRIGHT:{
    if(D=1){
    D++;
    D_C=(char *)D;
    sprintf(text, “%s%s”,D_C , NR_C); //STRCAT????
    lcd.print(text);//funciona no es correcto?? no se mantiene el texto
    delay(1000);
    }else if(D>=2){
    sprintf(text, “%s%s”,D_C , NR_C);
    lcd.print(text);
    delay(1000);
    }

    break;
    }

    la función sprinf ni siquiera me muestra nada y no soy capaz de ver porque.
    Gracias.

    • Jaime Corchado

    Ok!! todo bien, ya funciona muchísimas gracias.
    Gran web!!

    • Jaime Corchado

    Hola buenas estoy intentando usar el lcd 16×2, en un arduino atmega, y no consigo averiguar que pines tengo que pasarle a la inicialización
    LiquidCrystal lcd(??¿?¿¿);???
    Alguien lo ha probado cuales son los correctos, llevo ya unos dias probando a lo loco… sin resultado… jajaja bueno, ruego me contesten cuando antes porfavor. GRACIAS

  • /* —————————————————————-
    http://www.prometec.net
    Prog_84_1

    Usando un Arduino keypad Shield
    http://www.prometec.net/lcd-keypad-shield/
    ——————————————————————–
    */
    #include
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    // define some values used by the panel and buttons
    int lcd_key = 0;
    int key = 0;
    #define btnRIGHT 0
    #define btnUP 1
    #define btnDOWN 2
    #define btnLEFT 3
    #define btnSELECT 4
    #define btnNONE 5
    int BacklitPin=10;
    int conteo=0;

    void setup()
    {
    pinMode(BacklitPin,OUTPUT);
    digitalWrite(BacklitPin,HIGH);
    lcd.begin(16,2);
    lcd.setCursor(3,0);
    lcd.print(“BIENVENIDO”);
    lcd.setCursor(4,1);
    lcd.print(“IYP-UDB”);
    delay(2500);
    }

    void loop()
    {
    lcd_key = read_LCD_buttons();

    if( lcd_key == btnSELECT){
    digitalWrite(BacklitPin,HIGH);
    }
    if ( lcd_key == btnLEFT ){
    digitalWrite(BacklitPin,LOW);
    }
    if ( lcd_key == btnUP){
    conteo++;
    lcd.clear();
    }
    if (conteo= 51){
    lcd.clear();
    lcd.setCursor(4,0);
    lcd.print(“**Fin**”);
    delay(15);
    conteo=0;
    }
    }

    }

    int read_LCD_buttons() // Lee los botones y devuelve le valor pulsado
    {
    key = analogRead(0); // Leemos la puerta A0
    // Mis botones dan: 0, 145, 329,507,743 ; Comprueba que tu shield devuelve valores parecidos
    // Y ahora los comparamos con un margen comodo

    if (key > 1000) return btnNONE; //Si no se pulsa nada salimos (el 99% de las veces)
    if (key < 50) return btnRIGHT;
    if (key < 250) return btnUP;
    if (key < 450) return btnDOWN;
    if (key < 650) return btnLEFT;
    if (key < 850) return btnSELECT;

    return btnNONE; // when all others fail, return this…
    }

    Quiero que cada vez que aprete UP aumente 1 en el conteo porque lo de la luz me lo hace pero al presionar UP no me muestra un conteo correcto que hago? Te agradeceria si me instruyeras por favor 😀

    • Hola Ricardo,

      Te pongo un codigo que creo que es lo que creo que quieres hacer. Ten en cuenta que, no uso buton left porque mi shield esta jodido ese boton sino el UP vale?

      void loop()
      {
      delay(500);
      lcd.clear();

      lcd_key = read_LCD_buttons();
      lcd.setCursor(0,1); // Cursor a linea 2, posicion 1

      if( lcd_key == btnRIGHT) lcd.print(“RIGHT “);
      if ( lcd_key == btnUP )
      { lcd.print(“UP “);
      conteo++ ;

      lcd.setCursor(0,0); // Cursor a linea 2, posicion 1
      lcd.print(conteo);

      if (conteo== 6)
      { lcd.clear();
      lcd.setCursor(0,1); // Cursor a linea 2, posicion 1
      lcd.print(“**Fin**”);
      delay(500);
      conteo=0;
      }
      }
      }

  • Disculpar mi ignorancia, pero cuando pasamos el proyecto a real, es decir, colocamos la pantalla dentro de una caja, como se pueden accionar los botones? Existen “alargos” para poder pulsar desde una caja?
    Muchas gracias

    • Supongo que seria mas sencillo recortar un area en la caja de modo que podamos encajar el shield con sus botones de modo que queden accesibles

  • Hola, tengo el mismo modelo de pantalla que usas solo que al cambiar cualquier digito o letra se ve una tranisicion rara, como si quedara el “fantasma del anterior digito” unos momentos.A que se debe esto y como pudeo corregirlo.

    • Pues me temo Jonathan que parece probable un defecto de tu shield porque en principio no he apreciado algo asi hasta el momento

  • El código no me funciona … al subirlo al arduino me sale :

    sketch_sep26a.ino:3:1: error: ‘key’ does not name a type
    sketch_sep26a.ino:11:1: error: ‘key’ does not name a type
    sketch_sep26a.ino: In function ‘void loop()’:
    sketch_sep26a.ino:35:17: error: ‘key’ was not declared in this scope
    sketch_sep26a.ino:38:34: error: ‘read_LCD_buttons’ was not declared in this scope
    Error de compilación

    Al poner un “int” delante del “key” funciona pero al leer por pantalla el valor de analogRead me sale 0 siempre…

    • Hola Edgar, no se porque no habia puesto el programa para descargar, pero ya esta corregido.
      He añadido un vinculo al programa Sesion_84 que confio resuleva tu problema.
      A mi me funciona, pero ya me diras

      Un saludo

    • Leon

    Como puedo conseguir la programacion y los circuitos por favor

    • No estoy seguro de entender tu pregunta. SI te refieres a adquirir el material a lo largo de la semana espero tener en marcha la tienda donde podras comprar el material si te interesa. Un saludo

    • Hola León. Si te refieres al sketch, solo debes copiar los trozos de programa por orden en el IDE y compilar. En cuanto al esquema, Admin deja el enlace “Display LCD” que nos remite al anterior tutorial con los LCD y allí estan las conexiones.
      Saludos.

Give a Reply

WordPress Anti-Spam by WP-SpamShield