
Entrada 12: Datalogger “Caja Negra” y Control Atmosférico con BME280 y Tarjeta SD en el Iglú Científico BermejaHab
Completada la telemetría en tiempo real del Invernadero y el Centro de Control, nos adentramos en el Módulo de Experimentos Científicos (Iglú). El alumnado asume el rol de Analistas de Datos Muestrales y Mantenimiento de Soporte Vital Atmosférico.
En esta fase se aborda la resiliencia de datos: la telemetría no solo se transmite por puerto serie, sino que se almacena de forma ininterrumpida en una tarjeta MicroSD en formato CSV (DATALOG.CSV), registrando presión, temperatura, humedad y el estado de la atmósfera lunar.
Plaintext
┌─────────────────────────────────────────────────────────────┐
│ IGLÚ DE EXPERIMENTOS CIENTÍFICOS │
│ │
│ ┌────────────────┐ ┌──────────────────────────┐ │
│ │ Sensor BME280 │ (I2C) │ Arduino Uno/Nano/Mega │ │
│ │ (P, T, H) ├────────>│ (Procesador de Vuelo) │ │
│ └────────────────┘ └────────────┬─────────────┘ │
│ │ (SPI) │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Módulo Tarjeta MicroSD │ │
│ │ (Caja Negra / CSV Log) │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
🤖 Prompt Optimizado para Claude: Generador de Firmware Datalogger
Plaintext
Actúa como un ingeniero de sistemas embebidos de la ESA/NASA. Genera un sketch completo, limpio y listo para compilar en C++ para Arduino (Uno, Nano o Mega) que gestione la toma de datos del Iglú Científico de la base BermejaHab.
Requisitos de Hardware:
1. Sensor BME280 por I2C (dirección 0x76 o 0x77) usando las librerías <Wire.h>, <Adafruit_Sensor.h> y <Adafruit_BME280.h>.
2. Módulo de Tarjeta MicroSD mediante bus SPI (Pin Chip Select / CS en el Pin 10) usando <SPI.h> y <SD.h>.
3. LED integrado (Pin 13) como testigo visual de escritura en disco.
Requisitos de Código:
1. En setup():
- Inicializa el puerto serie a 9600 baudios.
- Detecta e inicializa el BME280 (autodetección de dirección I2C 0x76 y 0x77).
- Inicializa la tarjeta SD. Si se inicializa correctamente, verifica si existe el archivo "DATALOG.CSV". Si el archivo no existe o está vacío, crea la cabecera: "Tiempo_ms;Presion_hPa;Temp_C;Humedad_Pct;Estado_Atmosfera".
2. En loop() (cada 3000 ms):
- Lee presión (hPa), temperatura (°C) y humedad (%).
- Clasifica el estado según la presión:
* 1000.0 hPa a 1025.0 hPa -> "NOMINAL"
* < 1000.0 hPa -> "ALERTA_DESPRESURIZACION"
* > 1025.0 hPa -> "ALERTA_SOBREPRESION"
- Escribe la fila separada por punto y coma (;) en "DATALOG.CSV" y parpadea el LED 13 durante la escritura.
- Muestra por el Monitor Serie la trama formateada para la telemetría web:
"[LAB] T:XXs | P:XXXX.X hPa | Temp:XX.X C | Hum:XX.X % | Estado: ESTADO"
Escribe únicamente código C++ funcional, con comentarios explicativos y sin placeholders.

