En este tutorial aprenderás a conectar tu microcontrolador con una pantalla LCD y a hacer tu primer sketch para mostrar lo que quieras en la pantalla LCD.
Utilizamos diferentes tipos de pantallas:
- Pantalla LCD sin conexión I2C
- Pantalla LCD con conexión I2C
Como bonus te muestro cómo puedes crear caracteres personalizados como un corazón en la pantalla de forma súper rápida y sencilla.
La mayoría de las veces usamos el trazador serial del IDE de Arduino para visualizar nuestras soluciones o la salida de un boceto. Es genial y le ahorra mucho tiempo al crear prototipos. Pero hay un momento en que su sistema se activará. Si, por ejemplo, solo está enviando datos del sensor a una base de datos en una Raspberry Pi, puede ver la salida desde su PC de forma remota conectándose a la base de datos. Pero hay casos de uso como una estación meteorológica interior, en los que desea ver la salida como la temperatura actual directamente y no cuando está en su PC.
Que las pantallas son el camino a seguir. Hay diferentes tipos de pantallas, como la pantalla LED de 7 segmentos, la pantalla de 7 segmentos de 4 dígitos, la pantalla de matriz de puntos de 8 × 8, la pantalla OLED o la versión más simple y la pantalla de cristal líquido (LCD) más barata.
La mayoría de las pantallas LCD tienen 2 líneas con 16 caracteres por línea o 4 líneas con 20 caracteres por línea. Hay una pantalla LCD con y sin módulo I2C. Sugiero encarecidamente módulos con I2C porque la conexión a la placa es muy simple y solo se usan 2 pines en lugar de 6. Pero vamos a cubrir la pantalla LCD con y sin módulo I2C en este artículo.

Especificaciones de la pantalla LCD
La pantalla LCD tiene un voltaje de funcionamiento de 4,7 V a 5,3 V con un consumo de corriente de 1 mA sin luz de fondo y 120 mA con luz de fondo completa. Hay versiones con retroiluminación verde y azul. Cada carácter en la pantalla está construido por un cuadro de 5 × 8 píxeles y, por lo tanto, es capaz de mostrar caracteres generados personalizados. Debido a que cada carácter está construido por (5 × 8 = 40) 40 píxeles, una pantalla LCD de 16 × 2 tendrá 16x2x40 = 1280 píxeles en total. El módulo LCD puede funcionar en modo de 8 y 4 bits. La diferencia entre el modo de 4 y 8 bits es la siguiente:
- En el modo de 8 bits, solo se necesita una señal de pulso para mostrar un carácter en la pantalla LCD en lugar de dos señales de pulso.
- El modo de 4 bits utiliza solo cuatro pines de datos en comparación con los 8 pines de datos en el modo de 8 bits.
- Dado que se requieren dos señales de pulso (encender) para mostrar un solo carácter, la latencia del modo de 4 bits es mayor en comparación con el modo de 8 bits.
Pantalla LCD sin conexión I2C
Si usamos la versión LCD sin conexión I2C, necesitamos agregar el potenciómetro manualmente para controlar el contraste de la pantalla. La siguiente imagen muestra la distribución de pines de la pantalla LCD.
También agregué una tabla sobre cómo conectar la pantalla LCD con el Arduino Uno y el NodeMCU con una descripción del pin LCD. Para que le resulte lo más fácil posible conectar su microcontrolador a la pantalla, encontrará la imagen de conexión fritzing correspondiente para Arduino Uno y NodeMCU en este capítulo.

