Ejercicio 01 — Mostrar texto fijo en la primera línea de un LCD 1602 por I2C y un…
Dificultad: verde · Módulo 08 (Pantallas)
Enunciado
Mostrar texto fijo en la primera línea de un LCD 1602 por I2C y un contador que sube cada segundo en la segunda línea.
Montaje (Arduino UNO)
LCD 1602 con módulo I2C → SDA=A4, SCL=A5, VCC=5V, GND=GND Librería: ‘LiquidCrystal I2C’ (instalar desde el gestor de librerías)
Cómo se resuelve
El primer contacto con una pantalla, y con el bus I2C por debajo. El montaje son cuatro cables: SDA del LCD al pin A4 del UNO, SCL al A5, VCC a 5V y GND a GND. Esos dos pines de señal no se eligen: en el Arduino UNO el I2C está cableado por hardware a A4 y A5.
El programa empieza incluyendo dos librerías. Wire.h es la del bus I2C y viene con el IDE; no la vas a llamar directamente en este ejercicio, pero es la que hace el trabajo por debajo. LiquidCrystal_I2C.h hay que instalarla desde el gestor de librerías del IDE, con el nombre exacto LiquidCrystal I2C, y es la que traduce “escribe esta letra aquí” a la conversación concreta que entiende el chip PCF8574 del backpack.
La línea clave del sketch es la creación del objeto:
LiquidCrystal_I2C lcd(0x27, 16, 2);Esos tres números son toda la descripción del hardware. 0x27 es la dirección I2C del módulo, escrita en hexadecimal; es la más común, pero muchos clones vienen con 0x3F, y si la tuya es de esas la pantalla se quedará en blanco sin dar ningún error de compilación. Cuando eso pase, el ejercicio 03 te dice cuál es la buena. Los otros dos números, 16 y 2, son las dimensiones en caracteres: 16 columnas por 2 filas. La librería los necesita para saber dónde acaba una línea y empieza la siguiente.
Antes de setup() se declara int contador = 0; fuera de las funciones. Tiene que ser así: si estuviera dentro de loop(), se crearía de nuevo valiendo cero en cada vuelta y nunca subiría de 0. Al declararla fuera, la variable vive durante toda la ejecución del programa y conserva su valor entre pasadas.
En setup() van las cuatro cosas que se hacen una sola vez. lcd.init() arranca la conversación con la pantalla por I2C. lcd.backlight() enciende la retroiluminación, y merece un aviso: sin esa línea el programa funciona igual de bien, los caracteres están escritos en el cristal, pero sin luz de fondo no se lee nada y parece que la pantalla está muerta. Después, lcd.setCursor(0, 0) coloca el cursor en la columna 0 de la fila 0 (el orden de los argumentos es columna primero, fila después, que es al revés de lo que mucha gente espera) y lcd.print("Curso Arduino") escribe el texto fijo. Está en setup() a propósito: ese título no cambia nunca, así que no hay ninguna razón para reescribirlo mil veces.
En loop() está la parte que sí cambia. lcd.setCursor(0, 1) baja a la segunda fila, y los tres print seguidos van dejando en pantalla la etiqueta "Contador: ", el valor de la variable y tres espacios. Esos tres print consecutivos funcionan porque el LCD tiene un cursor que avanza solo: cada print continúa donde terminó el anterior.
Los tres espacios del final son la parte no evidente del ejercicio. Un LCD de caracteres no se borra solo: lo que escribes se queda en su sitio hasta que algo lo sobrescriba. Si el contador va de 9 a 10, al escribir 10 sobre el 9 queda 10, correcto; pero el problema es el caso contrario, o cualquier situación en la que el número pase de más dígitos a menos, porque el dígito viejo se quedaría colgando y leerías un número que no existe. Imprimir espacios detrás es la forma barata de tapar lo que sobra sin llamar a lcd.clear(), que borraría la pantalla entera (incluido el título de la primera fila) y produciría un parpadeo desagradable en cada vuelta.
Al final, contador = contador + 1; y delay(1000). Como el delay es de 1000 milisegundos, el contador sube aproximadamente una unidad por segundo. Aproximadamente y no exactamente: al segundo hay que sumarle lo que tardan los print en viajar por el bus I2C, así que a la larga se retrasa un poco. Para un contador de demostración da igual; si necesitaras tiempo real usarías un reloj RTC, que casualmente también es un dispositivo I2C que se conecta a estos mismos dos cables.
Un detalle que merece la pena que observes si dejas el montaje corriendo: la etiqueta "Contador: " ocupa 10 de las 16 columnas, y quedan 6 para el número más los tres espacios. Mientras el contador tenga tres cifras o menos, todo cabe justo. Cuando llegue a 1000, unos diecisiete minutos después de arrancar, la línea se desborda. Es un buen recordatorio de que en una pantalla de tamaño fijo el formato de lo que muestras es parte del diseño, no un detalle.
Para practicar — cópialo y complétalo
Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.
/*
* Curso de Arduino — Módulo 08: Pantallas (LCD/OLED, I2C)
* Ejercicio 01 — PRÁCTICA (rellena los TODO)
* Enunciado: Mostrar texto fijo en la primera línea de un LCD 1602 por I2C
* y un contador que sube cada segundo en la segunda línea.
* Dificultad: verde
* Placa: Arduino UNO Montaje: LCD 1602 con módulo I2C -> SDA=A4, SCL=A5, VCC=5V, GND=GND
* Librería: 'LiquidCrystal I2C' (instalar desde el gestor de librerías)
* Correr: Arduino IDE / Wokwi (wokwi/ej01) / arduino-cli (ver README)
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// TODO: crea el objeto lcd con dirección 0x27, 16 columnas y 2 filas
// -> LiquidCrystal_I2C lcd(0x27, 16, 2);
int contador = 0;
void setup() {
// TODO: arranca el LCD -> lcd.init();
// TODO: enciende la retroiluminación -> lcd.backlight();
// TODO: coloca el cursor en (0, 0) -> lcd.setCursor(0, 0);
// TODO: imprime un texto fijo -> lcd.print("Curso Arduino");
}
void loop() {
// TODO: coloca el cursor en la segunda línea -> lcd.setCursor(0, 1);
// TODO: imprime "Contador: " y luego el valor de 'contador'
// TODO: imprime unos espacios para borrar dígitos sobrantes -> lcd.print(" ");
// TODO: incrementa 'contador'
// TODO: espera 1 segundo -> delay(1000);
}Solución — cópiala y ejecútala
/*
* Curso de Arduino — Módulo 08: Pantallas (LCD/OLED, I2C)
* Ejercicio 01 — MODELO (resuelto)
* Enunciado: Mostrar texto fijo en la primera línea de un LCD 1602 por I2C
* y un contador que sube cada segundo en la segunda línea.
* Dificultad: verde
* Placa: Arduino UNO Montaje: LCD 1602 con módulo I2C -> SDA=A4, SCL=A5, VCC=5V, GND=GND
* Librería: 'LiquidCrystal I2C' (instalar desde el gestor de librerías)
* Correr: Arduino IDE / Wokwi (wokwi/ej01) / arduino-cli (ver README)
*/
#include <Wire.h> // bus I2C (lo usa la librería del LCD por debajo)
#include <LiquidCrystal_I2C.h> // controla el LCD a través del expansor I2C
// Dirección I2C del módulo (0x27 es la más común; algunos clones usan 0x3F).
// 16 columnas x 2 filas:
LiquidCrystal_I2C lcd(0x27, 16, 2);
int contador = 0; // valor que iremos mostrando
void setup() {
lcd.init(); // arranca el LCD por I2C
lcd.backlight(); // enciende la retroiluminación
lcd.setCursor(0, 0); // columna 0, fila 0 (primera línea)
lcd.print("Curso Arduino"); // texto fijo
}
void loop() {
lcd.setCursor(0, 1); // columna 0, fila 1 (segunda línea)
lcd.print("Contador: ");
lcd.print(contador);
lcd.print(" "); // espacios: borran dígitos al pasar de 10 a 9, etc.
contador = contador + 1;
delay(1000);
}Cómo ejecutar la simulación
Sin instalar nada, en el navegador
- Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
- Pega la solución (o tu intento) en la pestaña
sketch.ino. - Abre la pestaña
diagram.json, borra lo que haya y pega el circuito de aquí abajo. - Dale al play. Verás el circuito funcionando: LEDs, pantallas y monitor serie.
Circuito del ejercicio (diagram.json)
{
"version": 1,
"author": "ESIBot",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
{ "type": "wokwi-lcd1602", "id": "lcd1", "top": -120, "left": 160, "attrs": { "pins": "i2c" } }
],
"connections": [
[ "uno:A4", "lcd1:SDA", "green", [] ],
[ "uno:A5", "lcd1:SCL", "yellow", [] ],
[ "uno:5V", "lcd1:VCC", "red", [] ],
[ "uno:GND.1", "lcd1:GND", "black", [] ]
],
"dependencies": {}
}En VS Code, con el repo del curso
El paquete de simulación de este ejercicio está en practica/08-pantallas/wokwi/ej01/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):
make sim EJ=08-pantallas/ej01y después, en VS Code, Ctrl+Shift+P → Wokwi: Start Simulator. La extensión no compila: simula un firmware ya compilado, y de compilarlo se encarga ese make.
Cómo usarlo
Con placa: abre el .ino en el Arduino IDE, elige placa y puerto y pulsa Subir. Sin placa: simulalo en Wokwi con cualquiera de las dos vias de arriba. Antes de mirar la solucion, intenta completar tu el esqueleto: es la mejor forma de aprender.