Crea tu Sistema de Monitoreo de Calidad del Aire con Raspberry Pi y Sensores: Respira Mejor
Este tutorial te guiará paso a paso en la creación de un sistema de monitoreo de calidad del aire utilizando una Raspberry Pi. Aprenderás a conectar sensores de partículas, gases y temperatura, y a programar la Raspberry Pi para recolectar y visualizar los datos. Mejora tu entorno y cuida tu salud con datos precisos.
🌬️ Introducción al Monitoreo de Calidad del Aire con Raspberry Pi
La calidad del aire que respiramos es crucial para nuestra salud y bienestar. Contaminantes como las partículas finas (PM2.5, PM10), los gases tóxicos (CO, NO2, O3) y el dióxido de carbono (CO2) pueden tener efectos adversos significativos a corto y largo plazo. Saber qué hay en el aire de nuestro hogar u oficina nos permite tomar medidas proactivas para mejorarlo, ya sea ventilando, usando purificadores o identificando fuentes de contaminación.
Tradicionalmente, los dispositivos de monitoreo de calidad del aire pueden ser costosos y no siempre ofrecen la flexibilidad o la granularidad de datos que un sistema DIY puede proporcionar. Aquí es donde entra en juego la versátil Raspberry Pi. Al combinar su capacidad de procesamiento con una variedad de sensores de bajo costo, podemos construir un sistema de monitoreo personalizado, eficiente y educativo.
Este tutorial te equipará con el conocimiento y los pasos necesarios para construir tu propio sistema de monitoreo de calidad del aire. No solo recopilarás datos importantes, sino que también aprenderás sobre electrónica, programación en Python y la importancia de un ambiente saludable. ¡Prepárate para respirar más tranquilo con tu Raspberry Pi!
🎯 Objetivos del Proyecto
Al finalizar este tutorial, serás capaz de:
- Entender la importancia de monitorear la calidad del aire.
- Conectar varios tipos de sensores a tu Raspberry Pi.
- Programar la Raspberry Pi para leer datos de los sensores.
- Almacenar y visualizar los datos recopilados.
- Crear un sistema de monitoreo funcional y personalizable.
🛠️ Materiales Necesarios
Para llevar a cabo este proyecto, necesitarás los siguientes componentes. La mayoría son fáciles de conseguir en tiendas de electrónica en línea.
Componentes Electrónicos
- Raspberry Pi: Cualquier modelo moderno (Raspberry Pi 3B+, 4B o Zero 2 W) será suficiente. Se recomienda la Raspberry Pi 4B por su mayor potencia y conectividad.
- Tarjeta microSD: De 16 GB o más, con Raspberry Pi OS instalado.
- Fuente de alimentación para Raspberry Pi: Adaptador USB-C (para Pi 4) o Micro USB (para Pi 3/Zero).
- Sensor de partículas PM2.5/PM10: Un SDS011 o PMS5003 son excelentes opciones. Este tutorial se centrará en el SDS011 por su popularidad y facilidad de uso.
- Sensor de Calidad del Aire y Gas: Un MQ-135 es una opción común para detectar una amplia gama de gases tóxicos (benceno, alcohol, CO2, amoniaco, etc.).
- Sensor de Temperatura y Humedad: Un DHT11 o DHT22. El DHT22 ofrece mayor precisión.
- Resistencia: De 10k ohmios (para el DHT11/DHT22).
- Protoboard (Breadboard): Para facilitar las conexiones.
- Cables Jumper: Macho-hembra y macho-macho.
- Opcional: Pequeña pantalla LCD (como un I2C 16x2) para mostrar datos localmente.
Herramientas y Software
- Ordenador con lector de tarjetas microSD.
- Acceso a internet.
- Terminal SSH (opcional, pero recomendado para trabajar con la Raspberry Pi sin monitor).
- Conocimientos básicos de Python.
Lista de la compra
| Componente | Descripción | Cantidad | Enlace de Ejemplo (genérico) |
|---|---|---|---|
| --- | --- | --- | --- |
| Raspberry Pi | Modelo 3B+, 4B o Zero 2 W | 1 | Ver en Amazon |
| Tarjeta microSD | 16GB o más, clase 10 | 1 | Ver en Amazon |
| --- | --- | --- | --- |
| Fuente de alimentación | 5V, 3A (o 2.5A para Pi 3) | 1 | Ver en Amazon |
| Sensor SDS011 | Sensor de partículas PM2.5/PM10 | 1 | Ver en Amazon |
| --- | --- | --- | --- |
| Sensor MQ-135 | Sensor de calidad de aire/gas | 1 | Ver en Amazon |
| Sensor DHT22 | Temperatura y Humedad | 1 | Ver en Amazon |
| --- | --- | --- | --- |
| Resistencia | 10k Ohm | 1 | Ver en Amazon |
| Protoboard | 400 puntos | 1 | Ver en Amazon |
| --- | --- | --- | --- |
| Cables Jumper | Macho-Hembra y Macho-Macho | 1 paquete | Ver en Amazon |
⚙️ Preparación de la Raspberry Pi
Asegúrate de que tu Raspberry Pi esté lista antes de empezar con los sensores.
1. Instalación de Raspberry Pi OS
Si aún no lo has hecho, instala la última versión de Raspberry Pi OS (recomendado Raspberry Pi OS Lite para un proyecto sin interfaz gráfica). Puedes usar Raspberry Pi Imager para esto.
2. Actualización del Sistema
Una vez que hayas arrancado tu Raspberry Pi, actualiza los paquetes del sistema:
sudo apt update
sudo apt full-upgrade -y
3. Habilitar la Interfaz Serial (UART) para SDS011
El sensor SDS011 se comunica a través de la interfaz serial (UART). Necesitamos asegurarnos de que esté habilitada y configurada correctamente. Ejecuta sudo raspi-config:
- Selecciona
3 Interface Options. - Selecciona
P6 Serial Port. - Cuando te pregunte
Would you like a login shell to be accessible over serial?, seleccionaNo. - Cuando te pregunte
Would you like the serial port hardware to be enabled?, seleccionaYes. - Reinicia tu Raspberry Pi.
4. Instalar Librerías Python Necesarias
Instalaremos las librerías para interactuar con los sensores. Para los sensores DHT, usaremos la librería Adafruit_DHT. Para el SDS011, usaremos una librería específica y para el MQ-135, lo leeremos directamente a través de GPIO.
sudo apt install python3-pip -y
pip3 install adafruit-circuitpython-dht
sudo apt install libgpiod2 -y # Dependencia para adafruit-circuitpython-dht
pip3 install sds011 # Librería para el sensor SDS011
Para el MQ-135 (y otros sensores MQ), que son analógicos, necesitaremos un convertidor analógico-digital (ADC) como el MCP3008 si tu Raspberry Pi no tiene pines ADC. Sin embargo, para simplificar, muchos tutoriales y proyectos de hobby conectan los MQ directamente a una entrada digital para detectar un umbral, o a un convertidor ADC para lecturas más precisas. En este tutorial, asumiremos la conexión directa a un GPIO para una lectura digital básica de presencia de gases por encima de un umbral para empezar. Si deseas lecturas analógicas más precisas, deberás añadir un MCP3008 y adaptar el código. Por simplicidad, leeremos el pin digital DO del MQ-135 si lo conectas de esa forma.
Consideración del MQ-135: El MQ-135 tiene pines AO (Analog Out) y DO (Digital Out). El pin DO proporciona una señal HIGH/LOW basada en un umbral ajustable con un potenciómetro en la placa del sensor. Esto es útil para detectar la presencia de gases por encima de un nivel. Si necesitas lecturas cuantitativas (ppm), necesitarás un ADC (como el MCP3008) para leer el pin AO, lo cual añade complejidad. Para este tutorial inicial, nos centraremos en la lectura digital del pin DO para detectar umbrales de gases.
🔌 Conexión de los Sensores a la Raspberry Pi
¡Es hora de conectar los componentes! Asegúrate de que tu Raspberry Pi esté apagada antes de realizar cualquier conexión física para evitar daños.
1. Conexión del Sensor SDS011 (Partículas PM2.5/PM10)
El SDS011 se conecta a través de UART.
- VCC (SDS011) a 5V (Raspberry Pi, Pin 2 o 4)
- GND (SDS011) a GND (Raspberry Pi, Pin 6, 9, 14, etc.)
- TX (SDS011) a RXD (GPIO15) (Raspberry Pi, Pin 10)
- RX (SDS011) a TXD (GPIO14) (Raspberry Pi, Pin 8)
2. Conexión del Sensor DHT22 (Temperatura y Humedad)
El DHT22 es un sensor de un solo cable digital. Necesita una resistencia pull-up.
- VCC (DHT22) a 3.3V (Raspberry Pi, Pin 1)
- GND (DHT22) a GND (Raspberry Pi, Pin 6, 9, 14, etc.)
- Data (DHT22) a GPIO4 (Raspberry Pi, Pin 7)
- Conecta una resistencia de 10k Ohm entre VCC y Data del DHT22.
3. Conexión del Sensor MQ-135 (Calidad del Aire / Gas)
Para una lectura digital simple de umbral (pin DO):
- VCC (MQ-135) a 5V (Raspberry Pi, Pin 2 o 4)
- GND (MQ-135) a GND (Raspberry Pi, Pin 6, 9, 14, etc.)
- DO (MQ-135) a GPIO23 (Raspberry Pi, Pin 16)
💻 Programación en Python para Recopilar Datos
Ahora vamos a escribir el código Python para leer los datos de cada sensor.
1. Script para el Sensor SDS011
Crea un archivo llamado read_sds011.py:
import sds011
import time
def read_sds011_data():
try:
# El puerto serial es /dev/ttyS0 para Raspberry Pi
sensor = sds011.SDS011('/dev/ttyS0', use_calibration=True)
# Establecer modo de consulta (activo)
# sensor.set_working_period(0)
# Esperar un momento para que el sensor se estabilice
time.sleep(2)
pm25, pm10 = sensor.query() # Consulta una vez
# pm25, pm10 = sensor.read() # Lee si está en modo activo
# Para apagar el ventilador entre lecturas y prolongar la vida útil del sensor
# sensor.sleep()
return pm25, pm10
except Exception as e:
print(f"Error al leer SDS011: {e}")
return None, None
if __name__ == '__main__':
print("Leyendo datos del sensor SDS011...")
pm25, pm10 = read_sds011_data()
if pm25 is not None and pm10 is not None:
print(f"PM2.5: {pm25} ug/m3")
print(f"PM10: {pm10} ug/m3")
else:
print("No se pudieron obtener datos del SDS011.")
Ejecuta el script: python3 read_sds011.py
2. Script para el Sensor DHT22
Crea un archivo llamado read_dht22.py:
import adafruit_dht
import board
import time
def read_dht22_data():
dht_device = adafruit_dht.DHT22(board.D4) # Conectado a GPIO4
try:
temperature_c = dht_device.temperature
humidity = dht_device.humidity
if temperature_c is not None and humidity is not None:
temperature_f = temperature_c * (9 / 5) + 32
return temperature_c, temperature_f, humidity
else:
print("Fallo al obtener lectura del DHT22. Intentando de nuevo...")
return None, None, None
except RuntimeError as error:
# Errores de lectura son comunes con el DHT, reintentar puede ser necesario.
print(f"Error de lectura DHT22: {error.args[0]}")
return None, None, None
except Exception as error:
dht_device.exit()
raise error
if __name__ == '__main__':
print("Leyendo datos del sensor DHT22...")
temp_c, temp_f, hum = read_dht22_data()
if temp_c is not None:
print(f"Temperatura: {temp_c:.1f} C / {temp_f:.1f} F")
print(f"Humedad: {hum:.1f} %")
else:
print("No se pudieron obtener datos del DHT22.")
Ejecuta el script: python3 read_dht22.py
3. Script para el Sensor MQ-135 (Lectura Digital)
Para leer el pin DO del MQ-135, usaremos RPi.GPIO.
Crea un archivo llamado read_mq135.py:
import RPi.GPIO as GPIO
import time
MQ135_DO_PIN = 23 # Conectado a GPIO23
def setup_mq135():
GPIO.setmode(GPIO.BCM)
GPIO.setup(MQ135_DO_PIN, GPIO.IN)
def read_mq135_data():
# El pin DO es LOW cuando se detecta gas (por encima del umbral)
# y HIGH cuando no hay gas (o está por debajo del umbral).
# La lógica puede variar; a menudo es inversa. Asumimos LOW = Gas detectado.
if GPIO.input(MQ135_DO_PIN) == GPIO.LOW:
return "Gas detectado (nivel alto)"
else:
return "Sin gas detectado (nivel bajo)"
if __name__ == '__main__':
setup_mq135()
try:
print("Leyendo datos del sensor MQ-135 (Digital)...")
# Dar tiempo al sensor para precalentarse y estabilizarse
print("Esperando 60 segundos para estabilización inicial del MQ-135...")
time.sleep(60)
while True:
status = read_mq135_data()
print(f"Estado del MQ-135: {status}")
time.sleep(5)
except KeyboardInterrupt:
print("Saliendo del programa.")
finally:
GPIO.cleanup()
Ejecuta el script: python3 read_mq135.py. Ajusta el potenciómetro en la placa del MQ-135 para calibrar el umbral de detección digital.
📊 Consolidación y Almacenamiento de Datos
Para que nuestro sistema sea útil, necesitamos un script principal que lea todos los sensores y almacene los datos. Usaremos un archivo CSV simple para el almacenamiento local.
1. Script Principal de Monitoreo
Crea un archivo llamado air_monitor.py:
import sds011
import adafruit_dht
import board
import RPi.GPIO as GPIO
import time
import csv
from datetime import datetime
# --- Configuración de Pines y Sensores ---
# SDS011
SDS011_SERIAL_PORT = '/dev/ttyS0'
# DHT22
DHT_PIN = board.D4 # GPIO4
dht_device = adafruit_dht.DHT22(DHT_PIN)
# MQ-135
MQ135_DO_PIN = 23 # GPIO23
# --- Archivo de Datos ---
CSV_FILE = 'air_quality_data.csv'
def init_mq135():
GPIO.setmode(GPIO.BCM)
GPIO.setup(MQ135_DO_PIN, GPIO.IN)
def write_header_if_not_exists():
try:
with open(CSV_FILE, 'x', newline='') as f:
writer = csv.writer(f)
writer.writerow([
'timestamp',
'temperature_c',
'humidity',
'pm25',
'pm10',
'gas_detected'
])
except FileExistsError:
pass # El archivo ya existe, no hacemos nada
def read_all_sensors():
timestamp = datetime.now().isoformat()
temp_c, humidity, pm25, pm10, gas_status = None, None, None, None, None
# Leer DHT22
try:
temp_c = dht_device.temperature
humidity = dht_device.humidity
if temp_c is None or humidity is None:
print("DHT22: Error de lectura. Reintentando en el siguiente ciclo.")
temp_c, humidity = None, None
except RuntimeError as error:
print(f"DHT22: Error de lectura: {error.args[0]}")
except Exception as e:
print(f"DHT22: Error inesperado: {e}")
# Leer SDS011
try:
sds_sensor = sds011.SDS011(SDS011_SERIAL_PORT, use_calibration=True)
sds_sensor.set_working_period(1) # Activar sensor por 1 minuto
time.sleep(10) # Dar tiempo para que el ventilador arranque y se estabilice
pm25, pm10 = sds_sensor.query()
sds_sensor.sleep() # Poner en modo de bajo consumo
except Exception as e:
print(f"SDS011: Error al leer: {e}")
pm25, pm10 = None, None
# Leer MQ-135
try:
if GPIO.input(MQ135_DO_PIN) == GPIO.LOW:
gas_status = "Detectado"
else:
gas_status = "No Detectado"
except Exception as e:
print(f"MQ-135: Error al leer: {e}")
gas_status = None
return {
'timestamp': timestamp,
'temperature_c': temp_c,
'humidity': humidity,
'pm25': pm25,
'pm10': pm10,
'gas_detected': gas_status
}
def save_data(data):
with open(CSV_FILE, 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow([
data['timestamp'],
data['temperature_c'],
data['humidity'],
data['pm25'],
data['pm10'],
data['gas_detected']
])
if __name__ == '__main__':
init_mq135()
write_header_if_not_exists()
print(f"Sistema de monitoreo de calidad del aire iniciado. Datos guardados en {CSV_FILE}")
print("Permite al MQ-135 un tiempo de precalentamiento para lecturas estables.")
try:
while True:
print("\n--- Realizando lectura de sensores ---")
sensor_data = read_all_sensors()
print(f"Datos recopilados: {sensor_data}")
save_data(sensor_data)
print(f"Datos guardados. Siguiente lectura en 5 minutos.")
time.sleep(300) # Leer cada 5 minutos
except KeyboardInterrupt:
print("\nDeteniendo el monitoreo.")
finally:
dht_device.exit() # Limpiar el sensor DHT
GPIO.cleanup() # Limpiar pines GPIO
2. Ejecución y Persistencia
Ejecuta el script principal:
python3 air_monitor.py
Para que el script se ejecute automáticamente al iniciar la Raspberry Pi, puedes usar cron:
crontab -e
Añade la siguiente línea al final del archivo para ejecutar el script cada vez que la Pi se inicie (y en caso de un reinicio inesperado).
@reboot python3 /home/pi/air_monitor.py > /home/pi/air_monitor.log 2>&1
📈 Visualización de Datos (Opcional pero Recomendado)
Ver los datos en un archivo CSV es funcional, pero una visualización gráfica es mucho más útil. Hay varias opciones, desde una sencilla gráfica en Python hasta plataformas más robustas.
1. Gráficas Sencillas con Matplotlib
Si quieres una visualización rápida, puedes usar Matplotlib para generar gráficos desde el CSV. Primero, instala Matplotlib:
pip3 install matplotlib pandas
Crea un script plot_data.py:
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
CSV_FILE = 'air_quality_data.csv'
def plot_air_quality():
try:
df = pd.read_csv(CSV_FILE)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.set_index('timestamp')
plt.figure(figsize=(15, 10))
# Temperatura y Humedad
plt.subplot(3, 1, 1)
plt.plot(df.index, df['temperature_c'], label='Temperatura (°C)', color='red')
plt.plot(df.index, df['humidity'], label='Humedad (%)', color='blue')
plt.title('Temperatura y Humedad')
plt.ylabel('Valor')
plt.legend()
plt.grid(True)
# Partículas PM2.5 y PM10
plt.subplot(3, 1, 2)
plt.plot(df.index, df['pm25'], label='PM2.5 (ug/m3)', color='purple')
plt.plot(df.index, df['pm10'], label='PM10 (ug/m3)', color='orange')
plt.title('Concentración de Partículas PM2.5 y PM10')
plt.ylabel('Concentración (ug/m3)')
plt.legend()
plt.grid(True)
# Estado del Gas (simplificado)
plt.subplot(3, 1, 3)
# Convertimos 'Detectado' a 1 y 'No Detectado' a 0 para graficar
df['gas_detected_numeric'] = df['gas_detected'].apply(lambda x: 1 if x == 'Detectado' else 0)
plt.plot(df.index, df['gas_detected_numeric'], label='Gas Detectado (1=Sí, 0=No)', drawstyle='steps-post', color='green')
plt.yticks([0, 1], ['No Detectado', 'Detectado'])
plt.title('Detección de Gas (MQ-135)')
plt.xlabel('Tiempo')
plt.ylabel('Estado')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.savefig('air_quality_report.png')
print("Gráfico 'air_quality_report.png' generado exitosamente.")
except FileNotFoundError:
print(f"Error: El archivo {CSV_FILE} no fue encontrado. Asegúrate de que el script de monitoreo se haya ejecutado.")
except Exception as e:
print(f"Error al generar el gráfico: {e}")
if __name__ == '__main__':
plot_air_quality()
Para generar el gráfico, ejecuta: python3 plot_data.py. Esto creará un archivo air_quality_report.png en el mismo directorio.
2. Opciones Avanzadas de Visualización
Para soluciones más robustas y con acceso desde cualquier lugar, considera integrar tus datos con:
- Grafana + InfluxDB: Una combinación potente para almacenamiento de series temporales y visualización de paneles interactivos.
- Node-RED: Una herramienta de programación visual para conectar dispositivos y servicios, ideal para dashboards sencillos.
- Servicios en la nube: AWS IoT, Google Cloud IoT, o Adafruit IO para enviar datos y visualizarlos en la web.
¿Por qué usar InfluxDB y Grafana?
InfluxDB es una base de datos de series temporales optimizada para almacenar datos que cambian con el tiempo, como las lecturas de sensores. Grafana es una plataforma de código abierto para monitoreo y observabilidad, que permite crear dashboards interactivos y personalizables a partir de diversas fuentes de datos, incluyendo InfluxDB. Juntos, ofrecen una solución muy potente para visualizar datos históricos y en tiempo real de tu sistema de monitoreo de calidad del aire.✅ Mantenimiento y Calibración
Un sistema de monitoreo requiere algo de atención para asegurar la precisión de sus lecturas.
Limpieza de Sensores
- SDS011: El ventilador y la cámara de sensado pueden acumular polvo. Ocasionalmente, usa aire comprimido suavemente para limpiar las entradas y salidas de aire.
- DHT22: Generalmente no requiere limpieza, pero asegúrate de que no haya acumulación de polvo en su superficie.
- MQ-135: Mantén el sensor libre de obstrucciones y polvo. Si se expone a gases de muy alta concentración, puede que necesite un tiempo para 'limpiarse' y volver a dar lecturas estables.
Calibración
- SDS011: Los fabricantes de sensores de partículas asequibles a menudo mencionan que tienen cierta variabilidad. Puedes comparar sus lecturas con estaciones de monitoreo profesionales cercanas a tu ubicación para entender su precisión y aplicar un factor de corrección si es necesario.
- DHT22: Estos sensores suelen venir precalibrados y son razonablemente precisos para aplicaciones domésticas. Si sospechas una gran desviación, puedes compararlo con un termómetro/higrómetro de referencia.
- MQ-135: Este sensor es más complejo de calibrar para obtener valores exactos en partes por millón (ppm) sin equipo especializado. Para este proyecto, nos centramos en su capacidad de detectar la presencia de gases por encima de un umbral. Puedes ajustar el potenciómetro en la placa del MQ-135 para cambiar la sensibilidad del pin digital 'DO' y así controlar el umbral de detección. Para una calibración más rigurosa para valores cuantitativos, necesitarías un entorno con concentraciones de gas conocidas y un ADC.
💡 Posibles Mejoras y Expansiones Futuras
Este es solo el comienzo. Tu sistema de monitoreo puede crecer contigo:
- Notificaciones: Envía alertas por correo electrónico, Telegram o SMS cuando los niveles de contaminación excedan un umbral.
- Integración con Hogar Inteligente: Usa los datos para activar purificadores de aire, abrir ventanas automáticas o controlar sistemas de ventilación a través de Home Assistant o IFTTT.
- Más Sensores: Añade sensores específicos para CO (MQ-7), NO2, O3, CO2 (MH-Z19B), formaldehído, etc., para un monitoreo más completo.
- Panel Web Local: Desarrolla una interfaz web simple con Flask o Django para ver los datos en tiempo real desde cualquier dispositivo en tu red local.
- Batería: Haz el sistema portátil añadiendo una batería y un módulo de carga.
Este proyecto te proporciona una base sólida para entender y mejorar la calidad del aire en tu entorno. ¡Experimenta, personaliza y hazlo tuyo!
Tutoriales relacionados
- Estación Meteorológica DIY: Monitoreando el Clima con Raspberry Pi y Sensoresintermediate20 min
- Crea tu Propio Servidor VPN WireGuard con Raspberry Pi: Accede de Forma Segura a tu Red Domésticaintermediate20 min
- Crea tu Propia Consola Retro con Raspberry Pi y RetroPie: ¡Revive los Clásicos!beginner15 min
- Automatiza tu Hogar: Control de Luces Inteligentes con Raspberry Pi y Pythonintermediate25 min
- Crea tu Propio Servidor de Almacenamiento NAS con Raspberry Pi y OpenMediaVaultintermediate20 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!