Ver temperatura y humedad en un display LCD
Recorrido del nivel
Esa barra de arriba te dice en qué paso estás. Tocala para ver el índice completo y saltar a cualquier paso.
Conectar el display LCD
Vamos a sumar un display LCDDisplay LCDPantalla de cristal líquido que muestra texto en filas y columnas; el clásico es de 16 columnas por 2 filas. Se puede conectar en modo paralelo (muchos pines) o por I2C (solo dos cables, SDA y SCL). No representa bien las tildes ni la letra Ñ. de 16 columnas por 2 filas para ver en pantalla lo que mide el sensor. Acá aparece la primera diferencia real entre las dos plataformas de este proyecto, y vale la pena entenderla, porque es muy didáctica: el display se conecta de una manera distinta en cada una.
En el Arduino UNO usamos el LCD Keypad Shield del original, un shieldShieldPlaca modular que se monta encimada sobre una placa Arduino, encastrando en sus pines, para agregarle funciones (pantalla, sensores, comunicación). Suele diseñarse para un modelo concreto: el LCD Keypad Shield tiene el formato del Arduino UNO y no encaja en un ESP32. que tiene el formato de la placa y se apila directamente encima del UNO, encastrando en sus pines: no hay que cablear nada en la protoboard. Al apilarlo, el display queda conectado en modo paralelo, usando seis pines de datos de la placa (los pines 8, 9, 4, 5, 6 y 7). Es importante no forzar las piezas: todos los pines deben coincidir perfectamente. Como el shield ocupa varios pines, el LED y el sensor DHT11 se cablean a los pines que quedan libres, tal como veníamos.
El LCD Keypad Shield tiene el formato del Arduino UNO y no se enchufa en un ESP32. Por eso, en el ESP32 usamos un LCD 1602 con módulo I2C: la misma pantalla de 16x2, pero con una plaquita (el módulo I2C) pegada atrás que reduce el cableado a solo dos cables de señal. En lugar de los seis pines del modo paralelo, conectamos: VCC a 3,3 V, GND a GND, SDA al GPIO 21 y SCL al GPIO 22 (los pines I2C por defecto del ESP32). Esta es una adaptación de plataforma pensada a propósito: hace lo mismo que el shield con muchísimo menos cableado.
Instalar la librería y probar el display con un saludo
Para manejar el display necesitamos su librería, y cada plataforma usa una distinta, en correspondencia con la forma en que conectamos la pantalla en el paso anterior.
En el Arduino UNO, el shield en modo paralelo se maneja con la librería LiquidCrystal, que
ya viene incluida con el Arduino IDE (no hay que instalar nada). En el código, el display se
declara indicándole los seis pines que usa: LiquidCrystal lcd(8, 9, 4, 5, 6, 7).
En el ESP32, el LCD por I2C se maneja con la librería LiquidCrystal_I2C, que se instala
desde el Gestor de bibliotecas del IDE (buscá “LiquidCrystal_I2C”). En el código, el display
se declara con su dirección I2C —típicamente 0x27— y su tamaño: LiquidCrystal_I2C lcd(0x27, 16, 2). Si al probar la pantalla no muestra nada, es posible que tu módulo use la dirección
0x3F: probá con ese valor.
Para familiarizarnos con el display, un primer programa de prueba puede escribir un saludo:
tras inicializar la pantalla, con lcd.print("Buen dia") aparece ese texto en la primera fila.
Un detalle a tener siempre presente: el LCD no representa bien las tildes ni la letra Ñ, así
que los textos se escriben sin ellas (por eso “Buen dia”, y más adelante “Temp.” y “Hum.”).
Si en el UNO el saludo no se lee (pantalla en blanco o todo encendido), ajustá el contraste con el potenciómetro azul (RP1) que está en la esquina superior izquierda del shield, usando un destornillador chico.
Mostrar la temperatura y la humedad en el display
Ahora volvemos al sistema completo: el sensor DHT11 y el LED de aviso siguen conectados como en el
nivel inicial, y le sumamos el display. Aprovechamos que el LCD tiene dos filas para escribir
la temperatura en la primera y la humedad en la segunda, cada una precedida por un rótulo
(Temp.: y Hum.:) para que se lean con claridad.
El programa toma lo del nivel inicial y le agrega el display: en cada vuelta lee una sola vez
la temperatura y la humedad del DHT11, con esos valores decide el aviso (el LED parpadea si la
temperatura supera UMBRAL_TEMP_C, igual que antes) y los escribe en el LCD. Sigue midiendo cada
INTERVALO_MEDICION_MS (2 segundos), respetando el límite del sensor.
Ver el código completo · temp-humedad-lcd.ino
// Invernadero con display: el sensor DHT11 mide temperatura y humedad del
// aire, un LCD 16x2 las muestra en pantalla, y el LED de ventilación
// PARPADEA cuando la temperatura supera el umbral (igual que en el nivel
// inicial). Ahora, además del aviso, vemos los números exactos.
//
// Plataforma: Arduino UNO.
// Conexión (la del esquema original): dato del DHT11 → pin 2; LED → pin 13;
// display LCD Keypad Shield en modo paralelo por los pines 8, 9, 4, 5, 6, 7.
// El shield se apila directamente sobre el UNO; su potenciómetro RP1 ajusta
// el contraste si no se lee el texto.
//
// Nota del original: en el LCD no usar tildes ni la letra Ñ (el display no
// las representa bien). Por eso los rótulos van como "Temp." y "Hum.".
//
// Basado en: Fragmento de código del Nivel Intermedio (Paso 5) — Invernadero
// Inteligente, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: (1) constantes nombradas en vez del C de mBlock3. (2)
// Librería DHT de Adafruit (ver nivel inicial), con dht.begin(). (3) El
// original llamaba a readTemperature() y readHumidity() varias veces por
// vuelta; acá se leen UNA vez a variables y esos mismos valores se usan
// para el LED y para el display.
#include "DHT.h"
#include <LiquidCrystal.h>
// Pin de datos del sensor y tipo de sensor (DHT11).
const int PIN_DHT = 2;
#define DHTTYPE DHT11
// LED indicador de "hay que ventilar".
const int PIN_LED_VENTILACION = 13;
// Umbral del original: por encima de 25 °C hay que ventilar.
const float UMBRAL_TEMP_C = 25.0;
// Tiempos del parpadeo del aviso, como en el original.
const unsigned long PARPADEO_ENCENDIDO_MS = 500;
const unsigned long PARPADEO_APAGADO_MS = 500;
// El DHT11 no admite más de una lectura por segundo; medimos cada 2 s.
const unsigned long INTERVALO_MEDICION_MS = 2000;
// Objeto del sensor: pin de datos + tipo.
DHT dht(PIN_DHT, DHTTYPE);
// Display LCD en modo paralelo. El orden de pines es el del LCD Keypad
// Shield: (RS, E, D4, D5, D6, D7) = (8, 9, 4, 5, 6, 7).
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
pinMode(PIN_LED_VENTILACION, OUTPUT);
dht.begin();
// Inicializamos el display de 16 columnas por 2 filas y lo limpiamos.
lcd.begin(16, 2);
lcd.clear();
}
void loop() {
// Leemos una sola vez y reutilizamos los valores. readTemperature() da
// grados Celsius; readHumidity() da humedad relativa en %.
float temperatura = dht.readTemperature();
float humedad = dht.readHumidity();
if (temperatura > UMBRAL_TEMP_C) {
// Demasiado calor: un parpadeo del LED para avisar que hay que ventilar.
digitalWrite(PIN_LED_VENTILACION, HIGH);
delay(PARPADEO_ENCENDIDO_MS);
digitalWrite(PIN_LED_VENTILACION, LOW);
delay(PARPADEO_APAGADO_MS);
}
// Fila 0: temperatura. Fila 1: humedad. Sin tildes ni Ñ (limitación LCD).
lcd.setCursor(0, 0);
lcd.print("Temp.: ");
lcd.print(temperatura);
lcd.setCursor(0, 1);
lcd.print("Hum.: ");
lcd.print(humedad);
delay(INTERVALO_MEDICION_MS);
} // Invernadero con display: el sensor DHT11 mide temperatura y humedad del
// aire, un LCD 16x2 las muestra en pantalla, y el LED de ventilación
// PARPADEA cuando la temperatura supera el umbral (igual que en el inicial).
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: dato del DHT11 → GPIO 4; LED externo → GPIO 16; display LCD 1602
// por I2C: SDA → GPIO 21, SCL → GPIO 22 (los pines I2C por defecto del ESP32).
//
// ADAPTACIÓN DE PLATAFORMA (¡importante!, ver README): el original usa un
// LCD Keypad Shield, una placa con formato Arduino UNO que se apila sobre la
// placa y se maneja con LiquidCrystal en modo PARALELO (6 pines de datos:
// 8, 9, 4, 5, 6, 7). Ese shield NO se enchufa en un ESP32. Por eso en ESP32
// usamos un LCD 1602 con módulo I2C: solo DOS cables de señal (SDA y SCL) en
// lugar de seis, y la librería LiquidCrystal_I2C en lugar de LiquidCrystal.
// Es el estándar moderno y evita el problema del shield. La dirección I2C
// típica de estos módulos es 0x27 (algunos son 0x3F: si la pantalla no
// muestra nada, probá 0x3F o escaneá el bus I2C).
// Nota eléctrica: el ESP32 trabaja a 3,3 V; DHT11 y el módulo I2C del LCD
// funcionan a 3,3 V.
//
// Nota del original: en el LCD no usar tildes ni la letra Ñ.
//
// Librerías requeridas (Library Manager): "DHT sensor library" (Adafruit) +
// su dependencia "Adafruit Unified Sensor", y "LiquidCrystal_I2C".
//
// Basado en: Fragmento de código del Nivel Intermedio (Paso 5) — Invernadero
// Inteligente, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas; DHT de Adafruit con dht.begin(); LCD
// paralelo del original adaptado a I2C para ESP32; una sola lectura por
// vuelta reutilizada para LED y display.
#include "DHT.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Pin de datos del sensor y tipo de sensor (DHT11).
const int PIN_DHT = 4;
#define DHTTYPE DHT11
// LED externo indicador de "hay que ventilar".
const int PIN_LED_VENTILACION = 16;
// Dirección I2C y tamaño del display (16 columnas x 2 filas).
const uint8_t LCD_DIRECCION_I2C = 0x27;
const uint8_t LCD_COLUMNAS = 16;
const uint8_t LCD_FILAS = 2;
// Umbral del original: por encima de 25 °C hay que ventilar.
const float UMBRAL_TEMP_C = 25.0;
// Tiempos del parpadeo del aviso, como en el original.
const unsigned long PARPADEO_ENCENDIDO_MS = 500;
const unsigned long PARPADEO_APAGADO_MS = 500;
// El DHT11 no admite más de una lectura por segundo; medimos cada 2 s.
const unsigned long INTERVALO_MEDICION_MS = 2000;
// Objeto del sensor y display por I2C.
DHT dht(PIN_DHT, DHTTYPE);
LiquidCrystal_I2C lcd(LCD_DIRECCION_I2C, LCD_COLUMNAS, LCD_FILAS);
void setup() {
pinMode(PIN_LED_VENTILACION, OUTPUT);
dht.begin();
// Con I2C, primero arranca el bus y el display; backlight enciende la luz.
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
// Leemos una sola vez y reutilizamos los valores.
float temperatura = dht.readTemperature(); // grados Celsius
float humedad = dht.readHumidity(); // humedad relativa en %
if (temperatura > UMBRAL_TEMP_C) {
// Demasiado calor: un parpadeo del LED para avisar que hay que ventilar.
digitalWrite(PIN_LED_VENTILACION, HIGH);
delay(PARPADEO_ENCENDIDO_MS);
digitalWrite(PIN_LED_VENTILACION, LOW);
delay(PARPADEO_APAGADO_MS);
}
// Fila 0: temperatura. Fila 1: humedad. Sin tildes ni Ñ (limitación LCD).
lcd.setCursor(0, 0);
lcd.print("Temp.: ");
lcd.print(temperatura);
lcd.setCursor(0, 1);
lcd.print("Hum.: ");
lcd.print(humedad);
delay(INTERVALO_MEDICION_MS);
} Fijate, al comparar las dos plataformas con el selector, que el corazón del programa es idéntico: cambia solo la parte del display (qué librería se incluye y cómo se declara e inicializa la pantalla). Todo lo demás —leer el sensor, decidir el aviso, los rótulos— es el mismo código.
Podés ver el sistema completo —el sensor midiendo, el display actualizándose y el LED avisando— en el simulador:
Simulación del comportamiento
La misma máquina de estados del firmware, portada a TypeScript, maneja el
comportamiento del dispositivo. No se ejecuta el binario real: la ejecución
del .hex con avr8js está en el roadmap.
Simulación lista. Presioná «Iniciar» para arrancar la secuencia.
Verificá
Con el programa cargado, el display tiene que mostrar Temp.: con el valor en la primera fila y
Hum.: con el valor en la segunda, actualizándose cada 2 segundos. Al acercar calor al sensor y
superar los 25 °C, el número de temperatura tiene que subir y el LED empezar a parpadear. Si la
pantalla se ve en blanco, revisá el contraste (RP1 en el UNO) o la dirección I2C (0x27 o 0x3F
en el ESP32).
Cierre del nivel
Al terminar este nivel, el invernadero no solo avisa que hace calor: muestra en pantalla los valores exactos de temperatura y humedad del aire. En el camino apareció una diferencia real y muy formativa entre las plataformas —el shield paralelo del UNO frente al LCD por I2C del ESP32— y viste que la lógica del proyecto no cambia, solo la manera de conectar la pantalla. En el nivel avanzado vamos a poder mirar todo esto a distancia: publicaremos la temperatura y la humedad por Internet de las Cosas para monitorear el invernadero desde el celular.
Evidencia de cierre
Al terminar este nivel, esto tiene que estar funcionando:
- El display LCD está conectado: en el UNO, el LCD Keypad Shield apilado sobre la placa (modo paralelo, 6 pines); en el ESP32, un LCD 1602 por I2C, con solo dos cables de señal (SDA y SCL).
- Instalaste la librería correcta según tu plataforma (LiquidCrystal, que ya viene con el IDE, en el UNO; LiquidCrystal_I2C en el ESP32) y probaste el display con un saludo, sin tildes ni Ñ.
- El display muestra la temperatura en la primera fila y la humedad en la segunda, y el LED sigue avisando (parpadea) cuando la temperatura supera UMBRAL_TEMP_C (25 °C).