• Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.

Display LCD mediante bus I2C/TWI

Los displays LCD son muy útiles para mostrar todo tipo de información sin necesidad de tener conectado el ordenador a nuestro Arduino, de esa forma podemos hacer proyectos que sean totalmente independientes de un ordenador y que al mismo tiempo nos permitan visualizar todo tipo de información, desde mensajes pre-cargados hasta el valor de variables de nuestro sistema.

En este tutorial vamos a ver como conectar un display LCD mediante el protocolo I2C. El conectar el display de esta forma nos va a simplificar en gran medida el proyecto ya que tan solo vamos a hacer uso de 2 cables para la comunicación entre nuestro Arduino y el display LCD. Si conectásemos el display sin el módulo interface serie I2C/SPI necesitaríamos al menos 6 cables para el funcionamiento de la pantalla (además de los cables para la alimentación del display).

displayI2C

Otra ventaja de usar un bus I2C para la conexión es que además del display también podemos conectar otros dispositivos a la misma línea i2C, por lo que con tan solo 2 cables podemos conectar innumerables dispositivos.

¿Que es el bus I2C?

El bus I2C es un bus de datos serie desarrollado por Philips en 1982, este bus se utiliza mayoritariamente para la comunicación entre un microcontrolador y diferentes periféricos. Por motivos de licencia, atmel introdujo el TWI (Two-Wired-Interface) en sus productos, pero aunque tengan diferente nombre, el TWI y el I2C son idénticos a nivel técnico.

El bus I2C esta diseñado como un bus de comunicación Maestro-Esclavo, esto quiere decir que hay un dispositivo maestro que regula la comunicación y uno o mas dispositivos esclavos que funcionan a petición del maestro. Existe la posibilidad de que un sistema posea mas de un Maestro (modo Multimaestro), pero tan solo puede haber un maestro activo al mismo tiempo, ya que estos dispositivos son los que gestionan la velocidad de comunicación y habilitan o no los diferentes periféricos, si hubiera 2 Maestros conectados al mismo tiempo ocasionarían graves problemas de comunicación.

El Bus I2C está formado por dos líneas, SLK (Serial Clock) y SDA (Serial Data) o lo que es lo mismo una línea por donde se transmite la información (SDA) y otra que marca la velocidad de comunicación (SLK) además de marcar los tiempos para la lectura/escritura en el bus.

Información

Ambas líneas precisas una resistencia de PullUp conectada a Vcc, el valor de esta resistencia suele estar comprendido entre 1KΩ y 2KΩ

I2C

Algo que debéis tener en cuenta cada vez que trabajáis con el bus I2C es que cada elemento conectado al bus tiene una dirección, por lo que para comunicarnos con cada dispositivo debemos conocer su dirección, en los siguientes apartados os enseñaré como ver la dirección del dispositivo, ya que es un error muy común el poner una dirección errónea haciéndonos pensar en muchas ocasiones que el dispositivo I2C esta estropeado.

Los microcontroladores de Atmel incorporan todo el Hardware necesario para realizar comunicaciones mediante el bus I2C, lo único que hay que tener en cuenta cuanto trabajemos con este bus en Arduino es añadir la librería Wire.h, esta librería nos va a simplificar mucho el trabajo, ya que usando un juego de instrucciones simples podremos controlar todas las funciones del bus I2C sin problemas.

Descarga

Podéis descargaros la librería Wire.h aqui

Si queréis saber más sobre la librería wire.h podéis consultar este link del sitio oficial

Módulo adaptador a I2C/TWI

adaptadorI2CPara adaptar la señal entre la pantalla y nuestro Arduino usamos un módulo que hace la vez de interface entre estos dispositivos, este módulo irá soldado al display o fijado mediante un conector dejando en uno de sus extremos 4 pines para la conexión con Arduino y para la alimentación del display.

Este módulo funciona con una alimentación de 5 voltios (que deberá ser conectada al terminal Vcc) y cuenta con un potenciómetro para el ajuste del contraste de la pantalla.

El "Jumper Backlight" debe de estar colocado si queremos que la luz de fondo de la pantalla pueda usarse, si retiramos este jumper evitamos así que se encienda.

