Construye un Monitor de Calidad del Aire con Arduino y Sensor DSM501A
Componentes y materiales
| Arduino Nano R3 | × | 1 |
| Módulo sensor de polvo DSM501A | × | 1 |
| Pantalla LCD alfanumérica 16×2 | × | 1 |
| Kit ventilador 40 mm | × | 1 |
| LED genérico | × | 5 |
| Resistencia 221 Ω | × | 1 |
| Potenciómetro mono-vuelta 10 kΩ | × | 1 |
Herramientas necesarias
- Soldador
Aplicaciones y servicios online
- Arduino IDE
Sobre el proyecto
La monitorización de la calidad del aire es una ciencia consolidada desde los años 80. Entonces la tecnología era limitada, compleja, voluminosa y muy costosa. Hoy, gracias a las tecnologías modernas, las soluciones son más precisas, rápidas, compactas y asequibles.
Este dispositivo usa el sensor Samyoung DSM501A, uno de los más baratos del mercado (unos pocos dólares en AliExpress), capaz de detectar partículas PM2.5 y PM10.
Conexión del circuito
El circuito es muy sencillo:
- Vout1 (PM2.5) → Pin D2 del Arduino
- Vout2 (PM10) → Pin D3 del Arduino
- Vcc → +5V del Arduino
- GND → GND del Arduino
- Los 5 LEDs se conectan a los pines analógicos A1–A5 (configurados como salidas en el código)
La pantalla LCD 16×2 (compatible con Hitachi HD44780) muestra la concentración de PM10 en pcs/0.01 cf y 5 estados de calidad del aire:
- CLEAN (Limpio)
- GOOD (Bueno)
- ACCEPTABLE (Aceptable)
- HEAVY (Cargado)
- HAZARD (Peligroso)
Tanto PM10 como PM2.5 pueden monitorizarse en el monitor serie. Según el nivel de contaminación (PM10), se enciende un LED de color correspondiente para una lectura rápida. La instalación de un ventilador que extrae aire por la salida del sensor mejora notablemente la estabilidad de las lecturas. El conjunto se monta en una caja de instalación eléctrica.
En el futuro planeo probar más sensores de polvo económicos y compartir los resultados.
Código
Código para monitor de calidad del aire Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int pin2 = 3;
int pin1 = 2;
unsigned long duration1, duration2;
unsigned long starttime;
unsigned long sampletime_ms = 3000;
unsigned long lowpulseoccupancy1 = 0;
unsigned long lowpulseoccupancy2 = 0;
float ratio1 = 0, ratio2 = 0;
float concentration1 = 0, concentration2 = 0;
int wLed = A1, gLed = A2, yLed = A3, rLed = A4, bLed = A5;
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(wLed, OUTPUT);
pinMode(gLed, OUTPUT);
pinMode(yLed, OUTPUT);
pinMode(rLed, OUTPUT);
pinMode(bLed, OUTPUT);
starttime = millis();
lcd.begin(16, 2);
}
void loop() {
duration1 = pulseIn(pin1, LOW);
duration2 = pulseIn(pin2, LOW);
lowpulseoccupancy1 += duration1;
lowpulseoccupancy2 += duration2;
if ((millis() - starttime) > sampletime_ms) {
ratio1 = lowpulseoccupancy1 / (sampletime_ms * 10.0);
concentration1 = 1.1 * pow(ratio1, 3) - 3.8 * pow(ratio1, 2) + 520 * ratio1 + 0.62;
ratio2 = lowpulseoccupancy2 / (sampletime_ms * 10.0);
concentration2 = 1.1 * pow(ratio2, 3) - 3.8 * pow(ratio2, 2) + 520 * ratio2 + 0.62;
lcd.setCursor(0, 0);
lcd.print("PM10 ");
lcd.setCursor(6, 0);
lcd.print(concentration1, 3);
Serial.print("concentration1 = ");
Serial.print(concentration1);
Serial.print(" pcs/0.01cf - ");
Serial.print("concentration2 = ");
Serial.print(concentration2);
Serial.print(" pcs/0.01cf - ");
// Lógica de estados y LEDs
if (concentration1 < 1000) {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
lcd.print("CLEAN");
digitalWrite(wLed, HIGH); digitalWrite(gLed, LOW); digitalWrite(yLed, LOW); digitalWrite(rLed, LOW); digitalWrite(bLed, LOW);
}
else if (concentration1 < 10000) {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
lcd.print("GOOD");
digitalWrite(wLed, LOW); digitalWrite(gLed, HIGH); digitalWrite(yLed, LOW); digitalWrite(rLed, LOW); digitalWrite(bLed, LOW);
}
else if (concentration1 < 20000) {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
lcd.print("ACCEPTABLE");
digitalWrite(wLed, LOW); digitalWrite(gLed, LOW); digitalWrite(yLed, HIGH); digitalWrite(rLed, LOW); digitalWrite(bLed, LOW);
}
else if (concentration1 < 50000) {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
lcd.print("HEAVY");
digitalWrite(wLed, LOW); digitalWrite(gLed, LOW); digitalWrite(yLed, LOW); digitalWrite(rLed, HIGH); digitalWrite(bLed, LOW);
}
else {
lcd.setCursor(0, 1);
for (int i = 0; i < 16; ++i) lcd.write(' ');
lcd.setCursor(4, 1);
lcd.print("HAZARD");
digitalWrite(wLed, LOW); digitalWrite(gLed, LOW); digitalWrite(yLed, LOW); digitalWrite(rLed, LOW); digitalWrite(bLed, HIGH);
}
lowpulseoccupancy1 = 0;
lowpulseoccupancy2 = 0;
starttime = millis();
}
}
Esquemáticos
Proceso de manufactura
- Medición de la Calidad del Aire con OpenSensors: Guía para Arduino y Python
- Sensor de Calidad del Aire Solar con Helium: Guía de Diseño y Despliegue
- Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
- Sistema de Sensor de Temperatura Multiposición para Integración en Hogar Inteligente
- Sensor K30 CO₂: Monitorización en tiempo real de la calidad del aire interior
- Sensor de obstáculos IR casero con Arduino – Tutorial fácil con LED IR y fotodiodo
- Integración del sensor de huella capacitivo DFRobot (ID809) con Arduino o ESP8266
- Crear un medidor IoT web con Arduino, Yaler e IFTTT
- Levitación magnética repulsiva con Arduino: Circuito simple y guía DIY
- Registrador de Datos de Alto Rendimiento para Globo Meteorológico con Arduino
- Sensor avanzado de NO₂ basado en carbono mejora monitorización de calidad del aire interior