| Pin NR | Etiqueta del pin LCD-016M002B | Conexión de Arduino Uno | Conexión de ESP8266 NodeMCU | Descripción |
|---|---|---|---|---|
| 1 | GND | GND | GND | Pin de tierra para conectar al pin GND del Arduino. |
| 2 | VCC | 3V3 / 5V | 3V3 / VIN | Tensión de alimentación de 5V (4,7V - 5,3V). También para una prueba 3V hace el trabajo. |
| 3 | VEE | Potenciómetro | Potenciómetro | Ajusta el contraste de la pantalla Si este pin está conectado a tierra, se obtiene el máximo contraste. Conectaremos el pin VEE a la salida del potenciómetro para ajustar el contraste cambiando la resistencia del mismo. |
| 4 | RS | D12 | D2 | Registro de comando de selección a bajo cuando estamos enviando comandos a la pantalla LCD como poner el cursor en un lugar específico, borrar la pantalla o apagar la pantalla. |
| 5 | R/W | GND | GND | Y selecciona el registro de datos cuando RS se pone en alto para enviar datos o caracteres a la LCD. |
| 6 | Habilitar | D11 | D3 | Selección de lectura o escritura (R/W). Se conecta permanentemente a GND (0 V) para operar en modo de escritura hacia la pantalla. |
| 7 | Pin de datos 0 (d0) | Pin de habilitación (Enable / E). Conmuta de nivel alto a bajo para registrar los datos o comandos presentes en el bus de datos en el controlador interno. | ||
| 8 | Pin de datos 1 (d1) | Los pines de datos 0 a 7 forman una línea de datos de 8 bits. Los pines de datos se conectan a los pines de E/S digitales del microcontrolador para enviar datos de 8 bits. Estos LCD también pueden funcionar en modo de 4 bits, en cuyo caso los pines de datos 4, 5, 6 y 7 quedarán libres. | ||
| 9 | Pin de datos 2 (d2) | |||
| 10 | Pin de datos 3 (d3) | |||
| 11 | Pin de datos 4 (d4) | D5 | D6 | |
| 12 | Pin de datos 5 (d5) | D4 | D7 | |
| 13 | Pin de datos 6 (d6) | D3 | D8 | |
| 14 | Pin de datos 7 (d7) | D2 | RX | |
| 15 | Positivo del LED | 3V3 / 5V | 3V3 / VIN | Terminal positivo del pin del LED de luz de fondo |
| 16 | LED negativo | GND | GND | Terminal negativo del pin del LED de luz de fondo |
Conexión de la pantalla LCD al Arduino Uno sin I2C
La siguiente imagen muestra las conexiones entre la pantalla LCD y el Arduino Uno.

Conexión de la pantalla LCD al ESP8266 NodeMCU sin I2C
La siguiente imagen muestra las conexiones entre la pantalla LCD y el ESP8266 NodeMCU.

Por supuesto, queremos probar la conexión entre el microcontrolador y la pantalla LCD. Por lo tanto, encontrará un boceto de ejemplo en el IDE de Arduino. La siguiente sección muestra el código del boceto y una imagen del ejemplo en ejecución, más o menos porque es difícil hacer una imagen de la pantalla ;-). El ejemplo muestra «¡hola, mundo!» en la primera línea de la pantalla y cuenta cada segundo en la segunda línea. Estamos usando la conexión que describimos anteriormente para este ejemplo.
// include the library code:
#include "LiquidCrystal_I2C.h"
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int RS = D2, EN = D3, d4 = D5, d5 = D6, d6 = D7, d7 = D8;
// if you use the NodeMCU 12E the suggested pins are
// const int RS = 4, EN = 0, d4 = 12, d5 = 13, d6 = 15, d7 = 3;
LiquidCrystal lcd(RS, EN, d4, d5, d6, d7);
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);
}


