En este artículo te explicamos como utilizar una pantalla LCD 16×2 por I2C con Arduino de manera que puedas aprovechar mejor tus pines de I/O.
La pantalla LCD de 16×2 es un periférico muy común, que se utiliza ampliamente en proyectos con Arduino y microcontroladores en general, sin embargo, es bien sabido por todo aquel entusiasta que ha incluido una en sus proyectos, que este tipo de pantalla requiere muchos pines del microcontrolador debido a que utiliza un bus paralelo para comunicarse.
Afortunadamente existe una solución muy fácil y económica para este problema: un adaptador basado en el PCF8574 que permite conectar la pantalla al Arduino usando solamente dos lineas digitales a través del bus I2C. Dichos pines, pueden además ser compartidos por otros periféricos como el RTC o memorias EEPROM.
En la foto principal vemos el Arduino UNO conectado a una pantalla LCD de 16 x 2 usando el bus I2C.
Materiales Necesarios
Los materiales para esta experiencia pueden encontrarse en nuestra tienda virtual, hace falta un poco de soldadura para poner a punto la pantalla con el adaptador I2C:
- Pantalla LCD 16×2 compatible con HD44780
- Adaptador para pantalla LCD I2C PCF8574
- Arduino UNO R3
- Cables tipo dupont Macho-Hembra
Preparación de la pantalla con el adaptador I2C
Para usar nuestra pantalla LCD 16×2 por I2C con Arduino el primer paso es soldar el adaptador I2C en la parte de trasera de la pantalla. Al finalizar la soldadura, nuestro adaptador debe verse de la siguiente manera:
Como se aprecia el adaptador para LCD 16×2 por I2C con Arduino nos permite ahorrar bastante tiempo en las conexiones, pues ya incluye el potenciómetro para regular el contraste de la pantalla. También incluye todo lo necesario para el funcionamiento del backlight (retro-iluminación), pudiendo incluso controlar esta función a través de software.
Si no queremos soldar el adaptador a la pantalla, podemos utilizar un protoboard para realizar la conexión entre ambas piezas, tal como se muestra a continuación.
Diagrama para conectar el LCD 16×2 por I2C
Una vez que tenemos soldado el adaptador I2C, hay que identificar los pines de I2C en la tarjeta Arduino que estemos usando. En el Arduino UNO, los pines del bus I2C corresponden con los analógicos A4 y A5. También los encontramos duplicados en la parte superior, cerca del conector USB y se etiquetan como SDA y SCL (por la parte de abajo del PCB).
Para realizar las conexiones con el Arduino te recomendamos revisar los mapas de pines en este post y tener la versión impresa siempre a la mano.
Las conexiones se realizan de la siguiente forma con el Arduino, como podemos ver estamos usando los pines analógicos A4 y A5, aunque también se puede conectar a SDA y SCL cerca del conector USB:
Programación de LCD 16×2 por I2C con Arduino
Descarga de librería para LCD 16×2 por I2C con Arduino
Para usar el LCD 16×2 por I2C con Arduino es necesario también agregar una librería a nuestro IDE, de forma que este sepa como comunicarse con el chip PCF8574.
Ya explicamos en alguna ocasión como cargar una librería y comenzar a utilizarla, si tienes dudas te recomendamos revisar el tutorial. Cabe aclarar que esta librería, así como el adaptador I2C deben funcionar de forma correcta con las pantallas de 20×4.
Puedes descargar la librería desde la página oficial en Bitbucket (repo).
Uso de la librería
La librería LiquidCrystal_I2C dispone de métodos similares (algunos idénticos) a los de la librería oficial.
- LiquidCrystal_I2C() – Constructor de la clase, configura el hardware.
- init() – Prepara el LCD para su uso.
- clear() – Borra todos los caracteres de la pantalla LCD.
- setCursor(col, row) – Permite mover el cursor a la posición indicada en sus parámetros.
- print() – Imprime una variable o literal en la pantalla
- scrollDisplayLeft() y scrollDisplayRight() – Recorre el contenido de la pantalla a la izquierda o a la derecha
- backlight() y noBacklight() – Métodos para encender / apagar la iluminación de fondo
- createChar(num, data) – Crear un carácter definido por el usuario en la memoria del controlador de pantalla
Recomendamos revisar el siguiente enlace para conocer todos los métodos de los que dispone la librería oficial LiquidCrystal:
Código básico para controlar LCD 16×2 por I2C con Arduino
El siguiente programa es un ejemplo básico para comenzar a utilizar nuestra pantalla y probar que las conexiones se encuentran correctas. Al cargarlo debemos ver letras en pantalla y además una animación del texto moviéndose. Hemos comentado lo más posible el código de manera que sea fácil de entender.
Si no se visualiza nada en la pantalla cuando se carga este programa, recomendamos mover el potenciómetro del contraste y/o revisar las conexiones del bus I2C. En el peor de los casos, si el adaptador I2C del que disponemos no es igual al de las fotos, puede ser necesario cambiar los parámetros al constructor de LiquidCrystal_12C.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /** GeekFactory - "Construye tu propia tecnologia" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx EJEMPLO BÁSICO PARA EL USO DEL LCD 16X2 A TRAVÉS DE I2C ESTE PROGRAMA MUESTRA UN MENSAJE EN UNA PANTALLA DE 16X2 Y REALIZA UNA ANIMACION DE DESPLAZAMIENTO DE UN EXTREMO A OTRO DE LA PANTALLA. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> // Constructor de la librería de LCD 16x2 // Aqui se configuran los pines asignados a la pantalla del PCF8574 LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); void setup() { // Indicar a la libreria que tenemos conectada una pantalla de 16x2 lcd.begin(16, 2); // Mover el cursor a la primera posición de la pantalla (0, 0) lcd.home (); // Imprimir "Hola Mundo" en la primera linea lcd.print("Hola Mundo"); // Mover el cursor a la segunda linea (1) primera columna lcd.setCursor ( 0, 1 ); // Imprimir otra cadena en esta posicion lcd.print("GEEKFACTORY"); // Esperar un segundo delay(1000); } void loop() { // EN EL CICLO PRINCIPAL SOLAMENTE RECORREMOS EL MENSAJE DE UN LADO A OTRO // Variable para conteo de ciclos int i; // Desplazar la pantalla a la derecha 2 veces for ( int i = 0; i < 5; i++ ) { lcd.scrollDisplayRight(); delay (1000); } // Desplazar la pantalla a la izquierda 2 veces for ( int i = 0; i < 5; i++ ) { lcd.scrollDisplayLeft(); delay (1000); } } |
Mostrar valores de sensores en LCD 16×2 por I2C con Arduino
La librería LiquidCrystal_I2C dispone de métodos idénticos a la librería oficial de Arduino, de forma que podamos migrar los programas fácilmente, incluidos aquellos en los que se utilizan las funciones de impresión directo en la pantalla. En el siguiente ejemplo, veremos como mostrar el contenido de variables enteras o de tipo flotante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** GeekFactory - "Construye tu propia tecnologia" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx EJEMPLO BÁSICO PARA EL USO DEL LCD 16X2 A TRAVÉS DE I2C ESTE EJEMPLO MUESTRA COMO IMPRIMIR EL VALOR DE UNA VARIABLE HACIA LA PANTALLA LCD de 16x2 A TRAVÉS DE I2C. ESTO PUEDE SER UTIL PARA VISUALIZAR EL VALOR LEIDO POR UN SENSOR, MOSTRAR UN CONTADOR, ETC. EN GENERAR SE PUEDE UTILIZAR EN CUALQUIER INTERFAZ DE USUARIO A DESARROLLAR CON LA PANTALLA LCD DE 16X2. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> // Constructor de la librería de LCD 16x2 // Aqui se configuran los pines asignados a la pantalla del PCF8574 // Este constructor es para usar con el modulo I2C que se muestra en las // fotografias de nuestro sitio web. Para otros modelos, puede ser necesario // cambiar los valores de acuerdo al esquemático del adaptador I2C. Los pines // del arduino SIEMPRE son los correspondientes al I2C (SDA y SCL) // Constructor sin control de backlight (retroiluminacion) //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // Constructor con control de backlignt (retroiluminacion) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); void setup() { // Indicar a la libreria que tenemos conectada una pantalla de 16x2 lcd.begin(16, 2); // Mover el cursor a la primera posición de la pantalla (0, 0) lcd.clear(); // Imprimir "Hola Mundo" en la primera linea lcd.print(" GEEKFACTORY.MX "); // Esperar un segundo delay(1000); } void loop() { // Actualizar la pantalla completa cada segundo lcd.clear(); // Imprimir encabezado lcd.print(" POTENCIOMETRO "); // Realizar la lectura analogica en A0 unsigned int val = analogRead(A0); // Convertir a voltaje float volts = (val * 5.0) / 1024.0; // Imprimir valores en la segunda linea lcd.setCursor(0, 1); lcd.print(val); // Imprimir el voltaje en la segunda linea, despues del valor del ADC lcd.setCursor(6, 1); lcd.print(volts, 1); // Esperar un segundo antes de continuar delay (1000); } |
Mostrar caracteres personalizados en LCD 16×2 por I2C
Las pantallas LCD 16×2 permiten definir hasta 8 caracteres personalizados, la librería LiquidCrystal_I2C provee las facilidades para realizar esta tarea de manera muy sencilla. Cada carácter se define como un grupo de 8 bytes que se envían a la memoria CGRAM. Por ejemplo, podemos crear un icono con una carita feliz de la siguiente forma:

Y traducido a código en C, quedaría de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 | byte smile[8] = { 0b00000000, 0b00001010, 0b00001010, 0b00001010, 0b00000000, 0b00010001, 0b00001110, 0b00000000, }; |
Podemos ponernos bastante creativos con esta funcionalidad del LCD y podemos obtener resultados bastante llamativos como se puede ver en la siguiente imagen:

El siguiente programa nos muestra como dar de alta caracteres personalizados en un LCD 16×2 por I2C con Arduino
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | /** GeekFactory - "Construye tu propia tecnologia" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx EJEMPLO BÁSICO PARA EL USO DEL LCD 16X2 A TRAVÉS DE I2C ESTE EJEMPLO MUESTRA COMO IMPRIMIR EL VALOR DE UNA VARIABLE HACIA LA PANTALLA LCD A TRAVÉS DE I2C. ESTO PUEDE SER UTIL PARA VISUALIZAR EL VALOR LEIDO POR UN SENSOR, MOSTRAR UN CONTADOR, ETC. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> // Constructor de la librería de LCD 16x2 // Aqui se configuran los pines asignados a la pantalla del PCF8574 // Este constructor es para usar con el modulo I2C que se muestra en las // fotografias de nuestro sitio web. Para otros modelos, puede ser necesario // cambiar los valores de acuerdo al esquemático del adaptador I2C. Los pines // del arduino SIEMPRE son los correspondientes al I2C (SDA y SCL) // Constructor sin control de backlight (retroiluminacion) //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // Constructor con control de backlignt (retroiluminacion) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Definicion de caracteres personalizados byte smile[8] = { 0b00000000, 0b00001010, 0b00001010, 0b00001010, 0b00000000, 0b00010001, 0b00001110, 0b00000000, }; byte sad[8] = { 0b00000000, 0b00001010, 0b00001010, 0b00001010, 0b00000000, 0b00001110, 0b00010001, 0b00000000, }; byte body[8] = { 0b00001110, 0b00001110, 0b00000100, 0b00011111, 0b00000100, 0b00001010, 0b00010001, 0b00000000, }; byte arrowr[8] = { 0b00001000, 0b00000100, 0b00000010, 0b00011111, 0b00000010, 0b00000100, 0b00001000, 0b00000000, }; byte arrowu[8] = { 0b00000100, 0b00001110, 0b00010101, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000000, }; byte arrowd[8] = { 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00010101, 0b00001110, 0b00000100, 0b00000000, }; byte arrowl[8] = { 0b00000010, 0b00000100, 0b00001000, 0b00011111, 0b00001000, 0b00000100, 0b00000010, 0b00000000, }; void setup() { // Indicar a la libreria que tenemos conectada una pantalla de 16x2 lcd.begin(16, 2); // Crear los caracteres personalizados en la pantalla lcd.createChar (0, smile); lcd.createChar (1, sad); lcd.createChar (2, body); lcd.createChar (3, arrowr); lcd.createChar (4, arrowu); lcd.createChar (5, arrowd); lcd.createChar (6, arrowl); // Mover el cursor a la primera posición de la pantalla (0, 0) lcd.clear(); // Imprimir "Hola Mundo" en la primera linea lcd.print(" GEEKFACTORY.MX "); // Mover cursor lcd.setCursor(0, 1); // Escribir bytes a la pantalla // Los códigos del 0 al 7 corresponden a los caracteres personalizados lcd.write((byte)0); lcd.write((byte)1); lcd.write((byte)2); lcd.write((byte)3); lcd.write((byte)4); lcd.write((byte)5); lcd.write((byte)6); } void loop() { } |
Conclusión
- En este artículo vimos una forma más eficiente en cuanto al uso de pines para conectar una pantalla LCD de 16 x 2 al Arduino
- Revisamos las conexiones a realizar y vimos que podemos convertir la pantalla estándar a una interfaz I2C de forma permanente.
- También aprendimos a realizar las conexiones en el protoboard, sin necesidad de soldar definitivamente el adaptador I2C
- Descargamos e instalamos la librería correspondiente para controlar la LCD 16×2 por I2C con Arduino
- Realizamos un ejemplo básico para mostrar texto en la pantalla
- Aprendimos a mostrar el valor de las variables en la pantalla LCD
- Mostramos como podemos crear caracteres personalizados y mostrarlos en la pantalla