You dont have javascript enabled! Please enable it!

Caso práctico: alarma calidad aire con Raspberry Pi 4

Caso práctico: alarma calidad aire con Raspberry Pi 4 — hero

Alarma de calidad del aire con Raspberry Pi 4 usando BME680 y HyperPixel 4.0 Touch

Objetivo y caso de uso

Qué construirás: Un panel de calidad del aire con Raspberry Pi 4 Model B usando un sensor BME680 y una pantalla HyperPixel 4.0 Touch para mostrar las condiciones de la habitación en vivo y estimar IAQ, eCO2 y TVOC en tiempo real. La interfaz se ejecuta localmente con tasas de refresco fluidas para pantalla táctil y muestra una alarma clara en pantalla cuando el eCO2 estimado supera un umbral configurable, como 1000 ppm.

Por qué importa / Casos de uso

  • Recordatorio de ventilación para aulas que ofrece una indicación visible cuando el eCO2 estimado supera 1000–1500 ppm.
  • Monitor de confort para oficina en casa para seguir temperatura, humedad y tendencias de aire viciado con actualizaciones locales de baja latencia.
  • Indicador para taller o sala de hobbies para detectar una mala renovación del aire y cambios en los patrones de VOC durante proyectos en interiores.
  • Pantalla de estado de sala de reuniones con estado codificado por colores para comprobaciones rápidas de apto/no apto antes de la ocupación.
  • Prototipo educativo para comparar cambios de ventilación frente a métricas IAQ estimadas y el comportamiento de la alarma.

Resultado esperado

  • Interfaz de pantalla táctil que muestra temperatura, humedad, presión, resistencia del gas, puntuación IAQ, eCO2 estimado y TVOC estimado.
  • Estado de la habitación codificado por colores con renderizado responsivo, normalmente alrededor de 20–30 FPS en una Pi 4 para un panel ligero.
  • Banner de alarma visible cuando el eCO2 estimado cruza el límite configurado, con respuesta local de la interfaz en menos de un segundo.
  • Interacción por toque o ratón para alternar detalles y reconocer temporalmente la alarma sin detener la monitorización.
  • Soporte tanto para modo con hardware real como para modo simulado para probar el flujo de la interfaz, umbrales de alarma y datos de demostración.
  • Funcionamiento local eficiente adecuado para uso tipo kiosco, manteniéndose a menudo en un rango modesto de GPU para un panel simple a pantalla completa.

Audiencia: Makers de Raspberry Pi, educadores y aficionados que construyen pantallas ambientales prácticas; Nivel: Intermedio

Arquitectura/flujo: La Pi 4 lee los valores del sensor BME680, deriva IAQ además de eCO2/TVOC estimados, actualiza un panel HyperPixel Touch a pantalla completa, aplica reglas de estado por color y activa un banner de alarma visible con reconocimiento táctil opcional cuando se supera el umbral configurado; en modo simulado, las lecturas simuladas siguen la misma canalización.

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: 31 apartados, 1 tablas y 23 bloques de código detectados en el contenido publicado.
  • Código comprobado: 2 Python/py_compile, 20 Bash/copy-paste checks.
  • Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo; 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

Nota de seguridad

Este proyecto es un prototipo educativo de calidad del aire en interiores, no un instrumento de seguridad certificado.

  • El BME680 no mide CO2 real directamente.
  • Los valores de eCO2 e IAQ mostrados en este tutorial son estimaciones heurísticas derivadas del comportamiento de la humedad y la resistencia del gas.
  • No uses esta construcción como única base para decisiones de salud, cumplimiento legal, detección de atmósferas peligrosas o respuesta a emergencias.
  • Alimenta la Raspberry Pi solo con una fuente USB-C adecuada de bajo voltaje.
  • Usa una carcasa o un montaje seguro para que la electrónica expuesta no pueda cortocircuitarse ni tocarse accidentalmente.

Requisitos previos

Necesitas:

  • Raspberry Pi 4 Model B
  • Raspberry Pi OS Bookworm de 64 bits
  • Python 3.11
  • Módulo BME680 con soporte I2C
  • HyperPixel 4.0 Touch
  • Uso básico de terminal
  • Conocimientos básicos de cableado GPIO/I2C

