
Si alguna vez has intentado conectar una pantalla LCD a un Arduino, es posible que hayas notado que consume muchos pines. Incluso en el modo de 4 bits, el Arduino aún requiere un total de siete conexiones, que es la mitad de los pines de E/S digitales disponibles.
La solución es utilizar una pantalla LCD I2C. Consume solo dos pines de E/S que ni siquiera forman parte del conjunto de pines de E/S digitales y también se pueden compartir con otros dispositivos I2C.
Descripción general del hardware
Una pantalla LCD I2C típica consiste en una pantalla LCD de caracteres basada en HD44780 y un adaptador LCD I2C. Vamos a conocerlos uno por uno.
Pantalla LCD de caracteres
Fieles a su nombre, estas pantallas LCD son ideales para mostrar solo texto/caracteres. Una pantalla LCD de 16 × 2 caracteres, por ejemplo, tiene retroiluminación LED y puede mostrar 32 caracteres ASCII en dos filas de 16 caracteres cada una.

Si miras de cerca, puedes ver pequeños rectángulos para cada carácter en la pantalla y los píxeles que componen un carácter. Cada uno de estos rectángulos es una cuadrícula de 5×8 píxeles.
Revisa nuestro tutorial para obtener más información sobre las pantallas LCD de caracteres.
Adaptador LCD I2C
En el corazón del adaptador hay un chip expansor de E/S de 8 bits: PCF8574. Este chip convierte los datos I2C de un Arduino en los datos paralelos necesarios para una pantalla LCD.

La placa también viene con un pequeño potenciómetro para realizar ajustes precisos en el contraste de la pantalla.

Además, hay un puente en la placa que suministra energía a la luz de fondo. Para controlar la intensidad de la luz de fondo, puedes quitar el puente y aplicar voltaje externo al pin del encabezado que está marcado como ‘LED’.
Dirección I2C de LCD
Si estás utilizando varios dispositivos en el mismo bus I2C, es posible que debas configurar una dirección I2C diferente para el adaptador LCD evitando que entre en conflicto con otro dispositivo I2C.
Para ello, el adaptador dispone de tres puentes de soldadura (A0, A1 y A2) o pads de soldadura.

Cada uno de estos se utiliza para codificar la dirección. Si un puente se cortocircuita con una gota de soldadura, establece la dirección.
Un punto importante aquí es que varias empresas fabrican el mismo chip PCF8574, Texas Instruments y NXP Semiconductors, por mencionar algunas. Y la dirección I2C de su LCD depende del fabricante del chip.
Si tu LCD tiene el chip PCF8574 de Texas Instruments:
Según la hoja de datos de Texas Instruments, los tres bits de selección de dirección (A0, A1 y A2) se colocan al final del registro de dirección I2C de 7 bits.

Dado que hay 3 entradas de dirección, que pueden tomar 2 estados, ya sea ALTO/BAJO, podemos crear 8 (23) combinaciones diferentes (direcciones).
De forma predeterminada, las 3 entradas de dirección se colocan en ALTO mediante pullups integrados, lo que le da al PCF8574 una dirección I2C predeterminada de 0100111 Binario o 0x27 Hex .
Al cortocircuitar los puentes de soldadura, las entradas de dirección se ponen en BAJO. Si se cortocircuitara los tres puentes, la dirección sería 0x20. El rango de todas las direcciones posibles abarca desde 0x20 hasta 0x27. Revisa la ilustración a continuación.

Si tu LCD tiene el chip PCF8574 de NXP:
De acuerdo con la hoja de datos de NXP Semiconductors, los tres bits de selección de dirección (A0, A1 y A2) también se colocan al final del registro de dirección I2C de 7 bits. Pero los otros bits en el registro de direcciones son diferentes.

Dado que hay 3 entradas de dirección, que pueden tomar 2 estados, ya sea ALTO/BAJO, podemos crear 8 (23) combinaciones diferentes (direcciones).
De manera predeterminada, las 3 entradas de dirección se colocan en ALTO mediante pullups integrados, lo que le da al PCF8574 una dirección I2C predeterminada de 0111111 Binario o 0x3F Hex.
Al cortocircuitar los puentes de soldadura, las entradas de dirección se ponen en BAJO. Si se cortocircuitara los tres puentes, la dirección sería 0x38. El rango de todas las direcciones posibles abarca desde 0x38 hasta 0x3F. Revisa la ilustración a continuación.

Entonces, tu LCD probablemente tenga una dirección I2C predeterminada 0x27 Hex o 0x3F Hex . Sin embargo, se recomienda que averigües la dirección I2C real de la pantalla LCD antes de usarla.
Afortunadamente hay una manera fácil de hacer esto. Lo veremos más adelante en el tutorial.
Configuración de pines de la pantalla LCD I2C
Una pantalla LCD I2C tiene solo 4 pines que la conectan con el mundo exterior. Las conexiones son las siguientes:

