Agregar la presión atmosférica con un sensor BMP180
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 sensor de presión BMP180
En el nivel inicial armamos una estación que mide temperatura, humedad y presencia de lluvia. Ahora le sumamos un sensor BMP180Sensor de presión BMP180Sensor barométrico que mide la presión atmosférica (y también temperatura). Digitaliza la lectura y se comunica por el bus I2C (pines SDA y SCL). La presión se expresa en hectopascales (hPa) y necesita una librería que gestione el protocolo., que mide la presión atmosférica: la fuerza que ejerce el aire sobre la superficie de la Tierra. La presión se expresa en hectopascales (hPa) (un valor típico ronda los 1013 hPa a nivel del mar).
El BMP180 no se lee por un pin cualquiera: se comunica por el bus I2C, un bus serial que usa solo dos líneas de señal, SDA (datos) y SCL (reloj), más su alimentación.
En el Arduino UNO, el bus I2C está en los pines A4 (SDA) y A5 (SCL). Conectamos ahí las líneas del BMP180, más su alimentación a 5V y GND, como indica el esquema.
En el ESP32, el bus I2C está en GPIO 21 (SDA) y GPIO 22 (SCL): exactamente los mismos pines
donde ya conectamos el LCD I2C en el nivel inicial. Y acá viene el punto lindo: el I2C es un
bus compartido. El LCD y el BMP180 se cuelgan de los mismos dos cables, y cada uno responde
a su propia dirección: el LCD en 0x27 y el BMP180 en 0x77. No hay conflicto, porque cuando
la placa «llama» a una dirección, solo contesta ese dispositivo. Conectamos, entonces, SDA y SCL del
BMP180 en paralelo con los del LCD, y su alimentación a 3,3 V y GND.
Instalar la librería del BMP180
Como el BMP180 se comunica por I2C, necesitamos una librería que resuelva ese protocolo. Es la misma que usaba el original: la “Adafruit BMP085 Library” (el BMP085 y el BMP180 son compatibles, por eso sirve la misma librería). La instalamos desde el Gestor de bibliotecas del Arduino IDE 2.x: buscamos “Adafruit BMP085” y apretamos Instalar.
En el código, el sensor se declara con Adafruit_BMP085 bmp;, se inicia con bmp.begin() en el
setup(), y la presión se lee con bmp.readPressure(). Esa función devuelve la presión en pascales
(Pa); como es más habitual expresarla en hectopascales (hPa), el código la divide por 100 antes
de mostrarla.
Para el aula
El original introducía aquí, además, un paso dedicado a «subir el código con el Arduino IDE», porque venía de programar por bloques en mBlock3. En esta reedición ese paso ya no hace falta: venimos escribiendo y subiendo C++ con el Arduino IDE 2.x desde el nivel inicial. Si algún grupo llega directamente a este nivel, es un buen momento para repasar cómo se elige la placa y el puerto y cómo se aprieta «Subir».
Programar y mostrar la presión en el display
Ahora completamos el programa: al código del nivel inicial le agregamos la lectura del BMP180 y
mostramos la presión en el display, identificada con la letra P. El original la ubica junto al
estado de la lluvia, en la segunda fila; por ejemplo, P: 1013.
El programa sigue midiendo cada INTERVALO_MEDICION_MS (2 segundos, por el límite del DHT11): en
cada ciclo lee la temperatura y la humedad del DHT11, el estado del sensor de lluvia y la presión del
BMP180, y vuelca los cuatro datos al LCD.
Ver el código completo · estacion-con-presion.ino
// Estación meteorológica con presión: además de temperatura y humedad (DHT11)
// y presencia de lluvia (sensor digital), suma un sensor BMP180 que mide la
// presión atmosférica. Todo se muestra en el LCD 16x2. Fila 0: temperatura y
// humedad. Fila 1: estado de lluvia y presión (rótulo "P:").
//
// ¿Por qué importa la presión? El original lo explica: las bajas presiones
// suelen asociarse a tiempo inestable (y a veces lluvia) y las altas, a tiempo
// estable. Sumarla enriquece el pronóstico de la estación.
//
// CONVENCIÓN DEL SENSOR DE LLUVIA (activo-bajo): la salida digital D0 vale
// BAJO cuando DETECTA agua y ALTO cuando está SECO (ver detalle en el sketch
// del nivel inicial). Por eso comparamos contra LOW.
//
// Plataforma: Arduino UNO.
// Conexión (la del esquema original): dato del DHT11 → pin 2; lluvia D0 → pin
// 3; display LCD Keypad Shield paralelo por 8, 9, 4, 5, 6, 7; BMP180 por el bus
// I2C del UNO: SDA → A4, SCL → A5.
//
// Nota del original: en el LCD no usar tildes ni la letra Ñ.
//
// Librerías requeridas (Library Manager): "DHT sensor library" (Adafruit) +
// "Adafruit Unified Sensor", y "Adafruit BMP085 Library" (sirve para BMP085 y
// BMP180, que son compatibles; es la que nombra el original).
//
// Basado en: Fragmento de código del Nivel Intermedio (Paso 3) — Estación
// Meteorológica Automatizada, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas; DHT de Adafruit con dht.begin();
// pausa de 2 s (el DHT11 no admite más de una lectura por segundo; el original
// no pausaba el loop).
#include "DHT.h"
#include <Wire.h>
#include <Adafruit_BMP085.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).
const int LLUVIA_DETECTADA_NIVEL = LOW;
// El DHT11 no admite más de una lectura por segundo; medimos cada 2 s.
const unsigned long INTERVALO_MEDICION_MS = 2000;
// Objetos de sensores y display. El BMP180 habla por I2C (A4/A5 en el UNO).
DHT dht(PIN_DHT, DHTTYPE);
Adafruit_BMP085 bmp;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
pinMode(PIN_LLUVIA, INPUT);
dht.begin();
bmp.begin(); // inicializa el sensor de presión por I2C
lcd.begin(16, 2);
lcd.clear();
}
void loop() {
float temperatura = dht.readTemperature(); // grados Celsius
float humedad = dht.readHumidity(); // humedad relativa en %
// readPressure() devuelve pascales (Pa); dividimos por 100 para tener
// hectopascales (hPa), la unidad habitual del "1013 hPa" del clima.
float presion = bmp.readPressure() / 100.0;
// 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 (col 0) y presión (col 10).
lcd.setCursor(0, 1);
if (digitalRead(PIN_LLUVIA) == LLUVIA_DETECTADA_NIVEL) {
lcd.print("Lluvia:SI");
} else {
lcd.print("Lluvia:NO");
}
lcd.setCursor(10, 1);
lcd.print("P:");
lcd.print(presion);
delay(INTERVALO_MEDICION_MS);
} // Estación meteorológica con presión: además de temperatura y humedad (DHT11)
// y presencia de lluvia (sensor digital), suma un sensor BMP180 que mide la
// presión atmosférica. Todo se muestra en el LCD 16x2. Fila 0: temperatura y
// humedad. Fila 1: estado de lluvia y presión (rótulo "P:").
//
// ¿Por qué importa la presión? El original lo explica: las bajas presiones
// suelen asociarse a tiempo inestable (y a veces lluvia) y las altas, a tiempo
// estable.
//
// BUS I2C COMPARTIDO (¡buen punto didáctico!): en el ESP32, TANTO el LCD como
// el BMP180 se conectan al MISMO bus I2C (SDA GPIO 21, SCL GPIO 22). El I2C es
// un bus compartido: varios dispositivos conviven en los mismos dos cables
// porque cada uno tiene una DIRECCIÓN distinta. El LCD responde en 0x27 y el
// BMP180 en 0x77, así que no hay conflicto. Ambos cuelgan en paralelo de
// SDA/SCL.
//
// CONVENCIÓN DEL SENSOR DE LLUVIA (activo-bajo): la salida D0 vale BAJO cuando
// DETECTA agua y ALTO cuando está SECO (ver detalle en el nivel inicial).
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: DHT11 → GPIO 4; lluvia D0 → GPIO 14; LCD y BMP180 al bus I2C
// (SDA GPIO 21, SCL GPIO 22).
//
// ADAPTACIÓN DE PLATAFORMA (ver README): el original usa un LCD Keypad Shield
// paralelo que no entra en un ESP32; acá el LCD es 1602 I2C (LiquidCrystal_I2C,
// 0x27; probá 0x3F si no muestra nada).
// Nota eléctrica: el ESP32 trabaja a 3,3 V; DHT11, BMP180 y LCD I2C andan 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) +
// "Adafruit Unified Sensor", "Adafruit BMP085 Library" (BMP085/BMP180) y
// "LiquidCrystal_I2C".
//
// Basado en: Fragmento de código del Nivel Intermedio (Paso 3) — Estación
// Meteorológica Automatizada, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas; portado a ESP32; DHT de Adafruit con
// dht.begin(); LCD adaptado a I2C (comparte bus con el BMP180); pausa de 2 s.
#include "DHT.h"
#include <Wire.h>
#include <Adafruit_BMP085.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;
// Objetos de sensores y display. LCD (0x27) y BMP180 (0x77) comparten el bus.
DHT dht(PIN_DHT, DHTTYPE);
Adafruit_BMP085 bmp;
LiquidCrystal_I2C lcd(LCD_DIRECCION_I2C, LCD_COLUMNAS, LCD_FILAS);
void setup() {
pinMode(PIN_LLUVIA, INPUT);
dht.begin();
bmp.begin(); // el BMP180 se inicializa por el mismo bus I2C que el LCD
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
float temperatura = dht.readTemperature(); // grados Celsius
float humedad = dht.readHumidity(); // humedad relativa en %
float presion = bmp.readPressure() / 100.0; // Pa → hPa
// 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 (col 0) y presión (col 10).
lcd.setCursor(0, 1);
if (digitalRead(PIN_LLUVIA) == LLUVIA_DETECTADA_NIVEL) {
lcd.print("Lluvia:SI");
} else {
lcd.print("Lluvia:NO");
}
lcd.setCursor(10, 1);
lcd.print("P:");
lcd.print(presion);
delay(INTERVALO_MEDICION_MS);
} Fijate, al comparar las dos plataformas con el selector, que el sensor de presión se lee igual en ambas: la librería resuelve el I2C por debajo. Lo único que cambia entre UNO y ESP32 es, otra vez, la parte del display.
Podés ver el sistema completo —los cuatro datos actualizándose en pantalla— 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 la temperatura y la humedad en la primera fila,
y el estado de la lluvia junto a la presión (P: con un valor cercano a 1000 hPa) en la segunda,
actualizándose cada 2 segundos. Si la presión aparece como 0 o un valor disparatado, revisá las
conexiones I2C (SDA y SCL) y que la librería Adafruit BMP085 esté instalada. En el ESP32, verificá
que el LCD y el BMP180 compartan bien las líneas SDA y SCL.
Cierre del nivel
Al terminar este nivel, tu estación mide cuatro variables del clima —temperatura, humedad, lluvia y presión atmosférica— y las muestra todas en el display. Además, apareció una idea importante: el bus I2C, donde el BMP180 (y, en el ESP32, también el LCD) conviven en dos cables compartidos gracias a sus direcciones. En el nivel avanzado vamos a poder mirar todos estos datos a distancia: publicaremos la temperatura, la humedad, la presión y el estado de la lluvia por Internet de las Cosas para monitorear la estación desde el celular.
Evidencia de cierre
Al terminar este nivel, esto tiene que estar funcionando:
- El sensor de presión BMP180 está conectado por el bus I2C: en el UNO por A4 (SDA) y A5 (SCL); en el ESP32 por GPIO 21 (SDA) y GPIO 22 (SCL), compartiendo el bus con el LCD I2C.
- Instalaste la librería Adafruit BMP085 (compatible con el BMP180) desde el gestor de bibliotecas del Arduino IDE 2.x.
- El display muestra ahora también la presión atmosférica en hectopascales (hPa), junto a la temperatura, la humedad y el estado de la lluvia.