Materiales

ElementoModelo exactoPropósito
Ordenador de placa únicaRaspberry Pi 4 Model BEjecuta la aplicación
SensorBME680Temperatura, humedad, presión, resistencia del gas
Pantalla táctilHyperPixel 4.0 TouchInterfaz táctil local
Fuente de alimentaciónFuente USB-C de 5 V para Raspberry Pi 4Alimentación estable
CableadoCables jumper hembra a hembraCableado del sensor
AlmacenamientoTarjeta microSD, 16 GB o superiorSO y archivos del proyecto

Configuración del hardware

Cableado I2C del BME680

Conecta el BME680 al encabezado de 40 pines de la Raspberry Pi:

  • BME680 VCC/VIN -> 3.3 V en la Raspberry Pi, pin 1 físico
  • BME680 GND -> GND en la Raspberry Pi, pin 6 físico
  • BME680 SDA -> SDA1 en la Raspberry Pi, pin 3 físico
  • BME680 SCL -> SCL1 en la Raspberry Pi, pin 5 físico

Notas:

  • Confirma que tu placa breakout es compatible con 3.3 V
  • No conectes una placa solo de 3.3 V a 5 V
  • Si la placa también soporta SPI, usa solo los pines I2C listados arriba

HyperPixel 4.0 Touch

Instala y verifica la HyperPixel usando las instrucciones actuales de Pimoroni para tu imagen de Raspberry Pi OS. Antes de continuar, confirma:

  • La pantalla muestra el escritorio de Raspberry Pi
  • La entrada táctil funciona correctamente

Preparación del sistema

Actualiza la Pi y habilita I2C:

sudo apt update
sudo apt full-upgrade -y
sudo raspi-config

En raspi-config:

  1. Abre Interface Options
  2. Habilita I2C
  3. Reinicia si se te solicita

Comprueba Python:

python3 --version

Instala los paquetes del sistema necesarios:

sudo apt install -y git python3-pip python3-venv i2c-tools

Verifica que el sensor aparece en I2C:

i2cdetect -y 1

Un BME680 aparece habitualmente en 0x76 o 0x77.

Configuración del proyecto

Crea el proyecto y el entorno virtual:

mkdir -p ~/projects/touchscreen-co2-air-quality-alarm
cd ~/projects/touchscreen-co2-air-quality-alarm
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install pygame smbus2 bme680

Valida las importaciones:

python3 -c "import pygame, smbus2, bme680; print('imports ok')"

Código de la aplicación

air_quality_alarm.py

#!/usr/bin/env python3
"""
Touchscreen air-quality alarm for:
- Raspberry Pi 4 Model B
- BME680 over I2C
- HyperPixel 4.0 Touch

The IAQ, eCO2, and TVOC values here are educational heuristic estimates.
They are useful for trend display and UI behavior validation, not certified measurement.
"""

from __future__ import annotations

import argparse
import math
import random
import sys
import time
from dataclasses import dataclass
from typing import Optional, Tuple

import pygame


@dataclass
class SensorReading:
    temperature_c: float
    humidity_pct: float
    pressure_hpa: float
    gas_ohms: float
    iaq_score: float
    eco2_ppm: int
    tvoc_ppb: int
    timestamp: float


def clamp(value: float, low: float, high: float) -> float:
    return max(low, min(high, value))


def estimate_iaq_score(humidity_pct: float, gas_ohms: float) -> float:
    """
    Educational heuristic only.
    Lower score is better, with an approximate 0..500 scale.
    """
    humidity_target = 40.0
    humidity_offset = abs(humidity_pct - humidity_target)
    humidity_score = clamp(humidity_offset / 40.0 * 25.0, 0.0, 25.0)

    gas_reference = 50000.0
    gas_ratio = clamp((gas_reference - gas_ohms) / gas_reference, 0.0, 1.0)
    gas_score = gas_ratio * 475.0

    return round(humidity_score + gas_score, 1)