Parece muy complicado imprimir datos en la pantalla LCD. Pero no se preocupe, porque en la mayoría de los casos, si comienza a ensuciarse, hay una biblioteca para correr la voz por nosotros. Este también es el caso de la pantalla LCD sin una conexión I2C.
Por lo tanto, el siguiente paso es instalar la biblioteca “LiquidCrystal”. Aquí encontrará un artículo sobre cómo instalar una biblioteca externa a través del IDE de Arduino. Una vez instalada la biblioteca, puede incluirla a través de: #include .
Pantalla LCD con conexión I2C
El uso de una mochila de adaptación I2C basada en el expansor de 8 bits PCF8574 / PCF8574T simplifica el conexionado al reducir de 16 pines (o 6 en modo paralelo de 4 bits) a solo 4 conductores: alimentación (VCC), masa (GND) y el bus de dos hilos (SDA y SCL). Para establecer comunicación serie con el controlador HD44780, es indispensable conocer la dirección I2C hexadecimal del integrado y respetar las tolerancias de tensión.
- Alimentación del display (VCC 5 V): la matriz de cristal líquido del display HD44780 necesita entre 4,7 V y 5,3 V para polarizar correctamente las moléculas nemáticas y ofrecer contraste legible. Alimentar el módulo a 3,3 V provoca que los caracteres aparezcan casi invisibles incluso con el potenciómetro de contraste al máximo. Conecta siempre VCC a la línea de 5 V (o VIN del puerto USB).
- Resistencias pull-up en el bus I2C hacia ESP32 / ESP8266: la inmensa mayoría de mochilas PCF8574 comerciales incorporan dos resistencias pull-up integradas (típicamente de 4,7 kΩ o 10 kΩ) conectadas directamente a su línea de alimentación VCC (5 V). En microcontroladores de 3,3 V como el ESP32 o ESP8266, estas resistencias fuerzan las líneas SDA y SCL a 5 V cuando el bus está en reposo. Para garantizar inmunidad y evitar fatiga térmica en los pines GPIO del microcontrolador, se recomienda interponer un conversor de nivel lógico bidireccional (tipo BSS138) o desoldar las resistencias pull-up de la mochila y conectar resistencias externas a la línea de 3,3 V.
- Regulación del potenciómetro de contraste (10 kΩ): si la pantalla enciende la retroiluminación azul/verde pero no muestra ningún texto o muestra una sola fila de bloques cuadrados negros/blancos, gira despacio el tornillo del potenciómetro azul situado en el reverso de la mochila hasta calibrar el fondo respecto a los píxeles activos.
Conexión I2C: Arduino Uno, ESP8266 y ESP32
La siguiente tabla resume el esquema de conexionado físico estandarizado para enlazar la pantalla LCD 16×2 o 20×4 mediante I2C con las plataformas de desarrollo más habituales:
| Pin Mochila LCD I2C | Arduino Uno / Nano (5 V) | ESP8266 NodeMCU (3,3 V) | ESP32 DevKit (3,3 V) | Función y Parámetros Eléctricos |
|---|---|---|---|---|
| GND | GND | GND | GND | Masa común del sistema de alimentación y bus. |
| VCC | 5V | VIN (5 V de USB) | VIN / 5V (USB) | Alimentación del display (mínimo 4,7 V requerido para contraste). |
| SDA (Serial Data) | A4 (o pin SDA dedicado) | D2 (GPIO 4) | GPIO 21 (SDA por defecto) | Línea de datos serie bidireccional open-drain del bus I2C. |
| SCL (Serial Clock) | A5 (o pin SCL dedicado) | D1 (GPIO 5) | GPIO 22 (SCL por defecto) | Línea de reloj de sincronismo del bus I2C (100 kHz estándar). |
Detección de la dirección I2C con escáner de bus
Las mochilas PCF8574 suelen emplear dos direcciones base según el fabricante del circuito integrado:
- 0x27: chip estándar PCF8574T (NXP / Texas Instruments).
- 0x3F: variante PCF8574AT.
Si la librería no detecta la pantalla con 0x27, carga este sketch escáner en tu placa (válido para Arduino Uno, Nano, ESP8266 y ESP32) para identificar en la consola serie a 115200 baudios la dirección exacta de respuesta ACK:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
while (!Serial);
Serial.println("\n--- Escaner de Bus I2C (ElOsciloscopio) ---");
}
void loop() {
byte error, address;
int nDevices = 0;
Serial.println("Escaneando bus I2C...");
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("Dispositivo encontrado en direccion 0x");
if (address < 16) Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
} else if (error == 4) {
Serial.print("Error desconocido en direccion 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No se encontraron dispositivos I2C. Verifica cables SDA/SCL y alimentacion.\n");
} else {
Serial.println("Escaneo completado.\n");
}
delay(5000);
}
Para usar la pantalla LCD I2C, necesitamos instalar la biblioteca requerida “LiquidCrystal_I2C” de Frank de Brabander. Aquí encontrará un artículo sobre cómo instalar una biblioteca externa a través del IDE de Arduino. Una vez instalada la biblioteca, puede incluirla a través de: #include LiquidCrystal_I2C.h>.
Este breve ejemplo le muestra cómo utilizar la biblioteca para controlar la pantalla LCD.
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
// create an LCD object (Hex address, # characters, # rows)
// my LCD display in on Hex address 27 and is a 20x4 version
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("This is");
lcd.setCursor(1, 1);
lcd.print("ElOsciloscopio");
}
void loop(){}