GND es un pin de tierra. Conéctalo a tierra del Arduino.
VCC suministra energía al módulo y al LCD. Conéctalo a la salida de 5V de Arduino o a una fuente de alimentación externa de 5V.
SDA es el pin de datos I2C. Conéctalo al pin de datos I2C de Arduino.
SCL es el pin del reloj I2C. Conéctalo al pin de reloj I2C de Arduino.
Conexión de un Arduino Uno a una pantalla LCD I2C
Conectar una pantalla LCD I2C es mucho más fácil que conectar una pantalla LCD estándar. Solo necesita conectar 4 pines en lugar de 12. Comienza conectando el pin VCC a la salida de 5V en Arduino y GND a tierra.
Ahora nos quedan los pines que se utilizan para la comunicación I2C. Ten en cuenta que cada placa Arduino tiene diferentes pines I2C que deben conectarse en consecuencia. En las placas Arduino con el diseño R3, SDA (línea de datos) y SCL (línea de reloj) están en los encabezados de los pines cerca del pin AREF. También se conocen como A5 (SCL) y A4 (SDA).
Si estás utilizando una placa Arduino diferente, consulta la tabla a continuación.

El siguiente diagrama muestra cómo conectar todo.

Ajuste del contraste de la pantalla LCD
Después de cablear la pantalla LCD, deberás ajustar el contraste de la pantalla. En el módulo I2C encontrarás un potenciómetro que puedes girar con un pequeño destornillador.
Conecta el USB de Arduino para alimentar la pantalla LCD. Verás que se enciende la luz de fondo. Ahora, al girar la perilla del potenciómetro, comenzarás a ver la primera fila de rectángulos. Si eso sucede, ¡Felicidades! tu LCD está funcionando bien.

Una vez hecho esto, podemos comenzar a programar la pantalla LCD.
Instalación de la biblioteca
Para controlar una pantalla LCD I2C, primero debes instalar una biblioteca llamada LiquidCrystal_I2C. Esta biblioteca es una versión mejorada de la biblioteca LiquidCrystal que viene con el IDE de Arduino.
Para instalar la biblioteca, ve a Sketch > Incluir bibliotecas > Administrar bibliotecas… Espere a que el Administrador de bibliotecas descargue el índice de la biblioteca y actualice la lista de bibliotecas instaladas

Filtra la búsqueda escribiendo ‘liquidcrystal‘. Debería haber algunas entradas. Busca la biblioteca LiquidCrystal I2C de Frank de Brabander. Haz clic en esa entrada y luego selecciona Instalar.

Determinación de la dirección I2C
La dirección I2C de tu LCD depende del fabricante, como se mencionó anteriormente. Si tiene un chip PCF8574 de Texas Instruments, su dirección I2C predeterminada es 0x27 Hex, si tiene el chip PCF8574 de NXP Semiconductors, su dirección I2C predeterminada es 0x3F Hex .
Entonces, tu LCD probablemente tengas una dirección I2C 0x27 Hex o 0x3F Hex . Sin embargo, se recomienda que averigües la dirección I2C real de la pantalla LCD antes de usarla. Afortunadamente, hay una manera fácil de hacer esto, gracias a Nick Gammon.
Nick escribió un código de escáner I2C simple que escanea el bus I2C y devuelve la dirección de cada dispositivo que encuentra.
#include <Wire.h>
void setup() {
Serial.begin (9600);
// Leonardo: wait for serial port to connect
while (!Serial)
{
}
Serial.println ();
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
Wire.begin();
for (byte i = 8; i < 120; i++)
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
delay (1); // maybe unneeded?
} // end of good response
} // end of for loop
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
} // end of setup
void loop() {}
Carga este codigo en tu Arduino y luego abre el monitor serial. Verás la dirección I2C de tu pantalla LCD I2C.

