ARD12 – Pantalla LCD

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

En este artículo vamos a aprender a usar una pantalla de cristal líquido (LCD) para que nuestra placa Arduino nos pueda enviar mensajes escritos. En realidad, para enviarnos mensajes escritos, podríamos usar la consola serie que ya conocemos, pero, ¿qué ocurre si, una vez que el sketch esté cargado en la placa Arduino, queremos que pueda funcionar independientemente de un ordenador? Ahí entra en juego el incorporar un sistema de visualización de datos autónomo, que pueda funcionar, simplemente, conectado a Arduino. La pantalla que vamos a usar aquí es el modelo LCD 1602A, que es de uso muy común, cuenta con dos líneas de visualización de datos, de 16 caracteres cada una.

Figura 12.1. El display fotografiado por delante y por detrás.

Figura 12.1. El display fotografiado por delante y por detrás.

No parece mucho, sobre todo comparado con otros dispositivos de visualización que hay en el mercado, pero, para nuestros propósitos didácticos es, de momento, más que suficiente. Además cuenta con la ventaja de ser un dispositivo barato, muy bien documentado en Internet, y de fácil adquisición, además de fácil de programar en entorno Arduino, gracias a una librería (llamada LiquidCrystal) que aprenderemos a manejar en este artículo. 

Figura 12.2. Nomenclatura de las conexiones del 1602A

Figura 12.2. Nomenclatura de las conexiones del 1602A

En la figura 12.1 vemos esta pantalla.

Como ves, tiene 16 puntos de conexión (a los que se pueden soldar cablecillos, o una tira de pines para conexión). Si la compras en una tienda de electrónica es posible, incluso, que ya venga con la tira de pines soldada, para facilitar su conexión a la placa protoboard. Si no, tendrás que soldar tú mismo la tira de pines, lo que puede ser un poco pesado pero, en ningún caso, difícil. En todo caso, el coste de este módulo ronda entre 8 y 11 euros, según donde la adquieras.

Los terminales de la pantalla los vemos en el esquema de la figura 12.2.

La relación de estos terminales aparece a continuación:

  • Vss. Es el pin de negativo (GND).
  • Vdd. Es el pin de alimentación, a 5V.
  • Vo. Este pin regula el contraste de la pantalla. Se puede conectar con un potenciómetro de 10 K, para facilitar una visualización adecuada.
  • RS. El selector de registro. Permite enviar a la pantalla instrucciones para visualizar caracteres, cambiar la posición del cursor, borrar la pantalla, etc.
  • R/W. Si está a 0 (a masa) permite escribir en la pantalla.
  • E. Habilita la pantalla para recibir datos.
  • D0-D7. Es un bus de datos de 8 bits.
  • A y K. Son los pines que determinan la retroiluminación de la pantalla, para mejorar la visualización. El A se conecta a 5 V. y el K a masa.

En realidad, a la pantalla le llegan los datos codificados por el bus D0-D7, y las señales de control, claro, pero nosotros no tenemos que preocuparnos por esto. La librería LiquidCrystal que vamos a usar en este montaje hace todo el trabajo “sucio” por nosotros, de modo que sólo tenemos que preocuparnos de enviar los mensajes de la forma adecuada, lo que es muy simple, como veremos enseguida.

EL CIRCUITO

El esquema electrónico de este montaje es un poco más elaborado, y requiere cierta atención. Lo vemos en la figura 12.3.

Figura 12.3. El esquema teórico del montaje de este artículo.

Figura 12.3. El esquema teórico del montaje de este artículo.

Cómo se puede ver, hay bastante cableado, dados los puntos del LCD que hay que conectar. Observa que del bus de datos sólo se emplean los cuatro últimos bits (D4- D7). Los cuatro primeros están reservados a otra finalidad y no se emplean aquí.

El potenciómetro regula el contraste. Si al poner en marcha el montaje no ves nada en la pantalla, gíralo hasta que encuentres el punto de mejor visualización.

Cuando cargues el sketch y lo pongas en marcha, verás un mensaje diferente en la pantalla cada vez que oprimas y sueltes el pulsador.

En la figura 12.4 ves una representación del montaje físico de este circuito. Por supuesto, es orientativa. Tú puedes, por ejemplo, montar el display directamente sobre la protoboard, si tienes tira de pines, o el potenciómetro, si lo cambias por uno de circuito impreso, etc.

Figura 12.4. El montaje cableado de este artículo.

Figura 12.4. El montaje cableado de este artículo.

EL SKETCH

El sketch de este circuito es más extenso que otros que hemos visto, pero verás que es más fácil de entender de lo que parece a primera vista. El listado completo es el siguiente:

