Air Surfer: Sistema DIY de Monitorización de Calidad del Aire con Arduino Mega 2560
Componentes y Suministros
- Arduino Mega 2560 × 1
- Pantalla TFT 3.2" para Mega 2560 (480×320) × 1
- Sonda de temperatura (DS18B20 en cápsula) × 1
- Sensor humedad/temperatura Adafruit SI7021 × 1
- Sensor CO2 MH-Z19 × 1
- Módulo RTC DS1307 × 1
- Regulador de voltaje ajustable LM2596 × 1
- Conector aviación GX12-3 (L89 G12) × 1
Aplicaciones y Servicios Online
- Arduino IDE
Sobre el Proyecto
Como ingeniero civil, sé bien cómo deben funcionar los sistemas de ventilación en casa. Para medir la calidad del aire en mi apartamento compré un monitor de CO2 y me gustó porque no solo mostraba CO2 sino también la temperatura ambiente.
Sin embargo, no era suficiente. Quería medir más parámetros, así que busqué un dispositivo adecuado. Encontré algunos ridículamente caros, así que decidí hacer el mío propio. En ese momento ya tenía experiencia programando controladores Arduino para una estación de bombeo con válvulas solenoides.
Base: Hardware Principal
Quería una pantalla grande de 10" mínimo, pero vaciaría mis bolsillos. Fui realista y elegí Arduino Mega 2560 R3 con pantalla TFT 3.2" 480×320. Esta configuración requiere cableado mínimo porque la pantalla se conecta directamente al Arduino.
Desafortunadamente, la pantalla que pedí en Aliexpress era tan barata que no funcionaba bien. Aparecían puntos blancos con el tiempo y colores invertidos. Probé diferentes librerías y controladores pero no ayudó. Así que ajusté los colores en el código y añadí refresco de pantalla a las 12:00 y 00:00.

Sensores
Sensor CO2 MH-Z19
La parte más cara del proyecto. Es relativamente barato entre sensores CO2 mientras proporciona mediciones fiables y función de auto-calibración.

Mientras otros módulos eran fáciles de instalar, este sensor tenía poca info en su hoja de datos, así que busqué código en foros y combiné toda la información. Ahora todo funciona perfecto e incluso mejor que el sensor anterior.
Tardó 24h en auto-calibrarse, así que al principio sus lecturas eran inconsistentes. La auto-calibración es simple: cuando salgo de casa no hay quien consuma oxígeno, así que el CO2 baja al nivel exterior (400 ppm). Si las lecturas están por debajo, el sensor se calibra.
Puede comunicarse por UART y PWM. Elegí UART por ser más fiable.

Sensor Temperatura/Humedad SI7021
Para monitorización interior uso I2C (pines SDA/SCL). No es caro, alta precisión industrial. Me gusta porque no tuve ningún problema con él.

Sensor Temperatura Exterior DS18B20
Uso DS18B20 en cápsula de acero inoxidable. Barato y preciso. Requiere resistencia de 4,7k Ω. Comunicación por 1-Wire.

Módulo RTC DS1307
Para la hora, usa I2C.

Indicadores y Controles
- 3 LEDs para niveles CO2: Verde (400-800 ppm), Naranja (800-1200 ppm), Rojo (1200+ ppm)
- 3 botones de acero inoxidable con LEDs: Hora, Minutos, Cambio color texto
- Fotorresistencia para ajustar brillo de LEDs (no molestar por la noche)

Alimentación
Para la fuente de alimentación taladré un agujero en la base y puse un conector DC.

El problema: solo tenía fuentes de 19V y 15V, mientras Arduino recomienda 7-12V. Usé reguladores LM2596 DC-DC ajustables.

Lo puse dentro de la caja y lo ajusté a 7 voltios. Descubrí que mi Arduino se calentaba mucho a 12V, así que elegí el mínimo recomendado. Ahora puede alimentarse de diversas fuentes.

Para el sensor exterior usé conectores aviación y cable telefónico.

Caja
Este fue el mayor problema porque no tenía impresora 3D. Intenté con arcilla polimérica pero no aguantaba la forma y la quemé una vez en el horno.
El segundo intento fue con contrachapado de 6mm. Estaba bien pero era difícil de cortar. Tuve que usar sierra eléctrica y dremel.
El intento final y más exitoso fue con contrachapado de 3mm (difícil de encontrar) que pude cortar sin herramientas eléctricas, solo cúter y lija. Lo pinté con pintura acrílica y el resultado se ve mucho mejor.