Ten en cuenta esta dirección. La necesitarás en ejemplos posteriores.
Sketch básico de Arduino – Hola mundo
El siguiente codigo de prueba imprimirá ‘¡Hola mundo!’ en la primera línea de la pantalla LCD y ‘LCD Tutorial’ en la segunda línea.
// enter the I2C address and the dimensions of your LCD here
LiquidCrystal_I2C lcd(0x3F, 16, 2);
Pero, antes de proceder a cargar el programa, debes realizar un pequeño cambio para que funcione. Debes pasar la dirección I2C de tu LCD y las dimensiones de la pantalla al constructor de la clase LiquidCrystal_I2C. Si estás utilizando una pantalla LCD de 16 × 2 caracteres, pasa el 16 y el 2; Si estás utilizando una pantalla LCD de 20 × 4, pasa 20 y 4. ¡Entendido el punto!
Una vez que hayas terminado, continúa y pruebe el sketch
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address to 0x3F for a 16 chars and 2 line display
void setup() {
lcd.init();
lcd.clear();
lcd.backlight(); // Make sure backlight is on
// Print a message on both lines of the LCD.
lcd.setCursor(2,0); //Set cursor to character 2 on line 0
lcd.print("Hello world!");
lcd.setCursor(2,1); //Move cursor to character 2 on line 1
lcd.print("LCD Tutorial");
}
void loop() {
}
Si todo va bien, deberías ver algo como esto en la pantalla.

Explicación del código:
El Sketch comienza al incluir la biblioteca LiquidCrystal_I2C.
#include <LiquidCrystal_I2C.h>
En primer lugar, se crea un objeto de la clase LiquidCrystal_I2C. Este objeto toma tres parámetros LiquidCrystal_I2C(address, columns, rows). Aquí es donde debes ingresar la dirección que encontraste anteriormente y las dimensiones de la pantalla.
LiquidCrystal_I2C lcd(0x3F,16,2);
Una vez que hayas declarado un objeto LiquidCrystal_I2C, puedes acceder a los métodos de objeto específicos de la pantalla LCD.
En ‘configuración‘ llamamos a tres funciones. La primera función es init(). Inicializa el objeto LCD. La segunda función es clear(). Esto borra la pantalla LCD y mueve el cursor a la esquina superior izquierda. Y tercero, la función backlight() enciende la luz de fondo de la pantalla LCD.
lcd.init();
lcd.clear();
lcd.backlight();
Después de eso, establecemos la posición del cursor en la tercera columna de la primera fila llamando a la función lcd.setCursor(2, 0). La posición del cursor especifica la ubicación en la que deseas que se muestre el nuevo texto en la pantalla LCD. Se supone que la esquina superior izquierda es col=0, row=0.
lcd.setCursor(2,0);
A continuación, la cadena ‘¡Hola mundo!’ se imprime llamando a la función print().
lcd.print("Hello world!");
De manera similar, las siguientes dos líneas de código establecen la posición del cursor en la tercera columna de la segunda fila e imprimen ‘Tutorial LCD’ en la pantalla LCD. Otras funciones útiles de la biblioteca.
lcd.setCursor(2,1);
lcd.print("LCD Tutorial");
Otras funciones útiles de la librería LiquidCrystal_I2C
Hay algunas funciones útiles que puede usar con objetos LiquidCrystal_I2C. Algunos de ellos se enumeran a continuación:
- lcd.home(), se utiliza para colocar el cursor en la parte superior izquierda de la pantalla LCD sin borrar la pantalla.
- lcd.blink(), muestra un bloque parpadeante de 5×8 píxeles en la posición en la que se escribirá el siguiente carácter.
- lcd.cursor(), muestra un guión bajo (línea) en la posición en la que se escribirá el siguiente carácter.
- lcd.noBlink(), apaga el cursor LCD parpadeante.
- lcd.noCursor(), oculta el cursor LCD.
- lcd.scrollDisplayRight() La función desplaza el contenido de la pantalla un espacio hacia la derecha. Si deseas que el texto se desplace continuamente, debes usar esta función dentro de un bucle for.
- lcd.scrollDisplayLeft() La función desplaza el contenido de la pantalla un espacio hacia la izquierda. Similar a la función anterior, usa esto dentro de un ciclo for para desplazamiento continuo.
Generación de caracteres personalizados para LCD de 16×2 caracteres
Si encuentras los caracteres en la pantalla aburridos, puede crear tus propios caracteres personalizados (glifos) y símbolos para su pantalla LCD. Son extremadamente útiles cuando desea mostrar un carácter que no forma parte del conjunto de caracteres ASCII estándar.
Como se discutió anteriormente en este tutorial, un caracter se compone de una matriz de 5 × 8 píxeles, por lo que debes definir el caracter personalizado dentro de esa matriz. Puedes usar la función createChar() para definir un carácter.
Para usar createChar(), primero configura una matriz de 8 bytes. Cada byte de la matriz representa una fila de caracteres en una matriz de 5×8. Mientras que 0 y 1 en un byte indican qué píxel de la fila debe estar ENCENDIDO y cuál debe estar APAGADO.
Todos estos caracteres definidos por el usuario se almacenan en la CGRAM de la pantalla LCD.
CGROM y CGRAM
Todas las pantallas LCD basadas en el controlador Hitachi HD44780 tienen dos tipos de memoria: CGROM y CGRAM (Generador de caracteres ROM y RAM).
CGROM es una memoria no volátil y no se puede modificar, mientras que CGRAM es una memoria volátil y se puede modificar en cualquier momento.
CGROM se usa para almacenar todas las fuentes permanentes que se muestran usando códigos ASCII. Por ejemplo, si enviamos 0x41 a la pantalla LCD, la letra ‘A’ se imprimirá en la pantalla.
CGRAM es otra memoria utilizada para almacenar caracteres definidos por el usuario. Esta RAM está limitada a 64 bytes. Para una pantalla LCD de 5 × 8 píxeles, solo se pueden almacenar 8 caracteres definidos por el usuario en CGRAM. Y para LCD basado en 5 × 10 píxeles, solo se pueden almacenar 4 caracteres definidos por el usuario.
Generador de caracteres personalizados
¡Crear caracteres personalizados nunca ha sido tan fácil! Hemos creado una pequeña aplicación llamada Custom Character Generator. ¿Puedes ver la cuadrícula azul a continuación? Puedes hacer clic en cualquier píxel de 5 × 8 para establecer/borrar ese píxel en particular. Y al hacer clic, el código del caracter se genera junto a la cuadrícula. Este código se puede usar directamente en tu código de Arduino.

