Wednesday 30 May 2012

LCD Shield with keypad para Arduino

Hola de nuevo, tengo en mente la creación de un sistema de control de accesos para la sala de servidores utilizando RFID para cuando sepa mejor como funciona arduino; una de las cosas que quiero ponerle es una pequeña pantalla LCD que muestre el nombre de la persona que se identifica, por lo que el otro día pedí una LCD Shield como la de la foto en dealextreme por unos 9$ que viene a ser unos 6€.


Un shield de arduino es una placa con una funcionalidad (las hay para wifi, controlador de motores, bluetooth, etc) que encaja perfectamente sobre la placa de arduino. por lo que no es necesario poner ningún tipo de cable para poder usar la funcionalidad inherente del shield.

Este tipo de pantalla no me servirá para mi proyecto ya que al ser un shield me limita las posibilidades de colocación de la pantalla, pero puede serme útil a la hora de entender como funcionan las pantallas LCD y como se comunica con Arduino.

La shield viene además de con la pantalla con una serie de botones que van todos conectados a una entrada analógica la A0 de arduino. Cada vez que se pulsa un botón arduino recibe un valor entre 0 y 1100 aproximadamente  en función del botón pulsado. Esto está muy bien ya que solo usaremos una entrada analógica para manejar un total de 5 botones si excluimos el reset.


Lo primero que intenté hacer al sacar el shield del sobre fue intentar probar el ejemplo que viene con el compilador de arduino que es tal que así:




// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}

Al ver que no funcionaba, entendí que el problema eran los pines que utiliza el lcd, el sketch del ejemplo utiliza (12,11,5,4,3,2), pero con mi shield no venía info alguna que dijera que pines de arduino utilizaba, por lo que el siguiente paso fue buscar info en la página de delaextreme que pines utilizan y encontré que los pines a usar eran (8, 9, 4, 5, 6, 7).

Sin embargo tras cambiar el código del programa seguía sin funcionar... El shield trae un potenciómetro que regula el contraste de las letras que aparecen en la pantalla y tras chequear lo con el polímetro ví que el valor que devolvía siempre era el mínimo... la placa estaba defectuosa. Por suerte, tenía a mano un potenciómetro que soldé en lugar del antiguo y el programa de hola mundo, empezó a mostrar la frase por la pantalla del arduino..





Ahora que todo funciona, solo queda hacer un programita para poder explorar un poco las posibilidades de la pantalla y de los botones de nuestro shield.








//Incluimos la librería de LCD que trae arduino
#include <LiquidCrystal.h>
//Indicamos los pins que vamos a usar para 
//comunicarnos con la pantalla
//En mi caso, al usar una lcd shield los botones
//son los siguientes
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//Creamos una constante para tomar 
//indicar a que pin está conectado
const int analogInPin = A0; 
//Creamos una variable para almacenar los 
//valores tomados por los botones
int sensorValue = 0;  

//Inicia el void setup que solo se ejecuta
//una vez
void setup() {
  //iniciamos el puerto serie
  //lo hemos usado para debugginh
  //y así ver los valores que devuelve 
  //al pulsar cada uno de los botones
  Serial.begin(9600); 
  //iniciamos también la pantalla lcd y le 
  //indicamos el número de columnas x el número de filas
  lcd.begin(16, 2);
  //Imprimimos por pantalla la frase HOLA MUNDO!
  lcd.print("HOLA MUNDO!");
  //Movemos el cursor a la segunda línea
  lcd.setCursor(0, 2);
  //Ponemos un mensaje en la segunda línea
  //que nos pide que pulsemos un botón
  lcd.print("Pulse un boton");
}