💻 Código Firmware Real: Datalogger BME280 + SD (Iglu_Cientifico_Datalogger.ino)
C++
/*
BermejaHab - Iglú de Experimentos Científicos
Datalogger "Caja Negra" (BME280 + Módulo SD SPI)
IES Monterroso - Proyecto MonteSTEAM
*/
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// Configuración de Hardware
const int chipSelect = 10; // Pin CS (Chip Select) del lector SD
const int ledWrite = 13; // LED integrado indicador de escritura
// Objetos globales
Adafruit_BME280 bme;
File dataFile;
bool sdOK = false;
bool bmeOK = false;
void setup() {
Serial.begin(9600);
pinMode(ledWrite, OUTPUT);
digitalWrite(ledWrite, LOW);
Serial.println(F("=================================================="));
Serial.println(F(" BERMEJAHAB - INICIALIZANDO IGLÚ CIENTÍFICO "));
Serial.println(F("=================================================="));
// 1. Inicialización BME280 (I2C)
if (bme.begin(0x76)) {
bmeOK = true;
Serial.println(F("🟢 BME280 detectado en direccion 0x76."));
} else if (bme.begin(0x77)) {
bmeOK = true;
Serial.println(F("🟢 BME280 detectado en direccion 0x77."));
} else {
Serial.println(F("❌ ERROR: No se encuentra el sensor BME280. Revisa el cableado I2C."));
}
// 2. Inicialización Tarjeta MicroSD (SPI)
Serial.print(F("Iniciando Tarjeta SD... "));
if (!SD.begin(chipSelect)) {
Serial.println(F("❌ FALLO: Tarjeta SD no detectada o error de lectura SPI."));
} else {
sdOK = true;
Serial.println(F("🟢 Tarjeta SD lista para registrar datos."));
// Verificar o crear cabecera CSV
dataFile = SD.open("DATALOG.CSV", FILE_WRITE);
if (dataFile) {
if (dataFile.size() == 0) {
dataFile.println(F("Tiempo_ms;Presion_hPa;Temp_C;Humedad_Pct;Estado_Atmosfera"));
Serial.println(F("📝 Cabecera CSV creada con éxito en DATALOG.CSV"));
}
dataFile.close();
} else {
Serial.println(F("⚠️ Error abriendo el archivo DATALOG.CSV"));
}
}
}
void loop() {
if (!bmeOK) {
Serial.println(F("⚠️ Error: BME280 no disponible. Comprueba las conexiones SDA/SCL."));
delay(3000);
return;
}
// Lectura de variables ambientales
float presion = bme.readPressure() / 100.0F; // Convertir Pa a hPa
float temp = bme.readTemperature();
float humedad = bme.readHumidity();
unsigned long tiempo = millis();
// Evaluador de Seguridad Atmosférica en el Iglú
String estadoAtmosfera = "NOMINAL";
if (presion < 1000.0) {
estadoAtmosfera = "ALERTA_DESPRESURIZACION";
} else if (presion > 1025.0) {
estadoAtmosfera = "ALERTA_SOBREPRESION";
}
// A. Emisión por Puerto Serie (Formato Telemetría Web)
Serial.print(F("[LAB] T:"));
Serial.print(tiempo / 1000);
Serial.print(F("s | P:"));
Serial.print(presion, 1);
Serial.print(F(" hPa | Temp:"));
Serial.print(temp, 1);
Serial.print(F(" C | Hum:"));
Serial.print(humedad, 1);
Serial.print(F(" % | Estado: "));
Serial.println(estadoAtmosfera);
// B. Registro en Tarjeta SD (Caja Negra CSV)
if (sdOK) {
digitalWrite(ledWrite, HIGH); // Testigo encendido durante la escritura
dataFile = SD.open("DATALOG.CSV", FILE_WRITE);
if (dataFile) {
dataFile.print(tiempo);
dataFile.print(F(";"));
dataFile.print(presion, 2);
dataFile.print(F(";"));
dataFile.print(temp, 2);
dataFile.print(F(";"));
dataFile.print(humedad, 2);
dataFile.print(F(";"));
dataFile.println(estadoAtmosfera);
dataFile.close();
} else {
Serial.println(F("⚠️ Error de escritura en disco SD."));
}
digitalWrite(ledWrite, LOW);
}
delay(3000); // Frecuencia de muestreo: 3 segundos
}
🛠️ Esquema de Conexión Compacto (Protoboard)
| Módulo / Sensor | Pin Módulo | Pin Arduino Uno / Nano | Pin Arduino Mega | Notas de Cableado |
| BME280 (I2C) | VCC / GND | 3.3V o 5V / GND | 3.3V o 5V / GND | Alimentación y tierra |
| SDA / SCL | A4 / A5 | 20 (SDA) / 21 (SCL) | Bus I2C de datos y reloj | |
| Lector SD (SPI) | VCC / GND | 5V / GND | 5V / GND | Alimentación del lector SD |
| MOSI / MISO | Pin 11 / Pin 12 | Pin 51 / Pin 50 | Bus SPI (Master In/Out) | |
| SCK / CS | Pin 13 / Pin 10 | Pin 52 / Pin 10 | Reloj SPI / Chip Select |
🔄 Secuencia Didáctica en el Taller y Laboratorio
- 💻 Simulación y Código desde Casa: El alumnado utiliza el Prompt de Claude para generar el firmware, analizando cómo se gestionan los errores de conexión I2C y la estructura de archivos en sistemas incrustados.
- 🔌 Montaje e Integración en el Aula: Conexión del sensor BME280 y el módulo SD. Inserción de una tarjeta MicroSD formateada en FAT32.
- 🧪 Prueba de Estrés Atmosférico: Simulación de una bajada brusca de presión colocando el BME280 dentro de un recipiente hermético flexible y aplicando succión para verificar el salto de estado a
ALERTA_DESPRESURIZACION. - 📊 Extracción de la “Caja Negra”: Retiro de la tarjeta MicroSD e inspección del archivo
DATALOG.CSVen hojas de cálculo o visualizadores web.
🎓 Vinculación Curricular (3º / 4º ESO)
- Asignaturas: Física y Química / Tecnología y Digitalización.
- Saberes Básicos:
- Sistemas de Adquisición de Datos: Sensores I2C/SPI, calibración y conversión de unidades de presión ($hPa$).
- Estructuras de Almacenamiento Persistente: Creación y gestión de archivos planos CSV (
DATALOG.CSV) para análisis estadístico posterior. - Física Atmosférica Espacial: Estudio de la presión en entornos confinados, despresurización y margen de supervivencia de la tripulación.
- Competencias Específicas: Diseñar y construir prototipos tecnológicos capaces de monitorizar magnitudes físicas reales y garantizar la redundancia de datos.