La imaginación es ilimitada. La única limitación es que la biblioteca LiquidCrystal solo admite ocho caracteres personalizados. Pero no te desanimes, mira el lado positivo, al menos tenemos ocho personajes.
Código de ejemplo de Arduino
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x3F for a 16 chars and 2 line display
// make some custom characters:
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
byte Bell[8] = {
0b00100,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100,
0b00000
};
byte Alien[8] = {
0b11111,
0b10101,
0b11111,
0b11111,
0b01110,
0b01010,
0b11011,
0b00000
};
byte Check[8] = {
0b00000,
0b00001,
0b00011,
0b10110,
0b11100,
0b01000,
0b00000,
0b00000
};
byte Speaker[8] = {
0b00001,
0b00011,
0b01111,
0b01111,
0b01111,
0b00011,
0b00001,
0b00000
};
byte Sound[8] = {
0b00001,
0b00011,
0b00101,
0b01001,
0b01001,
0b01011,
0b11011,
0b11000
};
byte Skull[8] = {
0b00000,
0b01110,
0b10101,
0b11011,
0b01110,
0b01110,
0b00000,
0b00000
};
byte Lock[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000
};
void setup()
{
lcd.init();
// Make sure backlight is on
lcd.backlight();
// create a new characters
lcd.createChar(0, Heart);
lcd.createChar(1, Bell);
lcd.createChar(2, Alien);
lcd.createChar(3, Check);
lcd.createChar(4, Speaker);
lcd.createChar(5, Sound);
lcd.createChar(6, Skull);
lcd.createChar(7, Lock);
// Clears the LCD screen
lcd.clear();
// Print a message to the lcd.
lcd.print("Custom Character");
}
// Print All the custom characters
void loop()
{
lcd.setCursor(0, 1);
lcd.write(0);
lcd.setCursor(2, 1);
lcd.write(1);
lcd.setCursor(4, 1);
lcd.write(2);
lcd.setCursor(6, 1);
lcd.write(3);
lcd.setCursor(8, 1);
lcd.write(4);
lcd.setCursor(10, 1);
lcd.write(5);
lcd.setCursor(12, 1);
lcd.write(6);
lcd.setCursor(14, 1);
lcd.write(7);
}
Verás el siguiente resultado en la pantalla LCD:

Explicación del código:
Una vez que se incluye la biblioteca y se crea el objeto LCD, se definen matrices de caracteres personalizadas. La matriz consta de 8 bytes, cada byte representa una fila de una matriz de LED de 5×8. En este sketch, se han creado ocho personajes personalizados.
Examinemos la matriz Heart[8] como ejemplo. Puedes ver como los bits (0s y 1s) van formando un corazón. 0 apaga el píxel y 1 enciende el píxel.
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
En setup(), se crea un caracter personalizado usando la función createChar(). Esta función toma dos parámetros. El primer parámetro es un número entre 0 y 7 para reservar uno de los 8 caracteres personalizados admitidos. El segundo es el nombre de la matriz.
lcd.createChar(0, Heart);
Luego en loop(), para mostrar el carácter personalizado, simplemente usamos la función write() y le pasamos el número del carácter que reservamos anteriormente.
lcd.setCursor(0, 1);
lcd.write(0);
Interface an I2C LCD with Arduino. Last Minute Engineers. https://lastminuteengineers.com/i2c-lcd-arduino-tutorial/