De fabrica este módulo viene con una dirección preestablecida, si queremos cambiarla debemos de puentear los pines del selector de dirección para conseguir otra dirección.

Dirección A0 A1 A2
0x20 0 0 0
0x21 1 0 0
0x22 0 1 0
0x23 1 1 0
0x24 0 0 1
0x25 1 0 1
0x26 0 1 1
0x27 1 1 1

El módulo puede comprarse ya integrado en la pantalla o separado y soldarlo directamente o ponerle un conector para poder quitarlo y ponerlo.

Conexionado

El conexionado de este módulo es muy sencillo, tan solo hay que conectar la alimentación del módulo y las líneas SDA y SCL a los pines correspondientes de nuestra placa Arduino. Hay que tener en cuenta que según el Arduino que usemos debemos de conectarlo en un pin u otro, ya que los pines SCL y SDA están asociados a diferentes pines dependiendo del modelo de Arduino.

displayI2C bb fritzing

En mi caso para hacer el montaje he usado un Arduno UNO, por lo que he conectado el PIN (A4) a SDA y el PIN (A5) a SCL, pero según el modelo de Arduino deberéis de conectarlo a uno u otro pin, aquí os dejo una lista con los pines usados para el Bus I2C de los Arduinos más comunes:

Placas I2C / TWI pins
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL)

¿Como obtener la dirección del dispositivo I2C?

Como os comenté anteriormente es muy importante cuando trabajamos con dispositivos conectados a un bus I2C conocer la dirección del dispositivo, en internet hay muchos tutoriales de como conectar este tipo de displays y muchas veces no funcionan por que la dirección que traen no es la adecuada, haciéndonos creer que nuestro display esta estropeado.

Para esto antes de meternos con el programa principal vamos a instalar un pequeño programa en nuestro arduino que nos va a dar la dirección del dispositivo conectado al bus I2C.

I2C Scanner

El I2C Scanner es un programa que se carga en nuestro Arduino y detectará la dirección de los dispositivos que estén conectados al bus I2C.

Descarga

Podéis descargar el I2C Scarner aqui

Para ejecutar el I2C Scanner tan solo hay que cargar el programa en Arduino, conectar el dispositivo en el Bus I2C y abrir el monitor serie, donde se mostrará la siguiente pantalla con los datos leídos.

I2CScanner

Como podéis observar en mi caso el display me ha dado la dirección 0x27, esta dirección debéis guardarla, ya que la vamos a usar posteriormente en nuestro programa.

Programa Básico

Ahora que ya tenemos conectado nuestro diplay y que conocemos su dirección vamos a escribir un pequeño programa para ver lo sencillo que es mostrar datos en el display.

#include <Wire.h>  // Incluimos la librería Wire.h
#include <LCD.h>   // Incluimos la librería para el uso del display
#include <LiquidCrystal_I2C.h>  // Librería para la comunicación del display mediante I2C 

#define I2C_ADDR    0x27  // Dirección del dispositivo I2C

LiquidCrystal_I2C             lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);
void setup()
   {
       lcd.begin (16,2);    // Inicializar el display con 16 caracteres 2 lineas
       lcd.setBacklightPin(3,POSITIVE);
       lcd.setBacklight(HIGH);  
   }
void loop() 
   {
     lcd.home ();                   // go home
     lcd.print("   ZONA MAKER");    // Muestra en pantalla
     lcd.setCursor ( 0, 1 );        // Cursor a la primera posición de la segunda linea
     lcd.print("Hola mundo!");      // Muestra en pantalla
   }

Como podéis ver es un programa muy sencillo, se pueden identificar claramente la cabecera (que tiene las librerías, objetos, variables...) el bloque setup (donde configuramos e inicializamos los diferentes elementos que tengamos) y el bloque loop (que contendrá las instrucciones de nuestro programa principal).

La cabecera de programa

En este caso la cabecera contendrá las librerías que vamos a usar en nuestro programa, la dirección del dispositivo I2C y un objeto llamado "LiquidCrystal_I2C" que contendrá la dirección del dispositivo i2C además de los pines a los que va asociado el display (No son los pines de Arduino).