def estimate_eco2_ppm(iaq_score: float, gas_ohms: float) -> int:
    """
    Educational heuristic only.
    Maps worsening gas behavior to an estimated eCO2 range.
    """
    base = 420
    score_component = int(iaq_score * 4.2)
    gas_component = int(clamp((50000.0 - gas_ohms) / 80.0, 0.0, 2000.0))
    return int(clamp(base + score_component + gas_component, 400, 2500))


def estimate_tvoc_ppb(iaq_score: float, gas_ohms: float) -> int:
    """
    Educational heuristic only.
    """
    base = 20
    score_component = int(iaq_score * 1.5)
    gas_component = int(clamp((50000.0 - gas_ohms) / 120.0, 0.0, 1000.0))
    return int(clamp(base + score_component + gas_component, 0, 1200))


def air_quality_state(eco2_ppm: int) -> Tuple[str, Tuple[int, int, int]]:
    if eco2_ppm < 800:
        return ("GOOD", (40, 140, 70))
    if eco2_ppm < 1200:
        return ("ELEVATED", (180, 150, 40))
    if eco2_ppm < 1600:
        return ("POOR", (190, 100, 30))
    return ("ALARM", (170, 40, 40))


class BME680Adapter:
    """Real sensor adapter using the bme680 package."""

    def __init__(self, i2c_addr: int = 0x76):
        self.i2c_addr = i2c_addr
        self.sensor = None

    def open(self) -> None:
        import bme680

        self.sensor = bme680.BME680(i2c_addr=self.i2c_addr)
        self.sensor.set_humidity_oversample(bme680.OS_2X)
        self.sensor.set_pressure_oversample(bme680.OS_4X)
        self.sensor.set_temperature_oversample(bme680.OS_8X)
        self.sensor.set_filter(bme680.FILTER_SIZE_3)
        self.sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)
        self.sensor.set_gas_heater_temperature(320)
        self.sensor.set_gas_heater_duration(150)
        self.sensor.select_gas_heater_profile(0)

    def read(self) -> SensorReading:
        if self.sensor is None:
            raise RuntimeError("Sensor not opened")

        if not self.sensor.get_sensor_data():
            raise RuntimeError("No sensor data available")

        data = self.sensor.data
        gas_ohms = float(getattr(data, "gas_resistance", 0.0) or 0.0)

        iaq_score = estimate_iaq_score(float(data.humidity), gas_ohms)
        eco2_ppm = estimate_eco2_ppm(iaq_score, gas_ohms)
        tvoc_ppb = estimate_tvoc_ppb(iaq_score, gas_ohms)

        return SensorReading(
            temperature_c=float(data.temperature),
            humidity_pct=float(data.humidity),
            pressure_hpa=float(data.pressure),
            gas_ohms=gas_ohms,
            iaq_score=iaq_score,
            eco2_ppm=eco2_ppm,
            tvoc_ppb=tvoc_ppb,
            timestamp=time.time(),
        )


class MockBME680Adapter:
    """Mock adapter for validation without hardware."""

    def __init__(self) -> None:
        self.t0 = time.time()

    def open(self) -> None:
        return

    def read(self) -> SensorReading:
        elapsed = time.time() - self.t0

        temperature_c = 22.0 + 1.5 * math.sin(elapsed / 40.0)
        humidity_pct = 45.0 + 8.0 * math.sin(elapsed / 55.0)
        pressure_hpa = 1012.0 + 1.2 * math.sin(elapsed / 120.0)

        baseline = 45000.0
        drop = min(32000.0, elapsed * 350.0)
        noise = random.uniform(-1200.0, 1200.0)
        gas_ohms = max(5000.0, baseline - drop + noise)

        iaq_score = estimate_iaq_score(humidity_pct, gas_ohms)
        eco2_ppm = estimate_eco2_ppm(iaq_score, gas_ohms)
        tvoc_ppb = estimate_tvoc_ppb(iaq_score, gas_ohms)

        return SensorReading(
            temperature_c=temperature_c,
            humidity_pct=humidity_pct,
            pressure_hpa=pressure_hpa,
            gas_ohms=gas_ohms,
            iaq_score=iaq_score,
            eco2_ppm=eco2_ppm,
            tvoc_ppb=tvoc_ppb,
            timestamp=time.time(),
        )


class HyperPixelUI:
    def __init__(self, width: int = 800, height: int = 480):
        pygame.init()
        pygame.font.init()
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("Air Quality Alarm")
        self.width = width
        self.height = height
        self.font_big = pygame.font.SysFont("Arial", 52)
        self.font_med = pygame.font.SysFont("Arial", 32)
        self.font_small = pygame.font.SysFont("Arial", 24)
        self.show_detail = False
        self.alarm_ack_until = 0.0

    def draw(self, reading: SensorReading, alarm_threshold: int) -> None:
        state, bg = air_quality_state(reading.eco2_ppm)
        self.screen.fill(bg)

        now = time.time()
        alarm_active = (
            reading.eco2_ppm >= alarm_threshold and now >= self.alarm_ack_until
        )

        title = self.font_big.render(state, True, (255, 255, 255))
        self.screen.blit(title, (30, 20))

        eco2_text = self.font_big.render(
            f"eCO2 {reading.eco2_ppm} ppm", True, (255, 255, 255)
        )
        self.screen.blit(eco2_text, (30, 95))

        iaq_text = self.font_med.render(
            f"IAQ score: {reading.iaq_score:.1f}", True, (255, 255, 255)
        )
        self.screen.blit(iaq_text, (30, 170))

        temp_text = self.font_small.render(
            f"Temp: {reading.temperature_c:.1f} C", True, (255, 255, 255)
        )
        hum_text = self.font_small.render(
            f"Humidity: {reading.humidity_pct:.1f} %", True, (255, 255, 255)
        )
        pres_text = self.font_small.render(
            f"Pressure: {reading.pressure_hpa:.1f} hPa", True, (255, 255, 255)
        )
        gas_text = self.font_small.render(
            f"Gas: {reading.gas_ohms:.0f} ohms", True, (255, 255, 255)
        )
        tvoc_text = self.font_small.render(
            f"TVOC est: {reading.tvoc_ppb} ppb", True, (255, 255, 255)
        )

        self.screen.blit(temp_text, (30, 230))
        self.screen.blit(hum_text, (30, 265))
        self.screen.blit(pres_text, (30, 300))

        if self.show_detail:
            self.screen.blit(gas_text, (30, 335))
            self.screen.blit(tvoc_text, (30, 370))

        info = self.font_small.render(
            "Tap left: details  |  Tap right: acknowledge 60 s",
            True,
            (255, 255, 255),
        )
        self.screen.blit(info, (20, 440))

        if alarm_active:
            banner = pygame.Rect(500, 20, 260, 90)
            pygame.draw.rect(self.screen, (255, 230, 230), banner, border_radius=12)
            msg1 = self.font_med.render("VENTILATE ROOM", True, (120, 0, 0))
            msg2 = self.font_small.render(
                f"Threshold {alarm_threshold} ppm exceeded", True, (120, 0, 0)
            )
            self.screen.blit(msg1, (520, 35))
            self.screen.blit(msg2, (520, 75))

        pygame.display.flip()

    def handle_event(self, event: pygame.event.Event) -> None:
        if event.type == pygame.MOUSEBUTTONDOWN:
            x, _y = event.pos
            if x < self.width // 2:
                self.show_detail = not self.show_detail
            else:
                self.alarm_ack_until = time.time() + 60.0


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Touchscreen CO2 air-quality alarm")
    parser.add_argument("--mock", action="store_true", help="Run without hardware")
    parser.add_argument(
        "--i2c-addr",
        default="0x76",
        help="BME680 I2C address such as 0x76 or 0x77",
    )
    parser.add_argument(
        "--alarm-ppm",
        type=int,
        default=1200,
        help="Estimated eCO2 alarm threshold",
    )
    parser.add_argument(
        "--interval",
        type=float,
        default=2.0,
        help="Seconds between sensor updates",
    )
    return parser.parse_args()