Coste Total
| Componente | Coste (USD) | Coste (Rub) |
|---|---|---|
| Arduino Mega 2560 R3 | 8,27$ | 480₽ |
| Pantalla TFT 3.2 480×320 | 8$ | 400₽ |
| Módulo RTC DS1307 | 0,55$ | 32₽ |
| Sensor CO2 MH-Z19 | 20$ | 1160₽ |
| Sensor Temp/Hum SI7021 | 2$ | 118₽ |
| Sensor DS18B20 en cápsula | 1,14$ | 66₽ |
| Fotorresistencia (50 uds) | 1$ | 65₽ |
| LEDs (100 uds) | 0,67$ | 39₽ |
| Botones acero inox (3 uds) | 5,07$ | 294₽ |
| Conector aviación GX12-3 | 1,17$ | 68₽ |
| Conector DC (10 uds) | 1,25$ | 73₽ |
| Regulador LM2596 | 0,69$ | 40₽ |
| Adaptador 12V | 2,14$ | 120₽ |
| Cables | 1,78$ | 100₽ |
| Contrachapado 3mm | 1,78$ | 100₽ |
Total: 55,51$ (3155 Rub)
Código
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SoftwareSerial.h>
#include <SparkFunHTU21D.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <UTFT.h>
#define ONE_WIRE_BUS 9
#define GREENLED 5
#define YELLOWLED 7
#define REDLED 8
#define BUTTONLED 11
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
UTFT myGLCD(CTE32HR, 38, 39, 40, 41);
HTU21D myHumidity;
RTC_DS1307 rtc;
extern uint8_t Ubuntu[];
byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[9];
unsigned int ppm;
unsigned long time;
int photocellReading;
int hourupg, minupg;
float humd, temp;
int tcolor;
int Z;
boolean Reset = false;
void lamps(void) {
// Indicadores CO2
if (ppm < 800) {
myGLCD.setColor(255,140,255); myGLCD.fillCircle(450, 87, 12);
analogWrite(GREENLED, Z); analogWrite(YELLOWLED, 0); analogWrite(REDLED, 0);
} else if (ppm < 1200) {
myGLCD.setColor(70,70,255); myGLCD.fillCircle(450, 87, 12);
analogWrite(GREENLED, 0); analogWrite(YELLOWLED, Z); analogWrite(REDLED, 0);
} else {
myGLCD.setColor(VGA_AQUA); myGLCD.fillCircle(450, 87, 12);
analogWrite(GREENLED, 0); analogWrite(YELLOWLED, 0); analogWrite(REDLED, Z);
}
// Indicadores humedad, temp interior, temp exterior...
}
void drawmain(void) {
// Dibuja pantalla principal con hora, CO2, humedad, temperaturas
// Colores de texto seleccionables (tcolor 0-12)
}
void dateandtime(void) {
// Ajuste hora/minutos con botones
}
void co2(void) {
// Lectura sensor MH-Z19 por UART con verificación CRC
}
void th(void) {
humd = myHumidity.readHumidity();
temp = myHumidity.readTemperature();
sensors.requestTemperatures();
}
void photosensor(void) {
// Ajuste brillo LEDs según luz ambiente (5 niveles)
}
void screenreset(void) {
// Refresco pantalla a las 00:00 y 12:00 para corregir artefactos
}
void setup() {
myGLCD.InitLCD();
myGLCD.clrScr();
myGLCD.fillScr(VGA_WHITE);
myGLCD.setBackColor(VGA_WHITE);
Serial3.begin(9600);
sensors.begin();
myHumidity.begin();
tcolor = 0;
rtc.begin();
pinMode(GREENLED, OUTPUT); pinMode(YELLOWLED, OUTPUT); pinMode(REDLED, OUTPUT);
pinMode(BUTTONLED, OUTPUT);
pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP);
Z = 0;
}
void loop() {
co2(); photosensor(); dateandtime(); th();
if (digitalRead(4) == LOW) { tcolor++; if (tcolor >= 13) tcolor = 0; }
drawmain(); lamps(); screenreset();
}
Esquemáticos

Proceso de manufactura
- Medición de la Calidad del Aire con OpenSensors: Guía para Arduino y Python
- Monitor DIY de calidad del aire: detector EPA-compliant económico
- Entendiendo los Actuadores de Cilindro Neumático: Fundamentos y Aplicaciones
- Guía Definitiva para Elegir los Mejores Compresores de Aire para su Instalación
- Cómo los Supercargadores Aumentan la Eficiencia y el Rendimiento del Motor
- Cómo los sistemas de aire acondicionado del automóvil mantienen tu coche fresco y cómodo
- Sistemas de Suspensión Neumática: Componentes, Funcionamiento y Beneficios para Vehículos Pesados
- Sistemas de inyección de aire: Reducción de emisiones de escape explicada
- Guía esencial de invernaje para compresores de aire: Proteja su equipo del daño por frío
- Aire comprimido: el coste oculto de su resultado final
- Dónde el aire comprimido impulsa procesos cotidianos