#include <Wire.h>  // Incluimos la librería Wire.h
#include <LCD.h>   // Incluimos la librería para el uso del display
#include <LiquidCrystal_I2C.h>  // Librería para la comunicacion del display medianet I2C 

#define I2C_ADDR    0x27  // Dirección del dispositivo I2C

LiquidCrystal_I2C             lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);

La librería Wire.h es la que se encargará de establecer la comunicación usando el protocolo i2C, esta librería estaba integrada de serie en las primeras versiones del IDE de Arduino, si tu versión de Arduino no la incorpora puedes descargarla en el apartado ¿Que es el bus I2C?

La librería LCD.h viene de serie con todas las versiones del IDE de Arduino y no es necesario que lo instaléis.

La librería LiquidCrystal_I2C.h es una librería creada por F. Malpartida (http://blog.electrofunltd.com/) y que a dia de hoy es considerada una de las mejores para la utilización de displays LCD mediante el protocolo I2C.

Descarga

Podés descargaros la librería LiquidCrystal_I2C.h de F. Malpartida aqui

Como podéis observar en la cabecera es donde debemos introducir la dirección que obtuvimos del "I2C Scanner", en mi caso me ha dado 0x27, si a vosotros os ha dado otra debéis sustituirlo en el programa, en la parte donde pone #define I2C_ADDR  0x27

El Bloque setup()

Como siempre en el bloque setup(), vamos a configurar nuestro dispositivo, en este caso el display.

void setup()
   {
       lcd.begin (16,2);    // Inicializar el display con 16 caracteres 2 lineas
       lcd.setBacklightPin(3,POSITIVE);
       lcd.setBacklight(HIGH);  
   }

En mi caso he usado 3 instrucciones, aunque tan solo lcd.begin es totalmente necesaria.

lcd.begin(16,2) --> Esta instrucción inicializa nuestro display y además especifica que estamos usando un display de 16 caracteres y 2 líneas, si estamos usando un display de 20 caracteres y 4 líneas la instrucción quedaría lcd.begin(20,4).

lcd.setBacklightPin(3,POSITIVE) ---> Esta instrucción establece que el pin 3 del display es el que enciende y apaga la luz de fondo.

lcd.setBacklight (HIGH) --> Con esta instrucción encendemos la luz de fondo de nuestro display, en este caso la enciendo en el setup, porque quiero que esté siempre encendida, en muchos casos esta instrucción se pone en el programa principal asociada a la pulsación de un botón o a algún otro evento, de esa forma el display permanecerá apagado consumiendo menos mientras y lo encenderemos solo cuando lo necesitemos.

El Bloque loop()

Este bloque contiene el programa principal, que en este caso mostrará por pantalla un mensaje, esta no es la mejor forma de mostrar datos por pantalla, ya que estamos refrescando los datos de la pantalla continuamente para un texto que no cambia, pero para nuestro ejemplo nos sirve sin problemas.

void loop() 
   {
     lcd.home ();                   // go home
     lcd.print("   ZONA MAKER");    // Muestra en pantalla
     lcd.setCursor ( 0, 1 );        // Cursor a la primera posición de la segunda linea
     lcd.print("Hola mundo!");      // Muestra en pantalla
   }

lcd.home () ---> Esta función coloca el cursor del display en la posición inicial (parte superior izquierda de la pantalla).

lcd.print (" MENSAJE" ) ---> La sintaxis de esta instrucción es muy parecida a la de escribir datos en el terminar, tan solo cambia "Serial" por "lcd", el funcionamiento es el mismo, escribe lo que le digamos en el display. Cuando escribamos debemos de tener en cuenta el espacio disponible, si la palabra tiene más letras que el espacio disponible no se mostrará completa.

lcd.setCursor (0,1) ---> Con esta instrucción podemos colocar el cursor en cualquier parte de la pantalla, una vez colocado, este será el punto desde el cual se empezará a escribir. Los dos valores que aparecen hacen referencia a la posición y la fila, en este ejemplo (0,1) indica que vamos a empezar a escribir en la posición 0 de la fila 1.

Información

Tanto la posición como la fila empiezan a contar desde 0, por lo que la fila 1 en realidad es la segunda fila

Una vez cargado el programa y si habéis seguido los pasos este será el resultado

resultado


Comentarios potenciados por CComment