Medir temperatura, humedad y lluvia 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
Empezamos por la pantalla donde vamos a ver las mediciones: 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. Acá aparece la primera diferencia 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, los sensores se cablean a los pines que quedan libres.
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. 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). Guardá en la memoria este bus I2C: en el nivel intermedio el sensor de presión se va a colgar de estos mismos dos cables.
La programación la haremos directamente en el lenguaje de Arduino (C++), con el Arduino IDE en
su versión 2.x, que se descarga gratis desde
arduino.cc/en/software. Un programa de Arduino se llama
sketch y tiene dos bloques: setup(), que se ejecuta una sola vez al encender, y loop(), que
se ejecuta repetidamente después. Todo lo que sigue a // es un comentario: no afecta al programa,
sirve para que el código sea más fácil de leer.
Un detalle a tener siempre presente con estas pantallas: el LCD no representa bien las tildes ni
la letra Ñ, así que los textos se escriben sin ellas (por eso, más adelante, T:, H: y
Lluvia:).
Si al probar el display no se lee (pantalla en blanco o todo encendido), ajustá el contraste con el potenciómetro azul (RP1) de la esquina superior izquierda del shield, con un destornillador chico.
Conectar el sensor de temperatura y humedad (DHT11)
Ahora sumamos el sensor que mide el aire: el sensor DHT11Sensor DHT11Sensor digital que mide temperatura y humedad del aire en un mismo integrado. Digitaliza la lectura internamente y la entrega por un pin digital (no es analógico: no va a A0). Necesita una librería para leerlo y no admite más de una lectura por segundo., que registra la temperatura y la humedad en un mismo integrado.
Un dato importante: el DHT11 es un sensor digital. A diferencia de un sensor analógico (que se conecta a una entrada A0–A5), el DHT11 tiene electrónica interna que digitaliza la medición y la transmite a la placa como un paquete de datos por un pin digital. Por eso no va a A0: va a un pin digital, y para leerlo hace falta una librería que gestione esa comunicación (la instalamos en un momento).
El DHT11 tiene tres conexiones útiles: alimentación (VCC y GND) y datos.
En el Arduino UNO seguimos el esquema original: el pin de datos del DHT11 va al pin digital 2
(la constante PIN_DHT del código), VCC al pin 5V y GND a GND.
En el ESP32 la conexión es equivalente, con un cuidado propio de la placa: el pin de datos del
DHT11 va al GPIO 4 (la constante PIN_DHT del código) y la alimentación se toma de 3,3 V
(no de 5 V) y GND. El DHT11 funciona sin problemas a 3,3 V.
Para poder leer el sensor necesitamos instalar su librería. En el Arduino IDE 2.x abrimos el
Gestor de bibliotecas (el ícono de los libritos en la barra lateral), buscamos “DHT sensor
library” de Adafruit y la instalamos; el IDE ofrecerá instalar también su dependencia
“Adafruit Unified Sensor”: aceptá, porque el sensor no funciona sin ella. Esta librería
reemplaza a la vieja DHT.h genérica del original, que ya no se consigue igual.
Programar la lectura del DHT11 y mostrarla en el display
Con la pantalla y el sensor conectados, la primera versión del programa lee el DHT11 y muestra
sus valores en el LCD. Aprovechamos las dos filas del display: en la primera escribimos la
temperatura, precedida por el rótulo T:, y a su lado la humedad con el rótulo H:. En cada
vuelta de loop() el programa lee el sensor una vez y actualiza esos números.
Hay un detalle del sensor que marca el ritmo del programa: el DHT11 no admite más de una lectura
por segundo. Por eso, entre medición y medición el programa espera con delay() el tiempo de la
constante INTERVALO_MEDICION_MS, que está en 2 segundos (un margen seguro; la librería de
Adafruit, además, guarda la última lectura durante 2 segundos). En este primer nivel usar delay()
es lo más simple y hace que el código se lea igual que su comportamiento; en el nivel avanzado lo
cambiaremos.
En el próximo paso agregamos el sensor de lluvia y vemos el programa completo del nivel inicial.
Agregar el sensor de lluvia
Falta el tercer sensor de esta etapa: el sensor de lluviaSensor de lluviaMódulo que detecta la presencia de lluvia. Una placa colectora con pistas conductoras se moja y, junto a un comparador, entrega una salida digital que indica «llueve / no llueve». Se conecta a un pin digital y su umbral de detección se ajusta con un potenciómetro.. Con él,
en la segunda fila del display vamos a mostrar Lluvia: SI o Lluvia: NO, según corresponda.
El sensor de lluvia consta de una placa colectora (la que se moja) recorrida por dos pistas
conductoras, y una plaquita con un comparador. Cuando cae agua, las pistas se conectan y el módulo
lo detecta. Lo importante para programarlo: su salida digital (DO) indica presencia o ausencia
de lluvia, así que se conecta a un pin digital (el pin de la constante PIN_LLUVIA del código,
el 3 del original) y se lee con digitalRead().
Antes de medir conviene calibrar el umbral con el potenciómetro azul del módulo. En la
calibración del original: cuando el sensor detecta agua, su salida digital queda en estado
BAJO (0 V); cuando no detecta lluvia, queda en estado ALTO (5 V). El programa lee ese
estado con digitalRead(): si está en alto, muestra Lluvia: NO; si está en bajo, Lluvia: SI.
En el Arduino UNO, la salida digital (DO) del sensor de lluvia va al pin 3 (PIN_LLUVIA), y su
alimentación a 5V y GND.
En el ESP32, la salida digital (DO) del sensor de lluvia va a un pin digital (PIN_LLUVIA, el
GPIO indicado en el código) y su alimentación a 3,3 V y GND.
Este es el programa completo del nivel inicial: lee el DHT11 y el sensor de lluvia, y muestra en el
LCD la temperatura, la humedad y el estado de la lluvia. Lo único que cambia entre plataformas es
cómo se maneja el display (LiquidCrystal en el UNO, LiquidCrystal_I2C en el ESP32); la lógica
de los sensores es idéntica.
Ver el código completo · estacion-basica.ino
// Estación meteorológica básica: mide temperatura y humedad del aire con un
// sensor DHT11 y detecta presencia de lluvia con un sensor digital, y muestra
// todo en un display LCD 16x2. Fila 0: temperatura y humedad. Fila 1: si
// llueve o no.
//
// CONVENCIÓN DEL SENSOR DE LLUVIA (¡importante!, activo-bajo): este módulo
// (tipo FC-37 / YL-83 con comparador LM393) cierra circuito cuando se moja.
// Su salida digital D0 vale BAJO (0 V) cuando DETECTA agua y ALTO (5 V)
// cuando está SECO. El original lo confirma: "al detectar agua... la salida
// digital D0 se debe encontrar en el estado BAJO (0V); cuando no se detecta
// lluvia... en el estado ALTO (5V)". Por eso comparamos contra LOW.
// La sensibilidad se calibra con el potenciómetro azul del módulo.
//
// Plataforma: Arduino UNO.
// Conexión (la del esquema original): dato del DHT11 → pin 2; salida digital
// D0 del sensor de lluvia → pin 3; display LCD Keypad Shield en modo paralelo
// por los pines 8, 9, 4, 5, 6, 7 (se apila sobre el UNO; su potenciómetro RP1
// ajusta el contraste).
//
// Nota del original: en el LCD no usar tildes ni la letra Ñ.
// Nota física: la placa de contactos del sensor de lluvia se moja a propósito,
// pero la electrónica (la placa Arduino y el módulo comparador) debe quedar
// protegida del agua. Es todo de baja tensión (5 V).
//
// Basado en: Fragmento de código del Nivel Inicial (Paso 4) — Estación
// Meteorológica Automatizada, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: (1) C++ idiomático con constantes nombradas en vez del C de
// mBlock3. (2) Librería "DHT sensor library" de Adafruit (instalar con su
// dependencia "Adafruit Unified Sensor"), que reemplaza la vieja "DHT.h" y
// requiere dht.begin(). (3) El original no pausaba el loop; acá medimos cada
// 2 s porque el DHT11 no admite más de una lectura por segundo.
#include "DHT.h"
#include <LiquidCrystal.h>
// Pin de datos del sensor y tipo de sensor (DHT11).
const int PIN_DHT = 2;
#define DHTTYPE DHT11
// Salida digital D0 del sensor de lluvia.
const int PIN_LLUVIA = 3;
// Nivel de la salida del sensor cuando HAY lluvia (activo-bajo: ver encabezado).
const int LLUVIA_DETECTADA_NIVEL = LOW;
// El DHT11 no admite más de una lectura por segundo; medimos cada 2 s
// (margen seguro; la librería de Adafruit además cachea 2 s).
const unsigned long INTERVALO_MEDICION_MS = 2000;
// Objeto del sensor y display paralelo (RS, E, D4, D5, D6, D7).
DHT dht(PIN_DHT, DHTTYPE);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
pinMode(PIN_LLUVIA, INPUT);
dht.begin();
lcd.begin(16, 2);
lcd.clear();
}
void loop() {
float temperatura = dht.readTemperature(); // grados Celsius
float humedad = dht.readHumidity(); // humedad relativa en %
// Fila 0: temperatura (col 0) y humedad (col 8). Sin tildes ni Ñ.
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperatura);
lcd.setCursor(8, 0);
lcd.print("H:");
lcd.print(humedad);
// Fila 1: estado de la lluvia. La salida en LOW significa agua detectada.
lcd.setCursor(0, 1);
if (digitalRead(PIN_LLUVIA) == LLUVIA_DETECTADA_NIVEL) {
lcd.print("Lluvia:SI");
} else {
lcd.print("Lluvia:NO");
}
// En este nivel usamos delay(): es la herramienta que ya conocemos y hace
// que el programa se lea de arriba hacia abajo igual que su comportamiento.
delay(INTERVALO_MEDICION_MS);
} // Estación meteorológica básica: mide temperatura y humedad del aire con un
// sensor DHT11 y detecta presencia de lluvia con un sensor digital, y muestra
// todo en un display LCD 16x2. Fila 0: temperatura y humedad. Fila 1: si
// llueve o no.
//
// CONVENCIÓN DEL SENSOR DE LLUVIA (¡importante!, activo-bajo): este módulo
// (tipo FC-37 / YL-83 con comparador LM393) cierra circuito cuando se moja.
// Su salida digital D0 vale BAJO (0 V) cuando DETECTA agua y ALTO cuando está
// SECO. El original lo confirma: "al detectar agua... la salida D0 en estado
// BAJO; cuando no se detecta lluvia... en ALTO". Por eso comparamos contra LOW.
// La sensibilidad se calibra con el potenciómetro azul del módulo.
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: dato del DHT11 → GPIO 4; salida digital D0 del sensor de lluvia →
// GPIO 14; display LCD 1602 por I2C: SDA → GPIO 21, SCL → GPIO 22.
//
// ADAPTACIÓN DE PLATAFORMA (ver README): el original usa un LCD Keypad Shield
// paralelo (6 pines) que no entra en un ESP32; acá usamos un LCD 1602 con
// módulo I2C (2 cables, librería LiquidCrystal_I2C, dirección típica 0x27;
// probá 0x3F si no muestra nada).
// Nota eléctrica: el ESP32 trabaja a 3,3 V; el DHT11 y el módulo I2C del LCD
// funcionan a 3,3 V. El módulo de lluvia se alimenta a 3,3 V para que su
// salida no supere ese nivel en el GPIO.
// Nota física: la placa de contactos del sensor de lluvia se moja a propósito,
// pero la electrónica (placa y módulo comparador) debe quedar protegida del
// agua. Es todo de baja tensión.
//
// Librerías requeridas (Library Manager): "DHT sensor library" (Adafruit) +
// "Adafruit Unified Sensor", y "LiquidCrystal_I2C".
//
// Basado en: Fragmento de código del Nivel Inicial (Paso 4) — Estación
// Meteorológica Automatizada, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: C++ idiomático con constantes nombradas; portado a ESP32;
// DHT de Adafruit con dht.begin(); LCD paralelo del original adaptado a I2C;
// pausa de 2 s (límite del DHT11; el original no pausaba el loop).
#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
// Salida digital D0 del sensor de lluvia.
const int PIN_LLUVIA = 14;
// Nivel de la salida del sensor cuando HAY lluvia (activo-bajo).
const int LLUVIA_DETECTADA_NIVEL = LOW;
// 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;
// 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_LLUVIA, INPUT);
dht.begin();
// Con I2C, primero arranca el display; backlight enciende la luz de fondo.
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
float temperatura = dht.readTemperature(); // grados Celsius
float humedad = dht.readHumidity(); // humedad relativa en %
// Fila 0: temperatura (col 0) y humedad (col 8). Sin tildes ni Ñ.
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperatura);
lcd.setCursor(8, 0);
lcd.print("H:");
lcd.print(humedad);
// Fila 1: estado de la lluvia. La salida en LOW significa agua detectada.
lcd.setCursor(0, 1);
if (digitalRead(PIN_LLUVIA) == LLUVIA_DETECTADA_NIVEL) {
lcd.print("Lluvia:SI");
} else {
lcd.print("Lluvia:NO");
}
delay(INTERVALO_MEDICION_MS);
} Podés ver el comportamiento —los valores actualizándose y el estado de la lluvia cambiando— en el simulador, antes de armar el circuito real:
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.
Para subir el código a la placa, conectala a la computadora con el cable USB, elegí en el Arduino IDE 2.x la placa y el puertoPuerto COMPuerto de comunicaciones por el cual el sistema operativo se comunica con un dispositivo externo, como la placa. Se asigna automáticamente al conectarla por USB y puede cambiar de número; en el IDE hay que indicar cuál usar. (en el IDE 2.x se eligen juntos en el menú desplegable de la barra superior) y apretá el botón Subir (la flecha →). Al terminar, aparece el mensaje de carga completada en la barra inferior.
Para el Arduino UNO: usá el cable USB tipo B, elegí la placa Arduino UNO y el puerto que se
agregó al conectarla (en Windows es un puerto COM numerado; en Linux suele llamarse /dev/ttyACM0
o similar).
Para el ESP32 hay dos pasos previos que se hacen una sola vez: instalar el soporte de placas ESP32 desde el gestor de placas del IDE (buscá “esp32” e instalá el paquete de Espressif) y, si el puerto no aparece, instalar el driver del conversor USB-serie de tu placa (generalmente CP210x o CH340). Después, elegí la placa ESP32 Dev Module (o “DOIT ESP32 DEVKIT V1”) y el puerto correspondiente. Si al subir el IDE queda esperando en “Connecting…”, mantené apretado el botón BOOT de la placa hasta que empiece la carga.
Verificá
Con el programa cargado, el display tiene que mostrar T: y H: con sus valores en la primera fila
y Lluvia: NO en la segunda (con el sensor seco). Acercá al DHT11 una fuente de calor suave (la
mano ahuecada, el aliento): el número de temperatura tiene que subir. Mojá apenas la placa
colectora del sensor de lluvia (con unas gotas, cuidando la electrónica): la segunda fila tiene que
pasar a Lluvia: SI. Si el estado de la lluvia queda invertido o no cambia, ajustá el umbral con el
potenciómetro del módulo.
Cierre del nivel
Al terminar este nivel, tu estación ya mide y muestra tres datos del clima: la temperatura y la humedad del aire (DHT11) y la presencia de lluvia (sensor de lluvia), todo en el display LCD. En el camino armaste un circuito con varios sensores y viste la primera diferencia real entre las plataformas: el LCD paralelo del UNO frente al LCD por I2C del ESP32. En el nivel intermedio vamos a sumar un dato más del tiempo —la presión atmosférica— con un sensor BMP180 que se comunica por el bus I2C.
Evidencia de cierre
Al terminar este nivel, esto tiene que estar funcionando:
- El circuito está montado en la protoboard: el display LCD conectado (LCD Keypad Shield apilado en el UNO, o LCD 1602 por I2C en el ESP32), el sensor DHT11 en su pin de datos y el sensor de lluvia en su pin digital.
- Sabés subir un programa desde el Arduino IDE 2.x: elegir la placa, elegir el puerto y verificar que el código quedó cargado.
- El display muestra la temperatura y la humedad que mide el DHT11 y, en la segunda fila, «Lluvia: SI» o «Lluvia: NO» según el estado del sensor de lluvia.
- Entendés que el DHT11 es digital (pin digital, no A0) y que el sensor de lluvia entrega una salida digital de umbral (llueve / no llueve).