En la primera línea vemos que se incluye una librería cuyo nombre ya nos indica claramente que implementa las funcionalidades para gestionar un display de cristal líquido.

#include <LiquidCrystal.h>

Esta librería (así como la que usamos para servomotores en un capítulo anterior, y otras que iremos usando) es oficial de Arduino, y forma parte del entorno de programación cuando lo instalas, por lo que no es necesario descargarla aparte de ninguna web. Solo la incluimos como hemos visto y ya la tenemos disponible en nuestro sketch.

A continuación usamos el constructor de la clase LiquidCrystal para crear un objeto que represente a nuestro display, al que llamamos LCD. Los argumentos que le pasamos son (por este orden):

  • Los pines de Arduino donde se conectan los terminales Rs y E del display.
  • Los pines de Arduino donde se conectan los bits de D4 a D7 del display.

Observa en las figuras 12.3 y 12.4 como se corresponden. El objeto, por tanto, se crea como hemos visto:

LiquidCrystal LCD (12, 11, 5, 4, 3, 2);

A continuación definimos una constante para referirnos al pin donde se conectará el pulsador, así como unas variables que usaremos en el sketch y que representarán el estado del pulsador (oprimido o no), el estado anterior del pulsador (para comprobar si lo hemos cambiado pulsando o soltando) y una variable en la que se generará un número aleatorio, que luego veremos que determinará el mensaje a mostrar en el display.

const int pulsador = 6;
int estadoCom = 0;
int estadoComPrevio = 0;
int respuesta;

En la sección setup lo primero que vemos es cómo configuramos el pin asignado al pulsador como de entrada. Esto es la forma habitual de configurar un pin de Arduino, y no vamos a detenernos más en ello. A continuación empezamos a inicializar el display:

LCD.begin(16,2);

El método begin(w, h) del objeto de la clase LiquidCrystal permite la inicialización del display. Como argumentos recibe el número de caracteres que puede contener cada fila, y el número de filas. Esto es así porque esta clase podría manejar otros displays LCD con otras características.

El método write(cadena) del objeto escribe una cadena de texto en la pantalla. La cadena se escribe a partir de la posición del cursor. Como acabamos de inicializar el objeto, el cursor está, por defecto, en el primer carácter de la primera fila.

LCD.write("Inicio:");

A continuación el cursor está situado (aunque no sea visible como tal) en la siguiente posición al último carácter que se ha escrito en el display. Ahora lo reposicionamos al primer carácter de la segunda fila, así:

LCD.setCursor(0, 1);

El método setCursor(x, y) recibe dos argumentos. El primero se refiere al carácter dentro de un fila donde queremos posicionar el cursor. El segundo se refiere a la fila. Tanto los caracteres como las filas empiezan a contarse desde 0. En la línea de ejemplo ponemos el cursor en el carácter 0 (primer carácter) de la fila 1 (segunda fila).

LCD.write("Fin de setup");

Escribimos otro mensaje que, como veremos durante la ejecución, se extiende desde donde hemos posicionado el cursor.

En la sección loop englobamos el código en unos condicionales que permiten determinar si el estado del pulsador ha cambiado y ha pasado a ser LOW (soltado). Es entonces cuando se dispara el proceso interno que devuelve un mensaje al display. Observa la siguiente estructura:

Tanto la lectura en sí misma del estado del pulsador, como los condicionales necesarios ya nos son familiares, por lo que, una vez que se cumplen las condiciones, vamos a centrarnos en el proceso.

LCD.clear();

Este es el principio del proceso. El método clear(), que no recibe argumento alguno, borra el display y sitúa el cursor en el primer carácter de la primera fila.

A continuación escribimos un mensaje, así:

LCD.write("Numero al azar:");
LCD.setCursor(0, 1);

Cómo puedes ver, después de escribir este mensaje fijo, situamos el cursor en el primer carácter de la segunda fila.

ATENCIÓN. Es muy importante situar, en cada momento el cursor donde queremos que se escriba lo siguiente que vayamos a mostrar. Si no lo hacemos, se empezará a escribir en la fila actual, en el siguiente carácter al último que se escribió. Si no cabe todo el contenido, este NO pasa automáticamente a la siguiente fila, sino que es truncado.

Obtenemos un número aleatorio entre 0 y 7, así:

respuesta = random(8);

La función random(n) genera un número aleatorio entre 0 y n-1. También podemos escribirla como random(m,n). En este último caso, generará un número aleatorio entre m y n-1.