Funciones de la biblioteca LiquidCrystal y LiquidCrystal_I2C
La biblioteca LiquidCrystal tiene 20 funciones integradas que resultan útiles cuando desea trabajar con la pantalla LCD. En la siguiente parte de este artículo, repasaremos todas las funciones con una descripción junto con un boceto de muestra y un video corto para que veas lo que hace la función.
| LiquidCrystal | LiquidCrystal_I2C | Función LiquidCrystal library | Descripción |
|---|---|---|---|
| x | x | LiquidCrystal() LiquidCrystal_I2C() | Esta función crea una variable del tipo LiquidCrystal. Los parámetros de la función definen la conexión entre la pantalla LCD y el Arduino. Puedes utilizar cualquiera de los pines digitales del Arduino para controlar la pantalla. El orden de los parámetros es el siguiente LiquidCrystal(RS, R/W, Enable, d0, d1, d2, d3, d4, d5, d6, d7) Si R/W está conectado a GND no se utiliza el parámetro en la función: LiquidCrystal(RS, Enable, d0, d1, d2, d3, d4, d5, d6, d7) Si se quiere operar en el modo de 4 bits la función cambia: LiquidCrystal(RS, R/W, Enable, d4, d5, d6, d7) Si se utiliza una pantalla LCD con la conexión I2C no se definen los pines conectados porque no se conecta a pines individuales pero se define la dirección HEX y el tamaño de la pantalla: LiquidCrystal_I2C lcd(0x27, 20, 4); |
| x | lcd.begin() | Hay que llamar a la función lcd.begin(cols, rows) para definir el tipo de pantalla LCD con el número de columnas y filas. La función tiene que ser llamada en la parte void setup() de tu sketch. Para la pantalla de 16×2 se escribe lcd.begin(16,2) y para la de 20×4 lcd.begin(20,4). El ejemplo siguiente define la pantalla como de 20×4 y muestra un texto. | |
| x | lcd.init() | Inicialización de la pantalla I2C. | |
| x | x | lcd.clear() | La función clear borra cualquier dato de la pantalla LCD y coloca el cursor en la esquina superior izquierda. Puedes colocar esta función en la función de configuración de tu sketch para asegurarte de que no aparezca nada en la pantalla cuando inicies tu programa. |
| x | x | lcd.home() | Esta función coloca el cursor en la esquina superior izquierda de la pantalla. |
| x | x | lcd.setCursor() | Si quieres escribir texto en tu pantalla LCD, tienes que definir la posición inicial del carácter que quieres imprimir en la LCD con la función lcd.setCursor(col, row). Aunque tienes que definir la fila en la que se debe mostrar el carácter. |
| x | x | lcd.write() | Utiliza la función write para mostrar los valores, por ejemplo un valor del sensor. |
| x | x | lcd.print() | Esta función muestra diferentes tipos de datos: char, byte, int, long o string. Una cadena debe ir entre comillas («»). Los números pueden imprimirse sin las comillas. Los números también se pueden imprimir en diferentes sistemas numéricos lcd.print(data, BASE) con BIN para binario (base 2), DEC para decimal (base 10), OCT para octal (base 8), HEX para hexadecimal (base 16). |
| x | lcd.println() | Esta función muestra también diferentes tipos de datos: char, byte, int, long, o string como la función lcd.print() pero lcd.println() imprime siempre una nueva línea al flujo de salida. | |
| x | x | lcd.cursor() / lcd.noCursor() | Muestra u oculta el cursor de la pantalla LCD como un guión bajo (línea) en la posición en la que se escribirá el siguiente carácter. |
| x | x | lcd.blink() / lcd.noBlink() | La función blink y noBlink muestra u oculta un cursor de estilo bloque que parpadea al encenderse y apagarse. |
| x | x | lcd.display() / lcd.noDisplay() | Esta función enciende y apaga cualquier texto o cursor de la pantalla pero no borra la información de la memoria. Por lo tanto, es posible encender y apagar la pantalla con esta función. |
| x | x | lcd.scrollDisplayLeft() / lcd.scrollDisplayRight() | Esta función desplaza el contenido de la pantalla (texto y cursor) una posición a la izquierda o a la derecha. Después de 40 espacios la función volverá al primer carácter. Con esta función en la parte del bucle de tu sketch puedes construir una función de desplazamiento de texto. Texto de desplazamiento si desea imprimir más de 16 o 20 caracteres en una línea, que la función de texto de desplazamiento es muy útil. Primero se imprime la subcadena con el máximo de caracteres por línea, desplazando la columna de inicio de la derecha a la izquierda en la pantalla LCD. Luego se deja el primer carácter y se imprime el siguiente a la subcadena. Este proceso se repite hasta que se muestra la cadena completa en la pantalla. |
| x | x | lcd.autoscroll() / lcd.noAutoscroll() | La función autoscroll activa o desactiva la funcionalidad de que cada carácter se desplace una posición. La función se puede utilizar como la función scrollDisplayLeft / scrollDisplayRight. |
| x | x | lcd. leftToRight() / lcd.rightToLeft() | Las funciones leftToRight y rightToLeft cambian la dirección del texto escrito en la pantalla LCD. El modo por defecto es de izquierda a derecha, que no es necesario definir al inicio del sketch. |
| x | x | lcd.createChar() | Existe la posibilidad de crear caracteres personalizados con la función createChar. La forma de crear los caracteres personalizados se describe en el siguiente capítulo de este artículo, así como un ejemplo. |
| x | lcd.backlight() | La función backlight es útil si no quieres apagar toda la pantalla (ver lcd.display()) y por tanto sólo encender y apagar la luz de fondo. Pero antes de poder utilizar esta función tienes que definir el pin de la luz de fondo con la función setBacklightPin(pin, polaridad). El siguiente ejemplo muestra un sketch para encender y apagar la luz de fondo. lcd.setBacklightPin(7, NEGATIVO); lcd.setBacklight(1); | |
| x | lcd.moveCursorLeft() / lcd.moveCursorRight() | Esta función permite mover el cursor a la izquierda y a la derecha. Para que esta función sea útil hay que combinarla con lcd.setCursor() porque si no no hay cursor para mover a la izquierda o a la derecha. Para nuestro ejemplo también utilizamos la función lcd.cursor() para hacer visible el cursor. | |
| x | lcd.on() / lcd.off() | Esta función enciende y apaga la pantalla LCD. Encenderá/apagará el controlador del LCD y la luz de fondo. Este método tiene el mismo efecto que llamar a display/noDisplay y a backlight/noBacklight. |
Ejemplo de pantalla parpadeante, de cursor y de desplazamiento
Para mostrarle algunos ejemplos básicos de las bibliotecas LiquidCrystal y LiquidCrystal_I2C, puede copiar el siguiente ejemplo que muestra tres funciones diferentes de la biblioteca:
- Muestre u oculte un campo de carácter intermitente para mostrarle al usuario su aplicación que, por ejemplo, se necesita una entrada o se está cargando una aplicación.
- Muestre u oculte un cursor útil («_») al crear un menú como una barra de navegación de izquierda a derecha o de arriba a abajo, dependiendo de una barra de menú horizontal o vertical. Si está interesado en crear un menú básico con el microcontrolador ESP o Arduino en combinación con la pantalla, encontrará un tutorial aquí.
- Mueva todos los caracteres a la derecha para una visualización de desplazamiento.
El siguiente código le muestra el programa Arduino para usar las tres funciones de la pantalla LCD en la biblioteca divididas en tres funciones separadas. El video después del programa también muestra las funciones en acción.
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup()
{
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop(){
show_blink();
show_cursor();
scroll_display();
}
void show_blink(){
lcd.clear();
lcd.setCursor(0,2);
lcd.print("Blink is on");
lcd.setCursor(0,0);
lcd.blink();
delay(5000);
lcd.setCursor(0,2);
lcd.print("Blink is off");
lcd.setCursor(0,0);
lcd.noBlink();
delay(5000);
}
void show_cursor(){
lcd.clear();
lcd.setCursor(0,2);
lcd.print("Cursor is on");
lcd.setCursor(0,0);
lcd.cursor();
delay(5000);
lcd.setCursor(0,2);
lcd.print("Cursor is off");
lcd.setCursor(0,0);
lcd.noCursor();
delay(5000);
}
void scroll_display(){
lcd.clear();
lcd.setCursor(0,2);
lcd.print("Scroll display");
lcd.scrollDisplayRight();
delay(1000);
lcd.scrollDisplayRight();
delay(1000);
lcd.scrollDisplayRight();
delay(1000);
lcd.scrollDisplayRight();
delay(3000);
}
¿Cómo visualizo los caracteres generados personalizados?
Crear personajes personalizados es muy fácil si usa las bibliotecas mencionadas anteriormente. Tanto LiquidCrystal como la biblioteca LiquidCrystal_I2C tienen la función “lcd.createChar ()” para crear un carácter personalizado a partir de los 5 × 8 píxeles de un personaje. Para diseñar sus propios personajes, debe crear una matriz binaria de su personaje personalizado a partir de un generador de caracteres LCD o mapearlo usted mismo. Este código crea un hombre que se retuerce.
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
// Set the LCD address to 0x27 in PCF8574 by NXP and Set to 0x3F in PCF8574A by Ti
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte customChar1[] = {
B01110,
B01110,
B00100,
B11111,
B00100,
B01110,
B01010,
B01010
};
byte customChar2[] = {
B01110,
B01110,
B10101,
B01110,
B00100,
B00100,
B01010,
B10001
};
void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
lcd.createChar(0, customChar1);
lcd.home();
lcd.write(0);
delay(1000);
lcd.createChar(0, customChar2);
lcd.home();
lcd.write(0);
delay(1000);
}
Puede utilizar la siguiente herramienta para crear caracteres generados personalizados de forma fácil y rápida: http://omerk.github.io/lcdchargen/
Códigos de control importantes para la pantalla LCD
En la sección de asignación de pines de la pantalla LCD sin I2C, vimos que si configuramos el pin RS en cómo, podemos enviar comandos a la pantalla LCD. Estos comandos se envían a través de los pines de datos y se representan en la siguiente tabla como código HEX.
| N.º | Código hexadecimal | Comando a registro de instrucción LCD |
|---|---|---|
| 1 | 1 | Borrar pantalla |
| 2 | 2 | Retorno del cursor a origen (Home) |
| 3 | 4 | Descender el cursor (desplazar el cursor a la izquierda) |
| 4 | 6 | Cursor de aumento (desplazar el cursor a la derecha) |
| 5 | 5 | Desplazar la pantalla a la derecha |
| 6 | 7 | Cambiar la visualización a la izquierda |
| 7 | 8 | Pantalla apagada, cursor apagado |
| 8 | 0A | Pantalla desactivada, cursor activado |
| 9 | 0C | Pantalla activada, cursor desactivado |
| 10 | 0E | Pantalla encendida, cursor parpadeando |
| 11 | 0F | Pantalla encendida, cursor parpadeando |
| 12 | 10 | Cambiar la posición del cursor a la izquierda |
| 13 | 14 | Cambiar la posición del cursor a la derecha |
| 14 | 18 | Desplazar toda la pantalla hacia la izquierda |
| 15 | 1C | Desplazar toda la pantalla hacia la derecha |
| 16 | 80 | Forzar el cursor al principio ( 1ª línea) |
| 17 | C0 | Forzar cursor al principio ( 2ª línea) |
| 18 | 38 | 2 líneas y matriz 5×7 |
Conclusión
Espero que hayas aprendido mucho de este artículo. No dude en probar los bocetos de muestra con su microcontrolador. ¿Tiene preguntas sobre este artículo? Utilice la sección de comentarios a continuación y responderé su pregunta.
Cómo verificar y depurar esta señal en el laboratorio con un osciloscopio
Si tu pantalla LCD muestra únicamente una fila de bloques sólidos sin texto, revisa primero el potenciómetro de contraste en el pin V0 (debe situarse entre 0,4 V y 0,9 V respecto a GND). Si utilizas el adaptador serie I2C PCF8574, conecta dos canales del osciloscopio a SDA y SCL para comprobar si el módulo responde con un bit ACK (nivel bajo en el noveno pulso de reloj) a la dirección 0x27 o 0x3F.
¿Buscas un instrumento para tu banco de trabajo? Consulta nuestra guía técnica: Cómo elegir un osciloscopio para proyectos con Arduino y ESP32 o compara los mejores osciloscopios digitales y osciloscopios USB para PC.
Diagnóstico y decodificación del bus I2C en la pantalla LCD con osciloscopio
- Evita bucles de masa destructivos a tierra (PE): las pinzas de cocodrilo de tierra de las sondas pasivas estándar de osciloscopio están conectadas internamente a la toma de tierra de protección (PE) del edificio. Si alimentas el microcontrolador o la pantalla mediante el puerto USB de un PC de sobremesa conectado a la red eléctrica y conectas la pinza de masa a un pin erróneo o a una masa con distinta referencia de potencial, se provocará un cortocircuito inmediato a través del blindaje BNC que destruirá las pistas de la placa o el front-end del osciloscopio. Conecta la pinza exclusivamente al pin GND y verifica la equipotencialidad antes de medir.
- Uso obligatorio del resorte de masa corto (Ground Spring) para medir flancos I2C: el cable de masa flexible largo de la sonda (~10 a 15 cm) introduce una inductancia parásita superior a 100 nH que resuena con la capacitancia de entrada (~15 pF), distorsionando los flancos de subida del reloj SCL y generando sobreoscilaciones (ringing) falsas en pantalla. Para verificar tiempos de subida reales a 100 kHz o 400 kHz (Fast-mode) y evaluar la idoneidad de las resistencias pull-up, retira el capuchón de gancho y utiliza el resorte de masa corto apoyado directamente sobre el plano de GND más próximo.
Cuando un display LCD 16×2 o 20×4 I2C no muestra caracteres o la comunicación se bloquea periódicamente, un multímetro digital resulta insuficiente porque solo mide el valor medio de tensión continua en las líneas. La inspección con un osciloscopio digital con decodificación de protocolos serie por hardware permite diagnosticar en menos de dos minutos el origen exacto del fallo técnico:
- Configuración de canales y disparo (Trigger): conecta la sonda del Canal 1 a la señal SCL (Reloj) y la sonda del Canal 2 a la señal SDA (Datos). Ambas sondas deben configurarse en atenuación 10X para no cargar la línea capacitivamente (la capacidad de una sonda 1X de ~100 pF deforma los flancos del bus I2C). Ajusta el acoplamiento en DC, la escala vertical en 1 V/div o 2 V/div y el disparo en flanco de bajada de SCL o directamente en condición de Trigger I2C: Start Condition.
- Comprobación del tiempo de subida (tr) y resistencias pull-up: al tratarse de un bus de drenador abierto (open-drain), el nivel alto se genera exclusivamente por la corriente suministrada por las resistencias pull-up. Si las resistencias son de valor excesivo (por ejemplo 10 kΩ o cables de conexión largos que añaden más de 200 pF de capacidad parásita), el flanco de subida adopta una curva exponencial lenta que impide alcanzar la tensión mínima de nivel alto VIH (3,5 V en PCF8574 alimentado a 5 V) antes del siguiente pulso de reloj. Con el osciloscopio se verifica que el tiempo de subida se mantenga inferior a 1.000 ns en modo estándar (100 kHz).
- Verificación del bit de reconocimiento (ACK / NACK): en el protocolo I2C, cada byte transmitido consta de 8 bits de datos seguidos por un noveno ciclo de reloj donde el emisor libera la línea SDA. Durante este noveno ciclo, el integrado PCF8574 debe forzar activamente SDA a nivel bajo (ACK = 0 V) para confirmar la recepción. Si en la pantalla del osciloscopio observas que SDA permanece a 5 V durante el noveno pulso de SCL (NACK), el chip no está reconociendo la dirección enviada (error entre
0x27y0x3F), el integrado carece de alimentación VCC, o el pin de direccionamiento A0-A2 está en flotación. - Decodificación de tramas de inicialización HD44780: activando la función de decodificación en pantalla (menú Decode > I2C), el osciloscopio traduce los niveles analógicos a bytes legibles en hexadecimal. Podrás comprobar cómo el microcontrolador envía la secuencia de configuración del bus de 4 bits (nibbles altos y bajos alternados con el pin de habilitación E): comandos
0x33,0x32, modo función0x28(2 líneas, caracteres 5×8) y control de display0x0C.
A continuación se comparan cuatro osciloscopios recomendados para análisis de buses digitales serie (I2C, SPI y UART) en bancos de desarrollo con Arduino y ESP32:
| Modelo | Ancho de Banda | Canales | Muestreo | Profundidad Memoria | Decodificación Serie I2C | Uso Recomendado en Banco |
|---|---|---|---|---|---|---|
| Rigol DS1054Z | 50 MHz (ampliable 100 MHz) | 4 Canales | 1 GSa/s | 24 Mpts | Hardware integrada (I2C, SPI, UART, RS232) | Osciloscopio de referencia para laboratorio maker, Arduino y depuración simultánea de buses serie de 4 canales. |
| Siglent SDS1104X-U | 100 MHz | 4 Canales | 1 GSa/s | 14 Mpts | Hardware estándar incluida (I2C, SPI, UART, CAN, LIN) | Excelente velocidad de captura (400.000 wfm/s) para cazar glitches transitorios en líneas SDA y rebotes inductivos. |
| FNIRSI 1014D | 100 MHz (ancho efectivo ~30 MHz) | 2 Canales | 1 GSa/s | 240 kpts | Sin decodificación por hardware (solo traza analógica) | Visualización analógica económica de reloj y flancos; requiere conteo manual de bits en pantalla. |
| Hantek 2D72 | 70 MHz | 2 Canales + Multímetro | 250 MSa/s | 6 kpts | Sin decodificación de bus | Herramienta portátil de campo con batería integrada para verificar presencia de reloj y nivel de alimentación sobre el terreno. |
Especificaciones técnicas contrastadas con las hojas de datos oficiales de Rigol Technologies, Siglent Technologies y Hantek Instruments. Enlaces de consulta técnica bajo directrices de afiliación transparente.
Preguntas frecuentes cuando la pantalla LCD 16×2 no muestra texto
¿Por qué mi pantalla LCD enciende la luz de fondo pero solo muestra una fila de rectángulos blancos?
Cuando la primera línea muestra 16 bloques sólidos y la segunda está vacía, significa que el controlador HD44780 tiene alimentación pero no ha recibido la secuencia de inicialización o el contraste está saturado. Primero gira suavemente el potenciómetro de contraste (V0); si los bloques persisten, en modo paralelo verifica que el pin 5 (RW) esté conectado a GND, y en modo I2C comprueba con un I2C Scanner si tu chip es un PCF8574T (dirección 0x27) o un PCF8574AT (dirección 0x3F).
¿Cómo conectar una pantalla LCD de 5 V a un ESP8266 o ESP32 que funcionan a 3,3 V?
La matriz de cristal líquido del LCD clásico de 5 V necesita al menos 4,5 V en su pin VCC para lograr buen contraste visual. Conecta el pin VCC del módulo I2C al pin VIN / VBUS (5 V del USB) del ESP32/NodeMCU y conecta SDA y SCL a los pines correspondientes (o usa un conversor de nivel lógico bidireccional si el módulo lleva resistencias pull-up a 5 V).
¿Cuáles son los pines I2C por defecto para conectar la pantalla LCD al ESP32?
En el módulo ESP32 DevKit clásico (de 30 o 38 pines), las líneas de hardware del puerto I2C maestro predeterminado corresponden a GPIO 21 (SDA) y GPIO 22 (SCL). Si utilizas el entorno Arduino con la librería estándar Wire.h y LiquidCrystal_I2C, no necesitas reasignar pines: la llamada a Wire.begin(); o lcd.init(); inicializa automáticamente la comunicación por estos dos terminales tras conectar VCC a la toma de 5 V (VIN) y GND a masa común.
perfecto no lo eh dominado pero en 2 horas pude programar el display
le agrdezco