//Inicia el loop que se ejecutará 
//mientras el arduino esté conectado
void loop() {
  //Recogemos el valor en el pin analógico
  //que nos dirá que botón hemos pulsado
  sensorValue = analogRead(analogInPin);
  //Para hacer el debuggin hemos usado esta instrucción
  //que nos va mostrando en la pantalla del ordenador
  //el valor devuelto al pulsar cada botón  
  Serial.println(sensorValue); 
  //Ponemos un pequeño retardo para que 
  //podamos leer los valores sin marearnos
  delay(100); 
  //En el debuggin hemos visto que al no tener ningún botón
  //pulsado los valores devueltos están entre 
  //1020 y 1025 por lo que cuando se den valores distintos 
  //a ese rango se ejecutará lo que hay dentro del if
  if (sensorValue <1000 ||  sensorValue>1100) {
    //llamamos a la función limpiar línea que veremos 
    //un poco más abajo
    limpiarLinea();
    //Imprimimos por pantalla lo que nos devuelve
    //la función opcion(int) que veremos más abajo
    //y que comprueba a cuanto equivale el valor del sensor 
    //y en función de éste, nos devuelve una cadena de texto
    lcd.print(opcion(sensorValue));
  }  
}


//Esta función comprobará el valor 
//del pin analógico conectado a los botones
//para determinar que botón hemos pulsado
//y devolver un texto en función de este
String opcion(int sensor){
  //Solo explicaré el primero, ya que el resto de ifs
  //son iguales.
  //En el debug vimos que al pulsar la tecla left, nos devolvía
  //un valor de aprox 479 por lo que cuando el valor del sensor esté 
  //entre 400 y 500 devolverá la cadena de texto izquierda
  if(sensor > 400 && sensor<500){
    return("Izquierda");
  }
  if(sensor > 600 && sensor<750){
    return("Select");
  }
  if(sensor > 300 && sensor<350){
    return("Abajo");
  }
  if(sensor > 100 && sensor<150){
    return("Arriba");
  }
  if(sensor < 10){
    return("Derecha");
  }
}

//Esta función la llamamos cuando queremos borrar 
void limpiarLinea(){
  //Colocamos el cursor la principio de la segunda
  //línea
  lcd.setCursor(0, 2);
  //Con este bucle recorremos toda la línea y la ponemos
  //en blanco
  for (int i = 0; i < 16; i = i + 1) {
    lcd.print(" ");
  }
  //Volvemos a colocar el cursor
  //al principio de la línea
  //para cuando volvamos a escribir algo
  //salga desde el principio de la línea
  lcd.setCursor(0, 2);
}


El resultado del programa es el siguiente:



Como veis es bastante soso, pero a partir de aquí podemos empezar a hacer otros sketchs o mezclar los resultados mostrados por pantalla con algún sensor como el de temperatura...


7 comments:

  1. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Imagino que te has dado ya cuenta de que el potenciómetro viene defectuoso...

      Un saludo

      Delete
  2. Excelente , Muchas Gracias, la clave esta en la distribucion correcta de los pines.

    Saludos

    ReplyDelete
  3. Mu buen trabajo , a mi me paso lo mismo con los pines .
    una consulta , quiero usar la lcd para hacer un reloj con termómetro para el coche , tengo todo lo necesario , pero no se hacer el código , tengo por separado los dos códigos el de reloj ds1307 y el de la temperatura lm35 y quiero unirlos para que salga, hora ,fecha y temperatura y no soy capaz , puedes ayudarme ? .
    un saludo y gracias

    ReplyDelete
  4. Hola Vicente.

    Si tienes los dos códigos no deberías tener problema, mete el del reloj en una función, y el de la temperatura en otra, y luego desde el void loop puedes hacer por ejemplo que al pulsar uno de los botones llame a una u otra función...
    Si quieres mándame los códigos y te intento echar una mano.

    Saludos.

    ReplyDelete
  5. hola buenas tardes , tengo que programar un control de un invernadero con dos sensores de temperatura y una alarma los sensores de temperatura activan un motor el cual se activa si se supera un margen de temperatura. el margen de temperatura tiene que ser modificable por medio del display tanto como para un sensor como para el otro. me podria ayudar a porgramarlo?

    ReplyDelete
  6. hola, que mal acabo de comprar el mismo lo compre para un arduino mega 2560. por cual potenciometro debo cambiarlo?

    ReplyDelete