domingo, 31 de enero de 2016

Verificando los valores del teclado del LCD Keypad Shield para Arduino


En este breve post os dejo un pequeño programa para verificar el valor que genera en la entrada A0 el teclado del LCD Keypad Shield para Arduino. Este display dispone de un teclado que se conecta a la entrada analógica A0 a través de un divisor resistivo, y en función del valor de la tensión que se genera en esta entrada al pulsar cada una de sus teclas, obtendremos un valor numérico que usaremos para discriminar cada tecla cuando las usemos en nuestros programas. 



Se preguntarán, ¿por qué necesitamos esto? La razón es que para cada LCD Keypad Shield que compremos, debido a la importante tolerancia de los resistores empleados en este divisor, los valores obtenidos en A0 serán distintos. Esto no es sólo un test, como los que en la web del display con teclado podemos encontrar, es un test que nos da directamente el valor que obtenemos en esa entrada, y para verificación, usando la función int read_LCD_buttons(), también dispondremos de un número, entre el 0 y el 5, para cada tecla:


0 -------> Nada
1 -------> Derecha
2 -------> Arriba
3 -------> Abajo
4 -------> Izquierda
5 -------> Menú

¿Cómo se ajusta el valor de discriminación para cada tecla? Después de cargar el programa verificamos que al pulsar cada tecla ninguno de los números que devuelve la función int read_LCD_buttons(), es decir, entre el 0 y el 5, se repitan. Si se repite alguno es que precisamos cambiar el rango de valores en las sentencias condicionales de nuestro código para que eso no sea así. Por ejemplo, en las siguientes:

int read_LCD_buttons() 
  { adc_key_in = analogRead(0);   // Leemos A0
    // Mis botones dan:  0(derecha), 99(arriba), 254(abajo),408(izquierda),638(menú), 1023(nada)
    // Y ahora los comparamos con un margen cómodo
    if (adc_key_in > 900)  return btnNONE;    // Ningun boton pulsado
    if (adc_key_in < 50)   return btnRIGHT;   // Botón derecho
    if (adc_key_in < 200)  return btnUP;      // Botón arriba
    if (adc_key_in < 350)  return btnDOWN;    // Botón abajo
    if (adc_key_in < 500)  return btnLEFT;    // Botón izquierdo
    if (adc_key_in < 850)  return btnSELECT;  // Botón Menú

    return btnNONE;  // Siempre por defecto nada (0)
  }

Para el 0, sin pulsar ninguna tecla, en la entrada A0 de mi Arduino, el LCD Keypad Shield  impone un valor de 1023, como podemos apreciar en la imagen superior.
Para el 1 el valor es el siguiente:


Para el 2:


Para el 3:


Para el 4:


Para el 5:


El código es el siguiente:


// LCD Keypad Shield ROBOT Drive the future
// por Nacho. Dominio público
// librería LCD y definición de las conexiones de los pines.

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

// Algunas definiciones por comodidad, para otorgar a cada tecla un número: 0(nada), 1(derecha),
// 2(arriba), 3(abajo), 4(izquierda) y 5(menú)

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

// Para leer los botones, definimos una función con los rangos de valores que adquiere
// la entrada A0 de la red resistiva a la que están conectados los botones

int read_LCD_buttons() 
  { adc_key_in = analogRead(0);   // Leemos A0
    // Mis botones dan:  0(derecha), 99(arriba), 254(abajo),408(izquierda),638(menú), 1023(nada)
    // Y ahora los comparamos con un margen cómodo
    if (adc_key_in > 900)  return btnNONE;    // Ningun boton pulsado
    if (adc_key_in < 50)   return btnRIGHT;   // Botón derecho
    if (adc_key_in < 200)  return btnUP;      // Botón arriba
    if (adc_key_in < 350)  return btnDOWN;    // Botón abajo
    if (adc_key_in < 500)  return btnLEFT;    // Botón izquierdo
    if (adc_key_in < 850)  return btnSELECT;  // Botón Menú

    return btnNONE;  // Siempre por defecto nada (0)
  }

// Mensaje en pantalla 
void setup() {  lcd.begin(16, 2);     // Inicializar el LCD
                lcd.setCursor(0,0);
                lcd.print("Cotidiana Place");  // Imprime un título en la primera línea del display
}

void loop() {
      // Gestiona los valores en la pantalla
      lcd.setCursor(10,1);        // Cursor a linea 2, posicion 9    
      lcd.print(adc_key_in);      // Imprime valor de la entrada Analógica 0,
                      // donde está conectada la red resistiva de los botones
      lcd.setCursor(10,1);
      delay(250);  // Es necesaria esta pausa para visualizar correctamente
                          // el valor de la variable adc_key_in
      lcd.print("    ");   // Limpiar el valor en el display de la variable
                                 // anterior para que no se solapen los números
      lcd.setCursor(15, 1);      // Cursor a linea 1, posicion 14
     
      lcd.print(lcd_key); // Imprime el valor de lcd_key, valor numérico que
                                    // devuelve el valor numérico de la función read_LCD_buttons
     
      lcd.setCursor(0,1);        // Cursor a línea 2, posición 1

      lcd_key = read_LCD_buttons();
      if( lcd_key == btnRIGHT)
              lcd.print("DERECHA ");
      else if ( lcd_key == btnLEFT )
              lcd.print("IZQUIERDA");
      else if ( lcd_key == btnUP)
              lcd.print("ARRIBA   ");
      else if ( lcd_key == btnDOWN)
              lcd.print("ABAJO    ");
      else if ( lcd_key == btnSELECT)
              lcd.print("MENU:   ");
      else if ( lcd_key == btnNONE)
              lcd.print("NADA     ");
}

// Fin de programa

Usando este sistema para disponer de un pequeño teclado se ahorran muchos pines, pero también es cierto que no se pueden usar las teclas pulsadas simultáneamente.
Para cargar el código sólo tienen que copiar, y luego pegar en el entorno IDE de programación de Arduino.

No hay comentarios:

Publicar un comentario en la entrada