El condicional switch evalúa una expresión. Según el valor de la misma, ejecutará el grupo de sentencias adecuado. Si estás familiarizado con este tipo de condicionales (habitual en cualquier lenguaje de programación), ya ves como actúa. Si no, te remito a la referencia del lenguaje Arduino que pondremos en otro artículo de esta serie. La sintaxis general de este condicional es la siguiente:

UNA VARIANTE

Vamos a escribir una variante que, tras generar un número aleatorio, lo muestre directamente en el display LCD, en lugar de mostrar el nombre del número, como hacíamos antes.

Lo primero que tenemos que saber es que al display no se le pueden enviar directamente datos de tipo numérico. Solo admite cadenas de texto. Por lo tanto, debemos convertir cada número generado a una cadena de texto. Arduino es un lenguaje fuertemente tipado, por lo que no se puede usar un dato como si fuera de otro tipo. Además, para convertir un valor numérico en cadena, tampoco podemos usar directamente una variable de tipo String, sino que debemos usar una matriz de datos de tipo char. Veamos el código y lo comentamos a continuación:

 

Observa la primera sección, donde se definen las variables. Hay una definición nueva:

char textoDeRespuesta[2];

Como ves, creamos una matriz de datos de tipo char de dos posiciones. El asignarle dos posiciones es porque, esta vez, el número aleatorio que generemos estará entre 0 y 99.

La sección setup no cambia. En la sección loop encontramos, después de la generación del número aleatorio, la siguiente línea:

sprintf(textoDeRespuesta, "%d", respuesta);

La instrucción sprintf() tiene varios usos. En este caso la usamos para convertir el número aleatorio obtenido en una secuencia de caracteres que se almacenará en la matriz char que habíamos creado. Observa los tres argumentos que le pasamos: el primero es el nombre de la matriz; el segundo es un comodín que será sustituido por el argumento pasado en tercer lugar y que, en nuestro ejemplo, contiene el número aleatorio obtenido. Esta sintaxis puede parecer un poco rebuscada, pero es la forma en que hace las cosas Arduino. Como la matriz de datos char tiene dos posiciones (lo que equivale a dos caracteres) si el número aleatorio tiene un solo dígito (si es menor de diez), este se almacenará en la primera posición, y la segunda quedará vacía. Si tiene dos dígitos, cada uno se almacenará en una posición.

Por último, enviamos la matriz completa al display. Al ser una matriz de caracteres el efecto es el de enviar una cadena de texto que, como hemos comentado, es lo que puede reconocer el LCD 1602.

Ahora supongamos que queremos mostrar en el display un número aleatorio entre 0 y 100, pero de tipo flotante, digamos con dos posiciones decimales. Lo primero que tenemos que saber es que la función random() solo devuelve números enteros. Por lo tanto, deberemos generar un aleatorio entre 0 y 10000 y luego dividirlo entre 100 y asignar el resultado a una variable flotante, así:

numeroAleatorio = random(0, 10000);
aleatorioDecimal = (float)numeroAleatorio/100;

Para convertir un número flotante en una matriz de caracteres ya no nos vale la función sprintf(). En su lugar emplearemos dtostrf(). Esta función recibe cuatro argumentos:

  • El número flotante a convertir.
  • El mínimo de caracteres que se emplearán, incluyendo el punto decimal.
  • La precisión, es decir, el número de decimales a mostrar.
  • El nombre de la matriz de tipo char donde se almacenará el resultado.

En el caso de querer convertir, como hemos dicho, un número flotante entre 0.00 y 99.99, emplearemos la siguiente instrucción:

dtostrf(numeroFlotante, 4, 2, matrizDeCaracteres);

El código completo queda así:

 

ATENCIÓN. La función random() genera lo que se llaman números pseudo-aleatorios. Esto quiere decir que puede entrar en un ciclo en el que repita dos o más veces el mismo número. La forma de evitar esto es mediante el uso de la función randomSeed(n) antes de ejecutar nuestro sketch. Por ejemplo, en la sección setup podríamos incluir una línea como la siguiente:

randomSeed(4);

Esto permitirá que durante la ejecución del sketch, la función random() genere realmente un número aleatorio. El argumento de randomSeed() puede ser cualquier número que no sea 0.

LA LIBRERÍA LiquidCrystal

La librería LiquidCrystal permite a Arduino comunicarse con un display LCD. Para ver una referncia de su funcionamiento con información interesante puedes pulsar este enlace.

 

     

3 comentarios:

  1. Pingback: ARD-SYN – La sintaxis de Arduino » eldesvandejose.com

  2. Pingback: La librería LiquidCrystal » eldesvandejose.com

  3. Pingback: ARD-SYN 03 – La sintaxis de Arduino (III) » eldesvandejose.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *