
BermejaSat #16: Sensor Identificado — Lectura Real de Presión y Temperatura con el BMP280
- publicado por José Luis Usero Vílchez
- Categorías: AIDARAC – Proyectos, BermejaSat, Proyecto AIDARAC
- Fecha: septiembre 2026
Introducción
En la entrada anterior dejamos preparado un banco de pruebas paralelo con una Raspberry Pi Pico W para validar el sensor barométrico antes de integrarlo en la Heltec V3.2 definitiva, junto con un código capaz de identificar automáticamente si el chip conectado era un BMP280 o un BME280. En esta entrega cerramos esa prueba: cableado confirmado, sensor identificado y primeras lecturas reales de presión y temperatura en el laboratorio.
🔌 Mapa de pines — GY-BM/PM280 a Raspberry Pi Pico W
Este es el cableado exacto, verificado y funcionando, usando los números de pin físico de la placa (no solo el nombre del GPIO, que es donde más fácil es confundirse):
| GY-BM/PM280 (sensor) | Función | Pico W — pin físico | Pico W — nombre |
|---|---|---|---|
| VCC | Alimentación 3.3V | Pin 36 | 3V3(OUT) |
| GND | Tierra | Pin 38 | GND |
| SCL | Reloj I2C | Pin 2 | GPIO1 |
| SDA | Datos I2C | Pin 1 | GPIO0 |
| CSB | Chip Select (modo SPI) | Sin conectar — dejar al aire | — |
| SDO | Selección de dirección I2C | A GND o a VCC (nivel definido, no flotante) | — |
⚠️ Dos puntos que no admiten atajos:
- CSB siempre al aire. Es el pin que decide si el chip arranca en modo I2C o SPI. Si accidentalmente toca GND, el sensor pasa a modo SPI y el bus I2C deja de responder por completo, aunque SDA/SCL estén perfectamente cableados.
- SDO tiene que estar a un nivel fijo (GND → dirección
0x76; VCC → dirección0x77), nunca flotando. En el código de esta entrada no hace falta que sepas a cuál lo has conectado, porque el propio sketch prueba las dos direcciones automáticamente.
Localizar el pin 1 físico en la Pico W: con el conector micro-USB mirando hacia arriba y la serigrafía hacia ti, el pin 1 es el primero de la columna izquierda contando desde la esquina superior.
🔬 Cómo el código distingue un BMP280 de un BME280
Ambos chips comparten el mismo diseño de placa GY-BM/PM280, así que a simple vista son indistinguibles. La solución no es adivinar ni mirar la serigrafía, sino preguntarle directamente al chip: todos los sensores Bosch de esta familia exponen un registro de solo lectura llamado Chip ID (dirección de registro 0xD0), que devuelve un valor fijo según el modelo — 0x58 para BMP280 y 0x60 para BME280. Leer ese único byte antes de inicializar nada permite que el propio sketch decida qué librería usar, sin intervención manual.
Librerías necesarias (instalar desde Herramientas → Gestionar Bibliotecas en Arduino IDE):
Adafruit BMP280 LibraryAdafruit BME280 LibraryAdafruit Unified Sensor(dependencia de ambas)
💻 Código completo (reproducible por el alumnado)
// BermejaSat - Identificación automática y lectura BMP280 / BME280
// Detecta el chip mediante su registro Chip ID (0xD0) antes de inicializar
// la librería correspondiente, y muestra los datos disponibles según el modelo.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BMP280.h>
#define SDA_PIN 0 // Pin fisico 1 de la Pico W
#define SCL_PIN 1 // Pin fisico 2 de la Pico W
Adafruit_BME280 bme;
Adafruit_BMP280 bmp;
bool esBME280 = false;
bool sensorOK = false;
uint8_t direccionSensor = 0x76;
// Lee el registro Chip ID (0xD0) directamente por I2C, sin depender
// todavia de ninguna libreria especifica de sensor.
uint8_t leerChipID(uint8_t direccion) {
Wire.beginTransmission(direccion);
Wire.write(0xD0);
if (Wire.endTransmission(false) != 0) return 0x00; // no responde en esta direccion
Wire.requestFrom(direccion, (uint8_t)1);
if (Wire.available()) {
return Wire.read();
}
return 0x00;
}
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Wire.setSDA(SDA_PIN);
Wire.setSCL(SCL_PIN);
Wire.begin();
Serial.println("BermejaSat - Identificacion automatica BMP/BME280");
// Probamos primero en 0x76 y, si no responde, en 0x77
uint8_t chipID = leerChipID(0x76);
if (chipID == 0x58 || chipID == 0x60) {
direccionSensor = 0x76;
} else {
chipID = leerChipID(0x77);
direccionSensor = 0x77;
}
Serial.print("Chip ID leido: 0x");
Serial.println(chipID, HEX);
Serial.print("Direccion I2C: 0x");
Serial.println(direccionSensor, HEX);
if (chipID == 0x60) {
Serial.println("Sensor identificado: BME280 (presion + temperatura + humedad)");
esBME280 = true;
sensorOK = bme.begin(direccionSensor);
} else if (chipID == 0x58) {
Serial.println("Sensor identificado: BMP280 (presion + temperatura, sin humedad)");
esBME280 = false;
sensorOK = bmp.begin(direccionSensor);
} else {
Serial.println("ERROR: no se reconoce ningun BMP280/BME280 en 0x76 ni 0x77.");
Serial.println("Revisa: alimentacion VCC, pin CSB al aire, cableado SDA/SCL.");
}
if (sensorOK) {
Serial.println("Sensor inicializado correctamente.\n");
}
}
void loop() {
if (!sensorOK) {
delay(3000);
return;
}
Serial.println("--- Lectura ---");
if (esBME280) {
Serial.print("Temperatura: ");
Serial.print(bme.readTemperature());
Serial.println(" C");
Serial.print("Presion: ");
Serial.print(bme.readPressure() / 100.0F); // Pa -> hPa
Serial.println(" hPa");
Serial.print("Humedad: ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.print("Altitud estimada: ");
Serial.print(bme.readAltitude(1013.25)); // presion de referencia a nivel del mar
Serial.println(" m");
} else {
Serial.print("Temperatura: ");
Serial.print(bmp.readTemperature());
Serial.println(" C");
Serial.print("Presion: ");
Serial.print(bmp.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Altitud estimada: ");
Serial.print(bmp.readAltitude(1013.25));
Serial.println(" m");
}
Serial.println();
delay(2000);
}
Importante para reproducirlo: el Monitor Serie de Arduino IDE debe estar configurado a 115200 baudios (no al valor por defecto de 9600), ya que el sketch usa Serial.begin(115200). Si las velocidades no coinciden, el monitor muestra caracteres ilegibles o nada en absoluto, aunque el sensor esté leyendo correctamente.
✅ Resultado: sensor identificado y lecturas reales
Al ejecutar el sketch sobre el banco de pruebas, el propio código confirmó el modelo exacto del sensor sin intervención manual — la ausencia del dato de humedad en la salida es la prueba definitiva:
--- Lectura ---
Temperatura: 32.52 C
Presion: 1021.49 hPa
Altitud estimada: -68.36 m
--- Lectura ---
Temperatura: 32.54 C
Presion: 1021.49 hPa
Altitud estimada: -68.38 m
Dos observaciones sobre estos datos:
- Es un BMP280, no un BME280. Solo imprime temperatura, presión y altitud; si fuera BME280 aparecería también la humedad relativa. Esto se decidió en tiempo de ejecución leyendo el Chip ID (
0x58), no por inspección visual del módulo. - La altitud negativa (-68 m) no es un fallo, es la fórmula barométrica funcionando como se espera. El cálculo usa
1013.25 hPacomo presión de referencia a nivel del mar. Como la presión real del día de la prueba fue más alta (1021.49 hPa — un día de alta presión atmosférica), la fórmula devuelve una altitud por debajo de ese cero de referencia. Para el CanSat real, esta referencia se recalibrará in situ justo antes del lanzamiento, de forma que lo que importe sea el descenso relativo medido durante el vuelo, no la altitud absoluta respecto al nivel del mar.
Conclusión Pedagógica
Esta entrada cierra el ciclo completo de validación de un componente nuevo antes de integrarlo en el sistema final: identificación de hardware por software (leyendo el Chip ID en lugar de asumir el modelo), verificación de un cableado crítico (CSB y SDO), y contraste de los datos obtenidos con la física real (por qué una altitud “negativa” es matemáticamente correcta y no un error de sensor). Con el BMP280 confirmado y funcionando de forma estable en el banco de pruebas, el siguiente paso es trasladar este mismo bloque de lectura al firmware definitivo de la Heltec V3.2, sumándolo a la trama de telemetría junto al AM2302 y al GPS.
Etiqueta:AIDARAC, altitud barométrica, bme280, BMP280, cansat, Chip ID, I2C, montesteam, presión atmosférica, Raspberry Pi Pico W


