Caso práctico: monitor de congelador con Raspberry Pi

Caso práctico: monitor de congelador Raspberry Pi — hero

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

Sensor DS18B20

lectura 1-Wire en Raspberry Pi

script/servidor web local ligero

página de estado en navegador + registro…

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 DS18B20FunciónPin de Raspberry PiNotas
RojoVDD3.3 V, pin físico 1No uses 5 V
NegroGNDGND, pin físico 6Tierra común
Amarillo/BlancoDATAGPIO4, pin físico 7Datos 1-Wire
Resistencia de 4.7 kOhmPull-upEntre 3.3 V y DATARequerida 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_master1
  • 28-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ónMétodoEvidencia esperada
Detección del sensorls /sys/bus/w1/devices/Existe un directorio de dispositivo 28-...
Lectura de temperatura en vivoAbrir /api/statusEl JSON incluye temperature_c y alarm
Umbral de alarmaCalienta ligeramente el sensor con la mano o mueve la sonda hacia el aire ambiente para una prueba brevealarm cambia de false a true cuando la temperatura medida cruza el umbral
RegistroEspera al menos 2 minutos/home/pi/freezer_temperature_log.csv contiene varias filas con marca de tiempo

Solución de problemas

SíntomaCausaSolución
No existe la ruta del sensor 28-...1-Wire no habilitado o error de cableadoVuelve a comprobar dtoverlay=w1-gpio, el cableado y reinicia
La comprobación CRC fallóConexión débil o ruidoComprueba la colocación de la resistencia y las uniones del cable
La página web no es accesibleLa aplicación no se está ejecutando o hay un problema de firewall/redInicia python3 freezer_alarm.py y verifica la dirección IP de la Pi
La temperatura parece incorrectaLa sonda no está colocada completamente en el área objetivoReubica 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

Ir a 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.

Quiz rápido

Pregunta 1: ¿Qué sensor impermeable se utiliza en el monitor de congelador descrito?




Pregunta 2: ¿Cuál es una de las funciones principales del sistema construido con Raspberry Pi?




Pregunta 3: ¿Qué ocurre cuando el congelador supera un límite seguro de temperatura?




Pregunta 4: ¿Para qué se almacenan lecturas con marca de tiempo de forma local?




Pregunta 5: ¿Desde dónde se puede comprobar el estado del congelador según el artículo?




Pregunta 6: ¿Qué temperatura se menciona como ejemplo de calentamiento inseguro?




Pregunta 7: ¿Qué nivel de carga de CPU suele requerir este servicio de monitorización?




Pregunta 8: ¿Qué uso de GPU se menciona para este servicio?




Pregunta 9: ¿Qué tipo de servicio se pretende crear con la Raspberry Pi?




Pregunta 10: ¿Qué situación puede confirmar el registro local además de la deriva de temperatura?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio