Objetivo y caso de uso
Lo que construirás: Un controlador con Raspberry Pi que lee la concentración de CO2 desde un sensor UART MH-Z19B y conmuta un relé para iniciar o detener un ventilador de ventilación según umbrales de ppm configurables. En una configuración típica, la Pi consulta el sensor cada 1–2 segundos, acciona el relé con un tiempo de respuesta GPIO inferior a 100 ms y usa recursos de cómputo insignificantes (<5% CPU, 0% GPU).
Por qué importa / Casos de uso
- Automatizar el control de la calidad del aire en una oficina en casa, aula, taller o sala de reuniones cuando el CO2 supera niveles como 1000–1200 ppm.
- Reducir el tiempo de funcionamiento innecesario del ventilador apagando la ventilación cuando el CO2 cae por debajo de un umbral inferior, por ejemplo 800 ppm, para evitar el traqueteo del relé y ahorrar energía.
- Aprender de forma práctica la interacción de Raspberry Pi con sensores UART, el control de relés por GPIO, la lógica de umbrales y la automatización ambiental básica.
- Crear una base para ampliaciones como registrar tendencias de ppm, añadir alertas o publicar datos en un panel.
Resultado esperado
- Lecturas estables de CO2 desde el MH-Z19B por UART, normalmente actualizadas cada 1–2 segundos.
- Conmutación fiable del relé cuando el CO2 cruza los umbrales definidos, con una latencia de activación GPIO normalmente inferior a 100 ms después de procesar una nueva lectura.
- Un bucle de control simple basado en histéresis, por ejemplo relé ENCENDIDO por encima de 1000 ppm y APAGADO por debajo de 800 ppm, para evitar conmutaciones rápidas.
- Un servicio ligero siempre activo adecuado para Raspberry Pi, que normalmente consume una carga mínima del sistema (<5% CPU, 0% GPU, sin requisito de FPS).
Público: principiantes de Raspberry Pi, makers y estudiantes que construyen automatización ambiental; Nivel: Básico
Arquitectura/flujo: Sensor de CO2 MH-Z19B → lectura UART en Raspberry Pi → lógica de umbral/histéresis → salida GPIO → módulo de relé aislado → ventilador de ventilación o carga de prueba de bajo voltaje
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: 3 apartados, 3 tablas y 7 bloques de código detectados antes de publicar.
- Código comprobado: 1 Python/py_compile, 6 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
Nota de seguridad
Este proyecto conmuta equipos de ventilación alimentados por la red eléctrica mediante un relé. Usa un módulo de relé con aislamiento adecuado, sigue las normas eléctricas locales y mantén el cableado de red físicamente separado del cableado de bajo voltaje de la Raspberry Pi. Si no estás cualificado para trabajar con corriente alterna de red, usa el relé solo para accionar una carga de prueba de bajo voltaje como un módulo LED o pide a un electricista cualificado que conecte el ventilador.
title: Caso práctico de Raspberry Pi: controlador de relé de ventilación basado en CO2
slug: practical-case-raspberry-pi
level: Básico
device: Raspberry Pi
objective: co2-ventilation-relay-controller
Controlador de relé de ventilación por CO2 con Raspberry Pi
Este caso práctico muestra cómo construir un controlador de relé de ventilación basado en CO2 en una Raspberry Pi. La Raspberry Pi lee la concentración de CO2 interior desde un sensor UART MH-Z19B y conmuta un relé para habilitar o deshabilitar un ventilador de ventilación cuando el valor medido cruza umbrales definidos.
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
Implementar un controlador de ventilación que:
- Lea ppm de CO2
- Encienda el relé de ventilación cuando el CO2 sea alto
- Apague el relé de ventilación cuando el CO2 baje
- Use histéresis para evitar el traqueteo del relé
- Se ejecute continuamente como un script de servicio simple en Raspberry Pi
Hardware
- Raspberry Pi con cabecera GPIO de 40 pines
- Tarjeta microSD con Raspberry Pi OS
- Sensor de CO2 MH-Z19B
- Módulo de relé de 5 V, 1 canal, compatible con GPIO
- Fuente externa de 5 V para el módulo de relé si la corriente del módulo lo requiere
- Cables jumper
- Opcional: lámpara de bajo voltaje o carga LED para pruebas seguras en banco
Cableado
Mapeo de pines
| Función | Pin del dispositivo | Pin de Raspberry Pi | Notas |
|---|---|---|---|
| 5 V para el sensor | MH-Z19B Vin | Pin 2 (5V) | El sensor requiere 5 V |
| Tierra para el sensor | MH-Z19B GND | Pin 6 (GND) | Tierra común |
| TX del sensor | MH-Z19B TX | Pin 10 (GPIO15 / RXD) | La Pi recibe datos del sensor |
| RX del sensor | MH-Z19B RX | Pin 8 (GPIO14 / TXD) | Opcional para soporte de comandos |
| Entrada del relé | Relay IN | Pin 11 (GPIO17) | Ejemplo activo en bajo en el software |
| VCC del relé | Relay VCC | Fuente de 5 V | Comprueba la especificación del módulo |
| GND del relé | Relay GND | GND de la Pi | Se requiere tierra común |
Notas
- Muchas placas de relé son activas en bajo. El software de abajo asume que llevar GPIO17 a LOW energiza el relé.
- La interfaz UART del MH-Z19B es segura con lógica de 3.3 V en TX hacia RX de la Pi en placas breakout comunes. Verifica tu módulo antes de cablear.
- En Raspberry Pi OS, la consola serie debe estar deshabilitada para que
/dev/serial0quede libre para el sensor.
Habilitar UART en Raspberry Pi
Ejecuta:
sudo raspi-config nonint do_serial_hw 0
sudo raspi-config nonint do_serial_cons 1
sudo reboot
Después de reiniciar, verifica que exista el dispositivo UART:
ls -l /dev/serial0
Instalar dependencias
sudo apt update
sudo apt install -y python3 python3-rpi.gpio
Programa del controlador
Guarda este archivo como co2_ventilation_controller.py.
#!/usr/bin/env python3
import time
import serial
import RPi.GPIO as GPIO
UART_DEVICE = "/dev/serial0"
UART_BAUD = 9600
RELAY_GPIO = 17
RELAY_ACTIVE_LOW = True
CO2_ON_THRESHOLD = 1000 # ppm: turn ventilation ON at or above this level
CO2_OFF_THRESHOLD = 800 # ppm: turn ventilation OFF at or below this level
POLL_INTERVAL_SECONDS = 5.0
def relay_write(enabled: bool) -> None:
if RELAY_ACTIVE_LOW:
GPIO.output(RELAY_GPIO, GPIO.LOW if enabled else GPIO.HIGH)
else:
GPIO.output(RELAY_GPIO, GPIO.HIGH if enabled else GPIO.LOW)
def mhz19_checksum(packet: bytes) -> int:
checksum = 0xFF - (sum(packet[1:8]) % 256) + 1
return checksum & 0xFF
def read_co2_ppm(ser: serial.Serial) -> int:
command = bytes([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
ser.reset_input_buffer()
ser.write(command)
response = ser.read(9)
if len(response) != 9:
raise RuntimeError(f"Incomplete response: got {len(response)} bytes")
if response[0] != 0xFF or response[1] != 0x86:
raise RuntimeError(f"Unexpected response header: {response.hex()}")
if response[8] != mhz19_checksum(response):
raise RuntimeError(f"Checksum error: {response.hex()}")
co2_ppm = response[2] * 256 + response[3]
return co2_ppm
def main() -> None:
GPIO.setmode(GPIO.BCM)
GPIO.setup(RELAY_GPIO, GPIO.OUT)
relay_enabled = False
relay_write(relay_enabled)
print("Starting CO2 ventilation relay controller")
print(f"ON threshold : {CO2_ON_THRESHOLD} ppm")
print(f"OFF threshold: {CO2_OFF_THRESHOLD} ppm")
try:
with serial.Serial(UART_DEVICE, UART_BAUD, timeout=1.0) as ser:
while True:
try:
co2_ppm = read_co2_ppm(ser)
if not relay_enabled and co2_ppm >= CO2_ON_THRESHOLD:
relay_enabled = True
relay_write(relay_enabled)
elif relay_enabled and co2_ppm <= CO2_OFF_THRESHOLD:
relay_enabled = False
relay_write(relay_enabled)
state = "ON" if relay_enabled else "OFF"
print(f"CO2={co2_ppm} ppm, ventilation relay={state}")
except RuntimeError as exc:
print(f"Read error: {exc}")
time.sleep(POLL_INTERVAL_SECONDS)
finally:
relay_write(False)
GPIO.cleanup()
if __name__ == "__main__":
main()
Ejecutar el controlador
python3 co2_ventilation_controller.py
Salida esperada en consola:
CO2=650 ppm, ventilation relay=OFFCO2=1100 ppm, ventilation relay=ON
Opcional: iniciar automáticamente al arrancar
Crea un archivo de unidad systemd:
sudo tee /etc/systemd/system/co2-ventilation.service >/dev/null <<'EOF'
[Unit]
Description=CO2 Ventilation Relay Controller
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/usr/bin/python3 /home/pi/co2_ventilation_controller.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
Habilítalo e inícialo:
sudo systemctl daemon-reload
sudo systemctl enable --now co2-ventilation.service
sudo systemctl status co2-ventilation.service --no-pager
Cómo funciona el control de ventilación
La Raspberry Pi implementa un controlador de ventilación por CO2 simple con histéresis:
| Valor de CO2 | Acción del relé | Estado de la ventilación |
|---|---|---|
>= 1000 ppm | Energizar relé | Ventilación ENCENDIDA |
801 to 999 ppm | Mantener el estado anterior | Estable, sin traqueteo |
<= 800 ppm | Liberar relé | Ventilación APAGADA |
Esto evita conmutaciones rápidas cerca de un único umbral.
Método de validación
Para validar el comportamiento del controlador de relé de ventilación por CO2:
- Alimenta el sensor y el módulo de relé.
- Ejecuta el script Python.
- Observa la salida en vivo en la terminal.
- Expón el sensor a un nivel más alto de CO2, por ejemplo respirando cerca del sensor brevemente en una configuración de prueba ventilada.
- Confirma:
- El valor de CO2 impreso sube por encima de
1000 ppm - El relé de ventilación cambia a
ON - Vuelve a colocar el sensor en aire fresco y espera a que la lectura baje.
- Confirma:
- El valor de CO2 impreso baja a
800 ppmo menos - El relé de ventilación cambia a
OFF
Evidencia esperada
- Registros de terminal que muestren valores de CO2 cruzando ambos umbrales
- Clics audibles del relé o cambio del indicador LED en la placa de relé
- Comprobación opcional de continuidad con multímetro en los contactos del relé
- Flujo de aire opcional o activación del ventilador cuando la salida de ventilación esté conectada
Solución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
Incomplete response | UART no habilitado o dispositivo serie incorrecto | Vuelve a habilitar UART y comprueba /dev/serial0 |
| Errores de checksum constantes | Problema de cableado o desajuste de baudios | Vuelve a comprobar TX/RX y usa 9600 baudios |
| Relé siempre ENCENDIDO | El módulo es activo en bajo | Mantén RELAY_ACTIVE_LOW = True |
| El relé nunca conmuta | Pin GPIO incorrecto o sin tierra común | Verifica el cableado de GPIO17 y GND |
| La lectura de CO2 no cambia | Calentamiento del sensor o mala ubicación | Deja que el sensor se caliente durante varios minutos |
Resultado
Ahora tienes un controlador de relé de ventilación por CO2 para Raspberry Pi funcional que lee un sensor de CO2 y conmuta un relé para controlar la ventilación automáticamente.
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.