def main() -> int:
    args = parse_args()
    i2c_addr = int(args.i2c_addr, 16)

    sensor = MockBME680Adapter() if args.mock else BME680Adapter(i2c_addr=i2c_addr)
    sensor.open()

    ui = HyperPixelUI()
    last_read = 0.0
    reading: Optional[SensorReading] = None
    running = True

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            ui.handle_event(event)

        now = time.time()
        if reading is None or (now - last_read) >= args.interval:
            reading = sensor.read()
            last_read = now

        if reading is not None:
            ui.draw(reading, args.alarm_ppm)

        time.sleep(0.05)

    pygame.quit()
    return 0


if __name__ == "__main__":
    sys.exit(main())

test_logic.py

#!/usr/bin/env python3

import air_quality_alarm as app


def run() -> None:
    assert app.clamp(5, 0, 10) == 5
    assert app.clamp(-1, 0, 10) == 0
    assert app.clamp(11, 0, 10) == 10

    iaq_good = app.estimate_iaq_score(40.0, 50000.0)
    iaq_bad = app.estimate_iaq_score(70.0, 10000.0)
    assert iaq_good <= iaq_bad

    eco2_good = app.estimate_eco2_ppm(iaq_good, 50000.0)
    eco2_bad = app.estimate_eco2_ppm(iaq_bad, 10000.0)
    assert eco2_good < eco2_bad

    assert app.air_quality_state(700)[0] == "GOOD"
    assert app.air_quality_state(900)[0] == "ELEVATED"
    assert app.air_quality_state(1300)[0] == "POOR"
    assert app.air_quality_state(1800)[0] == "ALARM"

    mock = app.MockBME680Adapter()
    mock.open()
    reading = mock.read()
    assert 0 <= reading.iaq_score <= 500
    assert 400 <= reading.eco2_ppm <= 2500
    assert reading.pressure_hpa > 800

    print("logic tests passed")


if __name__ == "__main__":
    run()

Guarda los archivos

cd ~/projects/touchscreen-co2-air-quality-alarm
chmod 700 .
nano air_quality_alarm.py
nano test_logic.py
chmod +x air_quality_alarm.py test_logic.py

Pasos de validación

1. Validar sintaxis

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 -m py_compile air_quality_alarm.py test_logic.py

Evidencia esperada:

  • Sin salida de py_compile

2. Validar pruebas lógicas

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 test_logic.py

Evidencia esperada:

logic tests passed

3. Validar modo simulado

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --mock --alarm-ppm 1200 --interval 1.5

Evidencia esperada:

  • Se abre una ventana de aproximadamente 800 x 480
  • Los valores se actualizan cada pocos segundos
  • El color de fondo cambia a medida que la habitación simulada empeora
  • Hacer clic en la mitad izquierda alterna los detalles
  • Hacer clic en la mitad derecha reconoce la alarma durante 60 segundos
  • Tras suficiente tiempo simulado, aparece el banner VENTILATE ROOM

4. Validar modo con sensor real

Si el sensor está en 0x76:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --alarm-ppm 1200 --interval 2.0

Si el sensor está en 0x77:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --i2c-addr 0x77 --alarm-ppm 1200 --interval 2.0

Evidencia esperada:

  • La temperatura es plausible para la habitación
  • La humedad es plausible para la habitación
  • La presión está en un rango atmosférico normal
  • La resistencia del gas es distinta de cero
  • La pantalla táctil se actualiza continuamente

5. Validación práctica en una habitación

Para validar el objetivo principal del tutorial, prueba el dispositivo en una habitación real:

  1. Coloca el dispositivo en una habitación pequeña y cerrada
  2. Deja la puerta y las ventanas cerradas durante un tiempo
  3. Observa si la tendencia del eCO2 estimado sube con el tiempo
  4. Abre una puerta o ventana
  5. Observa si la tendencia mostrada empieza a mejorar en las actualizaciones posteriores

Evidencia esperada:

  • El estado es fácil de interpretar en pantalla
  • La alarma visible aparece cuando se supera el umbral estimado configurado
  • Los cambios de ventilación producen un cambio de tendencia visible

Esto valida el prototipo como un recordatorio educativo para habitaciones basado en tendencias, no como un medidor de CO2 certificado.

Comandos de ejecución

Modo simulado:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --mock --alarm-ppm 1200 --interval 1.5

