Objetivo y caso de uso
Lo que vas a construir: Un monitor de congelador con Raspberry Pi que lee un sensor impermeable DS18B20, sirve la temperatura actual en una página web local y activa una alarma visible cuando el congelador supera un límite seguro. También almacena lecturas con marca de tiempo de forma local para que puedas verificar después la deriva de temperatura, eventos de puerta abierta o fallos de refrigeración.
Por qué importa / Casos de uso
- Comprobar el estado del congelador desde cualquier dispositivo de tu red local con cargas de página normalmente por debajo de 200 ms en una LAN doméstica.
- Detectar calentamientos inseguros, por ejemplo cuando la temperatura sube por encima de -18 °C durante varios minutos después de que se deja una puerta abierta.
- Mantener un registro local sencillo para confirmar si los alimentos permanecieron congelados durante cortes breves de energía o ciclos de descongelación.
- Crear un servicio de monitorización práctico y de baja carga en Raspberry Pi con una demanda mínima de cómputo, normalmente muy por debajo del 5% de CPU y cerca del 0% de GPU.
Resultado esperado
- Un lector de temperatura 1-Wire funcional conectado a un DS18B20 con muestreo periódico estable, por ejemplo cada 5-10 segundos.
- Un pequeño panel en el navegador que muestre la temperatura actual, el estado de alarma y actualizaciones recientes casi en tiempo real.
- Un comportamiento de alarma basado en umbral que cambie de estado cuando las lecturas superen el límite configurado para tu congelador.
- Un registro local CSV o de texto que puedas revisar más tarde para medir tendencias de temperatura, duración de alarmas y latencia de respuesta del sensor.
Audiencia: Principiantes de Raspberry Pi, makers y usuarios de laboratorio casero que estén construyendo un monitor ambiental sencillo; Nivel: Básico
Arquitectura/flujo: Sensor DS18B20 → lectura 1-Wire en Raspberry Pi → script/servidor web local ligero → página de estado en navegador + registro local de temperatura + estado de alarma cuando se supera el umbral.
Nota educativa de validación
Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. El validador comprobó los bloques de código, la estructura del artículo, los comandos copiables y la coherencia con el catálogo de dispositivos soportados.
Evidencia de validación publicada
- Resultado automático: PASS.
- Estructura parseada: 4 apartados, 3 tablas y 11 bloques de código detectados antes de publicar.
- Código comprobado: 3 Python/py_compile, 7 Bash/copy-paste checks.
- Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
- Hallazgos del informe: sin hallazgos bloqueantes.
Esta validación confirma compatibilidad sintáctica y de herramientas para el material publicado, pero no sustituye la prueba física sobre tu hardware, cableado y entorno exactos.
Nota educativa de seguridad
Este proyecto es un prototipo educativo, no un producto certificado. Antes de alimentar el montaje, verifica el pinout de la revisión exacta de tu placa ULX3S, mantén las señales de E/S del FPGA a 3.3 V, nunca conectes 5 V directamente a los pines de E/S, desconecta la alimentación antes de cambiar el cableado y usa fuentes externas adecuadas para cargas, motores o servos, compartiendo tierra solo cuando el cableado lo requiera.
title: Alarma web de temperatura para congelador en Raspberry Pi
level: Básico
slug: practical-case-raspberry-pi
Alarma web de temperatura para congelador en Raspberry Pi
Este caso práctico muestra cómo construir una alarma web de temperatura para congelador con una Raspberry Pi. La Raspberry Pi lee un sensor de temperatura 1-Wire DS18B20 impermeable, sirve una pequeña página web local y activa una alarma cuando la temperatura del congelador supera un umbral seguro para alimentos congelados.
Nota educativa de seguridad
Este proyecto es solo para monitorización. No dependas de él como única protección para la seguridad alimentaria, medicamentos o almacenamiento comercial en frío. Mantén el cableado de red eléctrica alejado de la condensación, usa una fuente de alimentación adecuada de 5 V para Raspberry Pi y coloca la electrónica fuera del recinto del congelador.
Diagrama de bloques conceptual
Vista de alto nivel: qué entra, qué procesa cada bloque y qué sale del sistema.
Arquitectura funcional
Flujo conceptual de señales y responsabilidades entre bloques del dispositivo.
Objetivo y caso de uso
Construir una alarma web de temperatura para congelador que:
- mida la temperatura dentro de un congelador,
- muestre la lectura actual en un navegador,
- muestre un estado de alarma cuando el congelador se caliente por encima de un límite configurado,
- registre las lecturas localmente para su verificación posterior.
Lista de materiales
- Raspberry Pi con Raspberry Pi OS
- Sensor de temperatura impermeable DS18B20
- Resistencia de 4.7 kOhm
- Protoboard o conexiones por terminal
- Cables jumper
- Acceso a red en la Raspberry Pi
Cableado
El DS18B20 usa el bus 1-Wire. Conéctalo a GPIO4.
| Cable DS18B20 | Función | Pin de Raspberry Pi | Notas |
|---|---|---|---|
| Rojo | VDD | 3.3 V, pin físico 1 | No uses 5 V |
| Negro | GND | GND, pin físico 6 | Tierra común |
| Amarillo/Blanco | DATA | GPIO4, pin físico 7 | Datos 1-Wire |
| Resistencia de 4.7 kOhm | Pull-up | Entre 3.3 V y DATA | Requerida para lecturas estables |
Habilitar 1-Wire en Raspberry Pi
Edita /boot/firmware/config.txt en las versiones actuales de Raspberry Pi OS y habilita el overlay de 1-Wire.
sudo sh -c 'grep -q "^dtoverlay=w1-gpio" /boot/firmware/config.txt || echo "dtoverlay=w1-gpio" >> /boot/firmware/config.txt'
sudo reboot
Después de reiniciar, confirma que los módulos del kernel y la ruta del sensor están disponibles:
lsmod | grep w1
ls /sys/bus/w1/devices/
Deberías ver entradas similares a:
w1_bus_master128-xxxxxxxxxxxx
Instalar software
Instala Flask para la interfaz web.
sudo apt update
sudo apt install -y python3-flask
Aplicación
Crea freezer_alarm.py:
#!/usr/bin/env python3
from __future__ import annotations
import csv
import glob
import os
import time
from datetime import datetime, timezone
from pathlib import Path
from flask import Flask, jsonify, render_template_string
# Alarm threshold in degrees Celsius.
# Example: alarm if freezer temperature rises above -12.0 C.
ALARM_THRESHOLD_C = -12.0
# Logging interval in seconds.
LOG_INTERVAL_S = 60
# CSV log file
LOG_FILE = Path("/home/pi/freezer_temperature_log.csv")
# DS18B20 sysfs base path
W1_BASE = "/sys/bus/w1/devices"
app = Flask(__name__)
HTML_TEMPLATE = """<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="15">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Freezer Temperature Web Alarm</title>
<style>
body { font-family: Arial, sans-serif; margin: 2rem; background: #f5f7fa; color: #222; }
.card { max-width: 36rem; padding: 1.5rem; border-radius: 12px; background: white; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.ok { color: #0a7d21; font-weight: bold; }
.alarm { color: #b00020; font-weight: bold; }
.value { font-size: 2rem; margin: 0.5rem 0; }
code { background: #eef; padding: 0.1rem 0.3rem; border-radius: 4px; }
</style>
</head>
<body>
<div class="card">
<h1>Freezer Temperature Web Alarm</h1>
<p class="value">{{ temp_text }}</p>
<p>Status:
{% if alarm %}
<span class="alarm">ALARM</span>
{% else %}
<span class="ok">OK</span>
{% endif %}
</p>
<p>Alarm threshold: <code>{{ threshold }} C</code></p>
<p>Last update: <code>{{ timestamp }}</code></p>
<p>JSON endpoint: <code>/api/status</code></p>
</div>
</body>
</html>
"""
def find_sensor_file() -> str:
matches = glob.glob(os.path.join(W1_BASE, "28-*", "w1_slave"))
if not matches:
raise FileNotFoundError(
"No DS18B20 sensor found under /sys/bus/w1/devices/. "
"Check wiring and 1-Wire configuration."
)
return matches[0]
def read_temperature_c() -> float:
sensor_file = find_sensor_file()
with open(sensor_file, "r", encoding="ascii") as f:
lines = f.read().strip().splitlines()
if len(lines) != 2 or not lines[0].endswith("YES"):
raise RuntimeError("Sensor CRC check failed")
marker = "t="
pos = lines[1].find(marker)
if pos == -1:
raise RuntimeError("Temperature value not found in sensor output")
milli_c = int(lines[1][pos + len(marker):])
return milli_c / 1000.0
def alarm_state(temp_c: float) -> bool:
return temp_c > ALARM_THRESHOLD_C
def ensure_log_header() -> None:
if not LOG_FILE.exists():
LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(LOG_FILE, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["timestamp_utc", "temperature_c", "alarm"])
def append_log_once() -> None:
ensure_log_header()
temp_c = read_temperature_c()
state = alarm_state(temp_c)
now = datetime.now(timezone.utc).isoformat()
with open(LOG_FILE, "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow([now, f"{temp_c:.3f}", int(state)])
@app.route("/")
def index():
temp_c = read_temperature_c()
state = alarm_state(temp_c)
timestamp = datetime.now(timezone.utc).isoformat()
return render_template_string(
HTML_TEMPLATE,
temp_text=f"{temp_c:.2f} C",
alarm=state,
threshold=f"{ALARM_THRESHOLD_C:.1f}",
timestamp=timestamp,
)
@app.route("/api/status")
def api_status():
temp_c = read_temperature_c()
state = alarm_state(temp_c)
timestamp = datetime.now(timezone.utc).isoformat()
return jsonify(
{
"device": "Raspberry Pi",
"application": "freezer-temperature-web-alarm",
"temperature_c": round(temp_c, 3),
"alarm": state,
"alarm_threshold_c": ALARM_THRESHOLD_C,
"timestamp_utc": timestamp,
}
)
def main() -> None:
append_log_once()
app.run(host="0.0.0.0", port=8000, debug=False)
if __name__ == "__main__":
main()
Hazlo ejecutable:
chmod +x freezer_alarm.py
Servicio de registro opcional
La aplicación web registra una vez al iniciarse. Para un registro continuo en segundo plano cada minuto, crea freezer_logger.py:
#!/usr/bin/env python3
from __future__ import annotations
import csv
import glob
import os
import time
from datetime import datetime, timezone
from pathlib import Path
ALARM_THRESHOLD_C = -12.0
LOG_INTERVAL_S = 60
LOG_FILE = Path("/home/pi/freezer_temperature_log.csv")
W1_BASE = "/sys/bus/w1/devices"
def find_sensor_file() -> str:
matches = glob.glob(os.path.join(W1_BASE, "28-*", "w1_slave"))
if not matches:
raise FileNotFoundError("No DS18B20 sensor found")
return matches[0]
def read_temperature_c() -> float:
sensor_file = find_sensor_file()
with open(sensor_file, "r", encoding="ascii") as f:
lines = f.read().strip().splitlines()
if len(lines) != 2 or not lines[0].endswith("YES"):
raise RuntimeError("Sensor CRC check failed")
pos = lines[1].find("t=")
if pos == -1:
raise RuntimeError("Temperature value not found")
return int(lines[1][pos + 2:]) / 1000.0
def ensure_log_header() -> None:
if not LOG_FILE.exists():
LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(LOG_FILE, "w", newline="", encoding="utf-8") as f:
csv.writer(f).writerow(["timestamp_utc", "temperature_c", "alarm"])
def main() -> None:
ensure_log_header()
while True:
now = datetime.now(timezone.utc).isoformat()
temp_c = read_temperature_c()
alarm = int(temp_c > ALARM_THRESHOLD_C)
with open(LOG_FILE, "a", newline="", encoding="utf-8") as f:
csv.writer(f).writerow([now, f"{temp_c:.3f}", alarm])
time.sleep(LOG_INTERVAL_S)
if __name__ == "__main__":
main()
Ejecuta la aplicación web:
python3 freezer_alarm.py
En otra terminal, ejecuta el registrador:
python3 freezer_logger.py
Abre la página de estado desde otro dispositivo en la misma red:
hostname -I
Luego navega a:
http://<raspberry-pi-ip>:8000/
Cómo funciona la alarma
Esta alarma web de temperatura para congelador informa:
- OK cuando la temperatura del congelador es menor o igual que
-12.0 C - ALARM cuando la temperatura del congelador supera
-12.0 C
Puedes cambiar el límite en ambos archivos Python editando:
ALARM_THRESHOLD_C = -12.0
Método de validación
No afirmes precisión ni fiabilidad sin comprobarlas. Un método de validación sencillo es:
| Comprobación | Método | Evidencia esperada |
|---|---|---|
| Detección del sensor | ls /sys/bus/w1/devices/ | Existe un directorio de dispositivo 28-... |
| Lectura de temperatura en vivo | Abrir /api/status | El JSON incluye temperature_c y alarm |
| Umbral de alarma | Calienta ligeramente el sensor con la mano o mueve la sonda hacia el aire ambiente para una prueba breve | alarm cambia de false a true cuando la temperatura medida cruza el umbral |
| Registro | Espera al menos 2 minutos | /home/pi/freezer_temperature_log.csv contiene varias filas con marca de tiempo |
Solución de problemas
| Síntoma | Causa | Solución |
|---|---|---|
No existe la ruta del sensor 28-... | 1-Wire no habilitado o error de cableado | Vuelve a comprobar dtoverlay=w1-gpio, el cableado y reinicia |
| La comprobación CRC falló | Conexión débil o ruido | Comprueba la colocación de la resistencia y las uniones del cable |
| La página web no es accesible | La aplicación no se está ejecutando o hay un problema de firewall/red | Inicia python3 freezer_alarm.py y verifica la dirección IP de la Pi |
| La temperatura parece incorrecta | La sonda no está colocada completamente en el área objetivo | Reubica el sensor y compáralo con un termómetro conocido |
Resultado
Ahora tienes una alarma web de temperatura para congelador en Raspberry Pi que lee la temperatura desde un sensor DS18B20, expone una página en el navegador y un endpoint de estado JSON, y registra mediciones para su verificación.
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.




