Almacenando automáticamente todas las medidas de nuestra estación meteorológica con Python
Uno de los aspectos más importantes de cualquier proyecto científico es garantizar que ninguna medida se pierda durante la adquisición de datos.
Después de conseguir que nuestra estación meteorológica enviara las medidas desde Arduino Mega hasta Python y posteriormente a ThingSpeak, el siguiente paso lógico era incorporar un sistema de almacenamiento automático en el ordenador.
La solución ha sido desarrollar un pequeño módulo en Python que se ejecuta al iniciar el programa y organiza automáticamente todas las sesiones de medida.
Cada ejecución genera una estructura de carpetas como la siguiente:
Proyecto_Eclipse_2026
│
└── 2026-07-24
│
└── Datos_21-48-36.csv
Dentro de cada archivo CSV quedan almacenadas todas las variables registradas por la estación:
- Fecha y hora.
- Temperatura (DHT22).
- Humedad.
- Temperatura del BMP280.
- Presión atmosférica.
- Altitud calculada.
- Luminosidad.
- Radiación ultravioleta.
- Voltaje del sensor UV.
Mientras Arduino continúa enviando una lectura cada pocos segundos, Python las almacena inmediatamente en el disco duro y, de forma independiente, publica una parte de ellas en ThingSpeak respetando las limitaciones de la versión gratuita.
Gracias a esta arquitectura conseguimos disponer simultáneamente de tres copias de la información:
- la tarjeta SD instalada en Arduino,
- el archivo CSV generado por Python,
- y la publicación automática en ThingSpeak.
Esta redundancia proporciona una gran seguridad para un proyecto de adquisición de datos como el que estamos desarrollando para el eclipse total de Sol de 2026.
En próximas entregas construiremos una interfaz gráfica que permitirá visualizar en tiempo real todos estos datos y generar gráficas durante la observación del eclipse.
CÓDIGO
import serial
import requests
import time
import csv
import os
from datetime import datetime
# =====================================
# CONFIGURACIÓN
# =====================================
PUERTO = "COM3" # Cambiar por el puerto del Mega
BAUDIOS = 115200
CHANNEL_ID = 3435298
WRITE_API_KEY = "PGYX6LNKM0EQZFA9"
URL = "https://api.thingspeak.com/update"
# =====================================
arduino = serial.Serial(PUERTO, BAUDIOS, timeout=1)
# =====================================
# CREAR CARPETA Y ARCHIVO CSV
# =====================================
fecha = datetime.now()
# Carpeta principal
CARPETA_PRINCIPAL = "Proyecto_Eclipse_2026"
os.makedirs(CARPETA_PRINCIPAL, exist_ok=True)
# Carpeta con la fecha
carpeta = os.path.join(
CARPETA_PRINCIPAL,
fecha.strftime("%Y-%m-%d")
)
os.makedirs(carpeta, exist_ok=True)
# Nombre del archivo
nombreCSV = fecha.strftime("Datos_%H-%M-%S.csv")
rutaCSV = os.path.join(carpeta, nombreCSV)
csvFile = open(rutaCSV, "w", newline="", encoding="utf-8")
writer = csv.writer(csvFile)
writer.writerow([
"FechaHora",
"Temperatura_DHT",
"Humedad",
"Temperatura_BMP",
"Presion",
"Altitud",
"Luminosidad",
"UV",
"VoltajeUV"
])
print("-------------------------------------")
print("CSV creado correctamente")
print(rutaCSV)
print("-------------------------------------")
print("Puerto serie abierto.")
print("Esperando datos...\n")
ultimo_envio = 0
while True:
linea = arduino.readline().decode(errors="ignore").strip()
if not linea.startswith("DATOS,"):
continue
print(linea)
datos = linea.split(",")
temperatura = float(datos[1])
humedad = float(datos[2])
temperaturaBMP = float(datos[3])
presion = float(datos[4])
altitud = float(datos[5])
luz = int(datos[6])
uv = int(datos[7])
voltajeUV = float(datos[8])
# =====================================
# GUARDAR EN CSV
# =====================================
writer.writerow([
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
temperatura,
humedad,
temperaturaBMP,
presion,
altitud,
luz,
uv,
voltajeUV
])
# Escribir inmediatamente en disco
csvFile.flush()
# ThingSpeak gratuito:
# solo enviar cada 20 segundos
if time.time() - ultimo_envio >= 20:
respuesta = requests.get(
URL,
params={
"api_key": WRITE_API_KEY,
"field1": temperatura,
"field2": humedad,
"field3": temperaturaBMP,
"field4": presion,
"field5": altitud,
"field6": luz,
"field7": uv,
"field8": voltajeUV
}
)
if respuesta.text != "0":
print(">>> Datos enviados a ThingSpeak")
ultimo_envio = time.time()
else:
print(">>> Error enviando datos")