Modo con hardware real y dirección predeterminada:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --alarm-ppm 1200 --interval 2.0

Modo con hardware real y dirección alternativa:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --i2c-addr 0x77 --alarm-ppm 1200 --interval 2.0

Script lanzador opcional

cat > ~/projects/touchscreen-co2-air-quality-alarm/run.sh << 'EOF'
#!/bin/sh
set -eu
cd "$HOME/projects/touchscreen-co2-air-quality-alarm"
. .venv/bin/activate
exec python3 air_quality_alarm.py --alarm-ppm 1200 --interval 2.0
EOF
chmod +x ~/projects/touchscreen-co2-air-quality-alarm/run.sh

Resolución de problemas

El sensor no es visible en i2cdetect

Vuelve a comprobar:

  • I2C habilitado en raspi-config
  • Alimentación correcta de 3.3 V
  • SDA y SCL no están intercambiados
  • Conexión de tierra sólida
  • Dirección 0x76 frente a 0x77

Comandos útiles:

i2cdetect -y 1
python3 air_quality_alarm.py --i2c-addr 0x77

Errores de importación

Activa el entorno virtual y reinstala:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 -m pip install pygame smbus2 bme680

La interfaz no aparece en la HyperPixel

Comprueba:

  • La HyperPixel es la pantalla activa del escritorio
  • Estás ejecutando desde una sesión de escritorio local, no desde una shell SSH sin interfaz
  • Los controladores de pantalla y táctil están instalados correctamente

Los valores parecen irreales

Posibles razones:

  • Tiempo de calentamiento del sensor
  • Corrientes de aire directas o calor corporal cerca
  • Umbral demasiado agresivo para tu habitación

Prueba un umbral de alarma más alto:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --alarm-ppm 1400 --interval 2.0

Para un comportamiento más estricto:

cd ~/projects/touchscreen-co2-air-quality-alarm
. .venv/bin/activate
python3 air_quality_alarm.py --alarm-ppm 1000 --interval 2.0

Lista de comprobación final

  • [ ] Raspberry Pi 4 Model B está ejecutando Raspberry Pi OS Bookworm de 64 bits
  • [ ] Python 3.11 está instalado
  • [ ] HyperPixel 4.0 Touch muestra el escritorio y acepta entrada táctil
  • [ ] El BME680 está cableado correctamente a 3.3 V, GND, SDA y SCL
  • [ ] i2cdetect -y 1 muestra el sensor en 0x76 o 0x77
  • [ ] El entorno virtual está creado
  • [ ] Las dependencias se instalan correctamente
  • [ ] python3 -m py_compile air_quality_alarm.py test_logic.py se ejecuta correctamente
  • [ ] python3 test_logic.py imprime logic tests passed
  • [ ] El modo simulado abre la interfaz y muestra valores cambiantes
  • [ ] El toque en el lado izquierdo alterna las métricas detalladas
  • [ ] El toque en el lado derecho reconoce la alarma durante 60 segundos
  • [ ] El modo real muestra valores del sensor en vivo
  • [ ] La alarma visible aparece cuando se cruza el umbral estimado
  • [ ] Los cambios de ventilación causan un cambio de tendencia visible

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é modelo de Raspberry Pi se utiliza para construir el panel de calidad del aire según el texto?




Pregunta 2: ¿Qué sensor específico se menciona para medir las condiciones de la habitación?




Pregunta 3: ¿Qué pantalla se utiliza en el proyecto para mostrar las condiciones en vivo?




Pregunta 4: ¿Qué parámetros estima el sensor BME680 en tiempo real según el texto?




Pregunta 5: ¿Cuándo muestra la interfaz una alarma clara en pantalla?




Pregunta 6: ¿Cuál es un ejemplo de umbral configurable para la alarma de eCO2 mencionado en el texto?




Pregunta 7: ¿Para qué caso de uso se menciona un recordatorio de ventilación?




Pregunta 8: ¿Qué permite detectar el indicador en un taller o sala de hobbies?




Pregunta 9: ¿Cómo se muestra el estado en la pantalla para las salas de reuniones?




Pregunta 10: ¿Qué característica tiene la interfaz que se ejecuta localmente?




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