Casa inteligente con Arduino: maqueta, sensores, código y móvil
Proyecto de casa inteligente con Arduino paso a paso: maqueta, luz con PIR, alarma de gas e incendio, puerta RFID, relés y control desde el móvil con ESP32.
Un proyecto de casa inteligente con Arduino consiste en automatizar con sensores las luces, la puerta, la ventana y las alarmas de una maqueta y, si quieres, controlarlo todo también desde el móvil. Por eso es uno de los proyectos escolares más populares. Una luz de pasillo que se enciende al detectar movimiento, una alarma que suena cuando hay una fuga de gas, un ventilador que arranca cuando hace calor y una puerta que se abre con una tarjeta forman una copia pequeña, pero funcional, de un sistema domótico real. Con un Arduino Uno o un ESP32, unos diez módulos y un fin de semana, tú también puedes hacerlo.
En esta guía empezamos por el plano de la maqueta: qué módulo va en cada habitación, en qué se va el presupuesto, cómo planificar la alimentación y cómo repartir los pines. Después montamos y probamos cada módulo por separado y escribimos el código completo de Arduino que los hace funcionar todos a la vez sin usar delay(). En las últimas secciones verás cómo controlar la casa desde el móvil con un servidor web en el ESP32 o con Blynk, cómo resolver los errores más habituales y cómo impresionar al jurado en la presentación del colegio o instituto.






¿Cómo funciona un sistema de casa inteligente?
Toda casa inteligente funciona con el mismo ciclo de tres partes. Los sensores miden el entorno: ¿se mueve alguien?, ¿está oscuro?, ¿qué temperatura hace?, ¿hay gas o una llama en la cocina?, ¿qué tarjeta se ha acercado a la puerta? El controlador, es decir, el Arduino o el ESP32, compara esos datos con unas reglas: "si está oscuro y hay movimiento, enciende la luz", "si la temperatura supera los 28 °C, pon en marcha el ventilador". Los actuadores ejecutan la decisión: el relé enciende la lámpara y el ventilador, el servo mueve la puerta y la ventana, el zumbador suena y la pantalla muestra el estado. El control desde el móvil solo añade una entrada más a este ciclo; esta vez decide tu dedo en lugar de una regla.
| Habitación / zona | Módulo | Qué hace |
|---|---|---|
| Puerta de entrada | RFID RC522 + servo SG90 | Abre la puerta al leer una tarjeta autorizada y la cierra 5 segundos después |
| Pasillo / salón | PIR HC-SR501 + LDR + relé | Enciende la lámpara al detectar movimiento a oscuras y la apaga tras 20 segundos sin movimiento |
| Cocina | Sensor de gas MQ-2 + sensor de llama + zumbador | Hace sonar una alarma intermitente si detecta gas o una llama |
| Ventana | Servo SG90 | Abre la ventana para ventilar cuando detecta gas |
| Dormitorio | DHT11 + relé + ventilador | Pone en marcha el ventilador a 28 °C y lo para a 26 °C |
| Cuarto técnico | Arduino, LCD I2C, fuente de alimentación | Muestra temperatura, humedad, el valor de gas y mensajes de estado |
Cómo planificar la maqueta
Diseña la maqueta pensando en la electrónica; no intentes meter la electrónica a presión al final. Una base de unos 50×40 cm basta para dos o tres habitaciones y una entrada. Para las paredes, el cartón pluma de 5 mm o el PVC espumado (tipo Forex) se cortan fácilmente con un cúter; el DM (MDF) de 3–4 mm es más resistente, pero necesita sierra o corte láser. La escala 1:20 es un buen punto de partida: un techo de 2,6 m se convierte en una pared de 13 cm y una puerta de 90 cm, en 4,5 cm de ancho. Haz el tejado desmontable o no lo pongas; el jurado querrá ver el interior de las habitaciones.
- Cuarto técnico o doble suelo: coloca el Arduino, la protoboard, el módulo de relés y la entrada de alimentación en un compartimento en la parte trasera de la casa o bajo un doble suelo de 3–4 cm de alto. Si lo tapas con metacrilato transparente, el circuito queda protegido y a la vista.
- Canales para los cables: haz un agujero de 6–8 mm bajo cada sensor y lleva los cables por debajo de la base hasta el cuarto técnico. En lugar de empalmar cables cortos, elige desde el principio cables de sensor lo bastante largos.
- Puerta: fija la puerta a la pared con una pequeña bisagra o cinta y une el brazo del SG90 a la puerta con un alambre doblado de un clip. Pega el RC522 en la cara interior de la pared exterior; normalmente el lector lee la tarjeta incluso a través de una plancha de 5 mm.
- Cocina: en las casas reales, el detector de gas natural (metano) se coloca cerca del techo porque es más ligero que el aire, y el de butano o propano (GLP), cerca del suelo porque pesan más; en la maqueta basta con un sitio cerca del techo. Orienta el sensor de llama hacia la cocina.
- Otros sensores: pon el PIR en una esquina que vea de lado el camino de entrada, el LDR en una pared exterior o ventana donde no le llegue la luz de la lámpara y el DHT11 lejos de la lámpara y del cuerpo caliente del MQ-2.
Lista de materiales y coste
| Componente | Cantidad | Función | Nivel de precio |
|---|---|---|---|
| Arduino Uno R3 (vale un clon) o ESP32 DevKit | 1 | El cerebro de la casa | Medio |
| Protoboard y juego de cables jumper (macho-macho, macho-hembra) | 1 juego | Conexiones | Bajo |
| Sensor de movimiento PIR HC-SR501 | 1 | Luz del pasillo | Bajo |
| LDR y resistencia de 10 kΩ | 1 + 1 | Detectar la oscuridad | Muy bajo |
| Módulo sensor de gas MQ-2 | 1 | Alarma de gas y humo | Bajo |
| Módulo sensor de llama (LM393) | 1 | Alarma de incendio | Bajo |
| Módulo de temperatura y humedad DHT11 | 1 | Control del ventilador | Bajo |
| Módulo RFID RC522 (con tarjeta y llavero) | 1 | Puerta con tarjeta | Bajo |
| Servomotor SG90 | 2 | Puerta y ventana | Bajo |
| Módulo de 2 relés de 5 V | 1 | Lámpara y ventilador | Bajo |
| Zumbador activo (buzzer) | 1 | Sonido de alarma | Muy bajo |
| Pantalla LCD 16x2 con I2C | 1 | Pantalla de estado | Bajo – medio |
| Miniventilador de 5 V y lámpara LED de 5 V o tira LED | 1 + 1 | Cargas de los relés | Bajo |
| Fuente de alimentación de 5 V y 2–3 A con conector DC o bornes | 1 | Alimentación de servos, relés y sensores | Medio |
| Cartón pluma o PVC espumado, cúter, pegamento termofusible | – | Estructura de la casa | Medio |
Los precios cambian a menudo según la tienda y con el tiempo, así que no damos cifras; la tabla muestra el peso de cada componente en el presupuesto. Los sensores y módulos son baratos por separado; la mayor parte del presupuesto se va en la placa, la pantalla LCD, la fuente de alimentación y el material de la maqueta. Si tienes un kit de inicio de Arduino, ya cuentas con la placa, la protoboard, los cables, el LDR, el zumbador y, a menudo, un servo y una pantalla LCD. Con poco presupuesto puedes prescindir de la pantalla y del segundo servo: usas el monitor serie en lugar de la pantalla y dejas la ventana para una segunda fase. Un DHT22, más preciso que el DHT11, cuesta algo más, pero hace que tus mediciones resulten más convincentes en la presentación.
Plan de alimentación: ¿por qué una fuente de 5 V aparte?
En las maquetas de casa inteligente, casi todas las quejas del tipo "se reinicia de vez en cuando", "el servo tiembla" o "salen caracteres raros en la pantalla" vienen de la alimentación. El puerto USB de un ordenador da unos 500 mA y, cuando la placa se alimenta por USB, el pin 5V del Uno también depende de ese límite. Si sumas los valores de abajo, verás que la corriente total supera fácilmente 1 A cuando los dos servos se mueven a la vez.
| Componente | Corriente aproximada a 5 V |
|---|---|
| Arduino Uno | 45–50 mA |
| MQ-2 (calentador siempre encendido) | Unos 150 mA |
| Módulo de relés (por canal, relé activado) | 70–80 mA |
| Servo SG90 (en movimiento / forzado) | 100–250 mA / hasta 0,5–0,7 A |
| LCD I2C (retroiluminación encendida) | 20–30 mA |
| RC522 (desde el pin de 3,3 V) | 13–26 mA |
| Zumbador activo, DHT11, PIR y sensor de llama | 30–40 mA en total |
| Miniventilador de 5 V y lámpara LED | 100–400 mA según el modelo |
Plan de pines: Arduino Uno y ESP32
Con tantos módulos, el Uno se queda casi sin pines, así que conviene planificarlos desde el principio. El RC522 usa SPI por hardware, por lo que sus líneas MOSI, MISO y SCK van fijas a D11, D12 y D13. La pantalla solo usa A4 y A5 a través de I2C; por eso elegimos una LCD con módulo I2C en lugar de una conectada en paralelo. Los pines analógicos también funcionan como digitales cuando hace falta, y así podemos conectar el servo de la ventana a A2. Deja libres D0 y D1: esa línea serie se usa al subir el código y al leer los números de las tarjetas en el monitor serie. Puedes ver la distribución de pines de tu placa en la herramienta Pinout.
| Pin del módulo | Arduino Uno | ESP32 |
|---|---|---|
| PIR OUT | D2 | GPIO 16 |
| Sensor de llama DO | D3 | GPIO 17 |
| DHT11 DATA | D4 | GPIO 13 |
| Zumbador activo (+) | D5 | GPIO 25 |
| Servo de la puerta (señal) | D6 | GPIO 32 |
| Relé IN1 (lámpara) | D7 | GPIO 26 |
| Relé IN2 (ventilador) | D8 | GPIO 27 |
| RC522 RST | D9 | GPIO 4 |
| RC522 SDA (SS) | D10 | GPIO 5 |
| RC522 MOSI / MISO / SCK | D11 / D12 / D13 | GPIO 23 / 19 / 18 |
| MQ-2 AO | A0 | GPIO 34 (con divisor de tensión) |
| Punto medio del divisor del LDR | A1 | GPIO 35 (divisor alimentado desde 3V3) |
| Servo de la ventana (señal) | A2 | GPIO 33 |
| LCD I2C SDA / SCL | A4 / A5 | GPIO 21 / 22 |
Montaje paso a paso
- Construye la estructura de la maqueta y prepara la posición de los módulos y los agujeros para los cables; la electrónica se coloca al final.
- Monta la línea de alimentación: conecta la fuente de 5 V a las líneas de alimentación de la protoboard, une su GND con el GND del Arduino y comprueba los 5 V con un multímetro.
- Conecta la LCD I2C y muestra un texto. Si no encuentras la dirección de la pantalla, usa el sketch escáner del artículo sobre la pantalla LCD I2C.
- Añade los sensores de uno en uno: DHT11, LDR, PIR, MQ-2 y sensor de llama. Prueba cada uno con un sketch corto en el monitor serie y apunta los valores con aire limpio, a oscuras y con luz.
- Añade los actuadores: prueba primero los relés sin carga fijándote en el clic y en su LED, luego los servos con alimentación externa y, por último, conecta el RC522. Acerca tus tarjetas y apunta sus números.
- Sube el código principal y ajusta los umbrales GAS_LIMIT, DARK_LIMIT y FAN_ON según tus notas.
- Fija los cables con pegamento termofusible y etiquétalos; deja el sistema encendido media hora y vigila si hay reinicios, calentamiento o falsas alarmas.
Luz automática con PIR y LDR
El sensor PIR HC-SR501 detecta los cambios en la radiación infrarroja que emite el cuerpo humano y pone su salida en HIGH cuando ve movimiento. Con un PIR solo, la lámpara se encendería también de día, así que nuestra regla tiene dos condiciones: encender si hay movimiento y está oscuro. El LDR se conecta como divisor de tensión con una resistencia de 10 kΩ (5V → LDR → A1 → 10 kΩ → GND), y el valor en A1 baja a medida que oscurece. El código guarda el momento del último movimiento y apaga la lámpara tras 20 segundos sin movimiento nuevo; mientras alguien camine por la habitación, el tiempo vuelve a empezar. Pon el puente (jumper) del sensor en H (disparo repetido) y su potenciómetro Tx al mínimo, y deja que el código decida el tiempo. Más detalles en los artículos sobre el sensor de movimiento PIR y el sensor de luz LDR.
Alarma de gas e incendio
Dentro del MQ-2 hay una capa de dióxido de estaño que un calentador mantiene caliente; el GLP, el metano, el butano, el hidrógeno, el alcohol y el humo cambian su resistencia. El pin AO del módulo entrega una tensión que sube cuando aumenta la concentración de gas. El sensor necesita calentarse cada vez que se enciende, por eso el código ignora las alarmas de gas durante los primeros 60 segundos. El sensor de llama detecta la luz infrarroja de 760–1100 nm que emite el fuego; en la mayoría de los módulos, la salida DO pasa a LOW y se enciende un segundo LED de la placa al ver una llama, pero comprueba siempre tu módulo con un mechero a una distancia segura. Si detecta gas, suena la alarma y la ventana se abre para ventilar; si detecta una llama, la ventana se queda cerrada, porque el aire fresco aviva el fuego. El ajuste del umbral y los demás sensores MQ se explican en el artículo sobre el sensor de gas MQ-2.
Temperatura, humedad y ventilador automático
El DHT11 mide la temperatura de 0 a 50 °C con una precisión de ±2 °C y la humedad del 20 al 90 % con ±5 %, y solo se puede leer una vez por segundo como máximo; el código lo lee cada dos segundos. En lugar de un único umbral, para el ventilador usamos histéresis: arranca a 28 °C, pero no se para hasta que la temperatura baja a 26 °C. Con un solo umbral, el relé no dejaría de hacer clic mientras la temperatura oscila entre 27 y 28 °C, y se desgastarían tanto él como el ventilador. Si el sensor falla una lectura y devuelve "nan", el código descarta esa medición y mantiene el último valor válido. Para medir con más precisión, el DHT22 funciona con el mismo código; basta con escribir DHT22 en lugar de DHT11. Más detalles en el artículo sobre el sensor de temperatura y humedad DHT11.
Puerta con tarjeta RFID y servo
El RC522 lee tarjetas y llaveros MIFARE de 13,56 MHz a 3–5 cm de distancia. Cada tarjeta tiene su propio número de identificación (UID), y el código compara el UID leído con una lista de tarjetas autorizadas. Si coincide, el servo abre la puerta hasta 90 grados, suena un pitido corto y la pantalla muestra "Hos geldin!" ("¡Bienvenido!" en turco); 5 segundos después la puerta se cierra sola. Una tarjeta desconocida recibe un pitido largo. Para saber el UID de tus tarjetas, sube el código, abre el monitor serie a 9600 baudios y acerca una tarjeta: verás una línea como "UID: A1 B2 C3 D4". Escribe esos bytes en la lista CARDS con el formato 0xA1 y añade un cero delante a los bytes que aparezcan con una sola cifra (0x05 en lugar de 5). Una cerradura que solo comprueba el UID sirve para aprender, pero no da seguridad real; explicamos por qué en el artículo sobre el RFID RC522.
Ventana y cortina
Para la ventana basta con un segundo SG90: unes una pequeña ventana de metacrilato con bisagra al brazo del servo mediante un alambre; 0 grados es cerrada y 90 grados, abierta. Llamar a write(0) antes de attach() evita que el servo salte a 90 grados al encenderse y golpee la ventana. Una cortina necesita más recorrido: hay que enrollar la tela en una varilla fina y hacerla girar. Para eso, un motor paso a paso 28BYJ-48 con driver ULN2003 es silencioso y preciso, pero necesita 4 pines; como al Uno no le quedan, lo lógico es dejar la cortina para la versión con ESP32 o para un Arduino Mega. Si tiene que bastar un solo pin, también sirve un servo de rotación continua FS90R, aunque, como no conoce su posición, abrirás y cerrarás la cortina por tiempo. Añadir un sensor de lluvia que cierre la ventana automáticamente cuando llueva es otra buena ampliación.
Lámpara y ventilador con relé

Un pin de Arduino solo puede dar con seguridad unos 20 mA (el límite absoluto es de 40 mA), mientras que un ventilador o una lámpara necesitan mucho más. Por eso se pone un módulo relé en medio: la señal del pin IN activa un electroimán que cierra los contactos de un circuito separado. Conecta la carga a los bornes COM y NO, así la lámpara sigue apagada mientras el Arduino está apagado o se reinicia. La mayoría de estos módulos son activos a nivel bajo, es decir, el relé se activa cuando escribes LOW; para eso están las constantes RELAY_ON y RELAY_OFF del código. En setup(), el código escribe HIGH antes de configurar el pin como salida, así el relé no se activa ni un instante al arrancar el Arduino. Usamos histéresis para que el ventilador no se encienda y apague demasiado a menudo, y la lámpara sigue encendida hasta que se agota el tiempo del PIR.
El código completo (Arduino Uno)
La regla más importante del código de una casa inteligente es que ningún módulo espere a otro. Si mantuvieras la puerta abierta 5 segundos con delay(5000), durante ese tiempo no funcionaría la alarma de gas ni se leería el PIR. Por eso cada módulo va en su propia función, y loop() llama a estas funciones una tras otra cientos de veces por segundo. Todo lo que depende del tiempo se mide con millis(), y el estado de cada módulo se guarda en variables como lightOn, fanOn, doorOpen y alarmOn. Todos los ajustes están arriba del código como constantes, así que no tienes que rebuscar en el código para cambiar un umbral. La lógica de este enfoque la tienes en el artículo millis() frente a delay(). Para compilar el código, instala desde el gestor de bibliotecas MFRC522, la DHT sensor library de Adafruit y LiquidCrystal I2C de Frank de Brabander, e instala todas las dependencias cuando te lo pida. Servo, SPI y Wire vienen con el IDE de Arduino.
1#include <SPI.h>
2#include <MFRC522.h>
3#include <Servo.h>
4#include <DHT.h>
5#include <Wire.h>
6#include <LiquidCrystal_I2C.h>
7
8// Pinler / Pins
9const byte PIR_PIN = 2, FLAME_PIN = 3, DHT_PIN = 4, BUZZER_PIN = 5, DOOR_PIN = 6;
10const byte LAMP_RELAY = 7, FAN_RELAY = 8, RST_PIN = 9, SS_PIN = 10;
11const byte GAS_PIN = A0, LDR_PIN = A1, WINDOW_PIN = A2;
12
13// Ayarlar / Settings
14const byte RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
15const byte FLAME_ACTIVE = LOW; // alev görünce DO LOW olur / DO goes LOW on flame
16const int GAS_LIMIT = 400; // temiz havaya göre ayarla / tune in clean air
17const int DARK_LIMIT = 300; // bunun altı karanlık / below this is dark
18const float FAN_ON = 28.0, FAN_OFF = 26.0; // fan histerezisi (°C) / fan hysteresis (°C)
19const unsigned long LIGHT_MS = 20000; // son hareketten sonra ışık / light after last motion
20const unsigned long DOOR_MS = 5000; // kapı açık kalma süresi / door open time
21const unsigned long WARMUP_MS = 60000; // MQ-2 ve PIR ısınması / MQ-2 and PIR warm-up
22
23const byte CARDS[][4] = { // yetkili kart UID'leri / authorised card UIDs
24 {0xA1, 0xB2, 0xC3, 0xD4},
25 {0x12, 0x34, 0x56, 0x78}
26};
27
28MFRC522 rfid(SS_PIN, RST_PIN);
29Servo door, window;
30DHT dht(DHT_PIN, DHT11);
31LiquidCrystal_I2C lcd(0x27, 16, 2);
32
33float tempC = 0, hum = 0;
34int gas = 0;
35bool lightOn = false, fanOn = false, doorOpen = false, alarmOn = false;
36unsigned long lastMotion = 0, doorAt = 0, lastDht = 0, lastLcd = 0, beepUntil = 0;
37
38void setup() {
39 Serial.begin(9600);
40 digitalWrite(LAMP_RELAY, RELAY_OFF); pinMode(LAMP_RELAY, OUTPUT); // açılışta kapalı / off at boot
41 digitalWrite(FAN_RELAY, RELAY_OFF); pinMode(FAN_RELAY, OUTPUT);
42 pinMode(PIR_PIN, INPUT);
43 pinMode(FLAME_PIN, INPUT);
44 pinMode(BUZZER_PIN, OUTPUT);
45 door.write(0); door.attach(DOOR_PIN); // önce açı, sonra attach / angle first, then attach
46 window.write(0); window.attach(WINDOW_PIN);
47 dht.begin();
48 SPI.begin();
49 rfid.PCD_Init();
50 lcd.init();
51 lcd.backlight();
52 lcd.print(F("BlueGrays Ev"));
53}
54
55void loop() {
56 unsigned long now = millis();
57 handleLight(now);
58 handleClimate(now);
59 handleSafety(now);
60 handleDoor(now);
61 bool beep = (long)(beepUntil - now) > 0;
62 digitalWrite(BUZZER_PIN, beep || (alarmOn && (now / 250) % 2)); // alarmda kesik bip / pulsed beep on alarm
63 updateLcd(now);
64}
65
66// 1) Hareketle ışık / motion light
67void handleLight(unsigned long now) {
68 if (now < WARMUP_MS) return; // PIR ısınıyor / PIR warming up
69 if (digitalRead(PIR_PIN) == HIGH) {
70 lastMotion = now;
71 if (analogRead(LDR_PIN) < DARK_LIMIT) lightOn = true; // yalnız karanlıkta yak / only when dark
72 }
73 if (lightOn && now - lastMotion > LIGHT_MS) lightOn = false;
74 digitalWrite(LAMP_RELAY, lightOn ? RELAY_ON : RELAY_OFF);
75}
76
77// 2) Sıcaklık ve fan / temperature and fan
78void handleClimate(unsigned long now) {
79 if (now - lastDht < 2000) return; // DHT11'i sık okuma / don't read DHT11 too often
80 lastDht = now;
81 float t = dht.readTemperature();
82 float h = dht.readHumidity();
83 if (isnan(t) || isnan(h)) return; // okuma hatası / read error
84 tempC = t;
85 hum = h;
86 if (tempC >= FAN_ON) fanOn = true;
87 if (tempC <= FAN_OFF) fanOn = false;
88 digitalWrite(FAN_RELAY, fanOn ? RELAY_ON : RELAY_OFF);
89}
90
91// 3) Gaz ve yangın / gas and fire
92void handleSafety(unsigned long now) {
93 gas = analogRead(GAS_PIN);
94 bool gasAlarm = now > WARMUP_MS && gas > GAS_LIMIT;
95 bool fire = digitalRead(FLAME_PIN) == FLAME_ACTIVE;
96 alarmOn = gasAlarm || fire;
97 window.write(gasAlarm && !fire ? 90 : 0); // gazda aç, yangında kapalı tut / open on gas, shut on fire
98}
99
100// 4) RFID kapı / RFID door
101void handleDoor(unsigned long now) {
102 if (doorOpen && now - doorAt > DOOR_MS) {
103 door.write(0); // süre dolunca kapat / close when time is up
104 doorOpen = false;
105 }
106 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
107 Serial.print(F("UID:")); // yeni kartın UID'sini öğren / learn a new card's UID
108 for (byte i = 0; i < rfid.uid.size; i++) {
109 Serial.print(' ');
110 Serial.print(rfid.uid.uidByte[i], HEX);
111 }
112 Serial.println();
113 if (isAllowed(rfid.uid.uidByte)) {
114 door.write(90);
115 doorOpen = true;
116 doorAt = now;
117 beepUntil = now + 100; // kısa bip: hoş geldin / short beep: welcome
118 } else {
119 beepUntil = now + 800; // uzun bip: yetkisiz kart / long beep: unknown card
120 }
121 rfid.PICC_HaltA();
122}
123
124bool isAllowed(const byte *uid) {
125 for (byte i = 0; i < sizeof(CARDS) / 4; i++) {
126 if (memcmp(uid, CARDS[i], 4) == 0) return true;
127 }
128 return false;
129}
130
131// 5) Ekran / display
132void updateLcd(unsigned long now) {
133 if (now - lastLcd < 1000) return;
134 lastLcd = now;
135 lcd.setCursor(0, 0);
136 lcd.print(F("T:"));
137 lcd.print(tempC, 0);
138 lcd.print(F("C Nem:%"));
139 lcd.print(hum, 0);
140 lcd.print(F(" "));
141 lcd.setCursor(0, 1);
142 if (alarmOn) {
143 lcd.print(F("!! ALARM !! "));
144 } else if (doorOpen) {
145 lcd.print(F("Hos geldin! "));
146 } else {
147 lcd.print(F("Gaz:"));
148 lcd.print(gas);
149 lcd.print(F(" "));
150 }
151}| Función | Tarea | ¿Con qué frecuencia? |
|---|---|---|
| handleLight() | Enciende el relé de la lámpara según el PIR y el LDR y lo apaga tras 20 segundos sin movimiento | En cada ciclo (salvo los primeros 60 segundos) |
| handleClimate() | Lee el DHT11 y controla el ventilador con histéresis de 28/26 °C | Cada 2 segundos |
| handleSafety() | Lee el MQ-2 y el sensor de llama y gestiona la alarma y la ventana | En cada ciclo |
| handleDoor() | Lee la tarjeta, muestra el UID en el monitor serie, abre y cierra la puerta | En cada ciclo |
| updateLcd() | Muestra temperatura, humedad, el valor de gas o un mensaje de estado | Una vez por segundo |
| Línea del zumbador dentro de loop() | Genera el pitido de la tarjeta y el sonido intermitente de alarma | En cada ciclo |
Una vez compilado, este código ocupa cerca del 38 % de la memoria de programa del Uno y el 28 % de su RAM; es decir, queda memoria libre, pero de pines solo queda A3. A A3 puedes conectar un pulsador o un sensor de lluvia; para más cosas tendrás que pasar a un Arduino Mega o a un ESP32. Escribir los textos fijos dentro de F() es la forma más sencilla de mantener bajo el uso de RAM.
Control desde el móvil: servidor web en el ESP32

El Uno no tiene Wi-Fi; la forma más fácil de controlar la casa inteligente desde el móvil es cambiar el cerebro por un ESP32. El código siguiente conecta el ESP32 a la red de casa y arranca un pequeño servidor web. Con el móvil en la misma red Wi-Fi, abre en el navegador la dirección IP que aparece en el monitor serie y verás cuatro botones grandes para la lámpara, el ventilador, la puerta y la ventana, además de la temperatura, la humedad y el valor de gas actuales; la página se recarga sola cada 10 segundos. Cada botón envía al ESP32 una petición corta que indica qué aparato hay que cambiar; el ESP32 cambia el estado y te devuelve a la página principal. Para los servos, instala la biblioteca ESP32Servo desde el gestor de bibliotecas, porque la biblioteca Servo estándar no funciona en el ESP32.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <ESP32Servo.h>
4#include <DHT.h>
5
6const char* ssid = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
7const char* password = "Sifre123"; // Wi-Fi şifren / your Wi-Fi password
8
9const int LAMP_RELAY = 26, FAN_RELAY = 27;
10const int DOOR_PIN = 32, WINDOW_PIN = 33;
11const int DHT_PIN = 13, GAS_PIN = 34; // GPIO 34: ADC1, bölücüyle / ADC1, through a divider
12const int RELAY_ON = LOW, RELAY_OFF = HIGH; // aktif LOW röle / active-LOW relay
13
14WebServer server(80);
15Servo door, window;
16DHT dht(DHT_PIN, DHT11);
17
18bool lamp = false, fan = false, doorOpen = false, windowOpen = false;
19float tempC = NAN, hum = NAN;
20unsigned long lastDht = 0;
21
22void apply() { // durumu donanıma uygula / push the state to the hardware
23 digitalWrite(LAMP_RELAY, lamp ? RELAY_ON : RELAY_OFF);
24 digitalWrite(FAN_RELAY, fan ? RELAY_ON : RELAY_OFF);
25 door.write(doorOpen ? 90 : 0);
26 window.write(windowOpen ? 90 : 0);
27}
28
29String button(const char* id, const char* label, bool on) {
30 return String("<a class='b ") + (on ? "on" : "off") + "' href='/set?d=" + id +
31 "&v=" + (on ? "0" : "1") + "'>" + label + (on ? ": ON" : ": OFF") + "</a>";
32}
33
34void handleRoot() {
35 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
36 "<meta name='viewport' content='width=device-width,initial-scale=1'>"
37 "<meta http-equiv='refresh' content='10'><title>BlueGrays Ev</title>"
38 "<style>body{font-family:sans-serif;text-align:center}"
39 ".b{display:block;margin:12px auto;padding:18px;max-width:320px;border-radius:10px;"
40 "color:#fff;text-decoration:none;font-size:20px}"
41 ".on{background:#2e7d32}.off{background:#607d8b}</style></head><body>"
42 "<h2>BlueGrays Akıllı Ev</h2>";
43 html += "<p>" + String(tempC, 1) + " °C | %" + String(hum, 0) +
44 " | Gaz/Gas: " + String(analogRead(GAS_PIN)) + "</p>";
45 html += button("lamp", "Lamba / Lamp", lamp);
46 html += button("fan", "Fan", fan);
47 html += button("door", "Kapı / Door", doorOpen);
48 html += button("window", "Pencere / Window", windowOpen);
49 html += "</body></html>";
50 server.send(200, "text/html", html);
51}
52
53void handleSet() { // /set?d=lamp&v=1
54 String d = server.arg("d");
55 bool v = server.arg("v") == "1";
56 if (d == "lamp") lamp = v;
57 else if (d == "fan") fan = v;
58 else if (d == "door") doorOpen = v;
59 else if (d == "window") windowOpen = v;
60 apply();
61 server.sendHeader("Location", "/"); // ana sayfaya dön / back to the main page
62 server.send(303);
63}
64
65void setup() {
66 Serial.begin(115200);
67 door.attach(DOOR_PIN, 500, 2400);
68 window.attach(WINDOW_PIN, 500, 2400);
69 pinMode(LAMP_RELAY, OUTPUT);
70 pinMode(FAN_RELAY, OUTPUT);
71 apply(); // her şey kapalı başlar / everything starts off
72 dht.begin();
73 WiFi.begin(ssid, password);
74 while (WiFi.status() != WL_CONNECTED) {
75 delay(500);
76 Serial.print('.');
77 }
78 Serial.println();
79 Serial.println(WiFi.localIP()); // bu adresi telefonda aç / open this address on your phone
80 server.on("/", handleRoot);
81 server.on("/set", handleSet);
82 server.begin();
83}
84
85void loop() {
86 server.handleClient();
87 if (millis() - lastDht > 2000) { // 2 sn'de bir ölç / measure every 2 s
88 lastDht = millis();
89 float t = dht.readTemperature();
90 float h = dht.readHumidity();
91 if (!isnan(t) && !isnan(h)) {
92 tempC = t;
93 hum = h;
94 }
95 }
96}Este código solo incluye las partes que controlas a distancia. También puedes pasar aquí las funciones handleLight(), handleSafety() y handleDoor() del código del Uno: cambia los números de pin según la columna ESP32 de la tabla, usa ESP32Servo en lugar de Servo y vuelve a medir los umbrales GAS_LIMIT y DARK_LIMIT, porque el ADC del ESP32 da valores de 0 a 4095. La página no tiene contraseña, así que cualquiera en tu red podría abrir la puerta; añadir una contraseña sencilla con la función authenticate() de la biblioteca WebServer es una buena costumbre. Para un panel que se actualiza en tiempo real, consulta el artículo sobre ESP32 y WebSocket.
Control desde cualquier lugar con Blynk
Al servidor web del ESP32 solo se puede acceder desde la misma red. Si también quieres controlarlo desde fuera de casa con datos móviles, una plataforma en la nube como Blynk IoT te lo pone fácil: montas la interfaz arrastrando y soltando en la app del móvil, y el ESP32 se conecta al servidor de Blynk. Crea una plantilla (template) en Blynk.Cloud, añade tres datastreams llamados V0 (entero, 0–1, lámpara), V1 (decimal, temperatura) y V2 (decimal, humedad), crea un dispositivo y pega al principio del código los valores Template ID, Template Name y Auth Token que te da. En la app, basta con enlazar un Switch a V0 y un Gauge a V1 y otro a V2. El plan gratuito limita el número de dispositivos, datastreams y mensajes al mes, por eso enviamos los datos de los sensores cada cinco segundos y no cada segundo. La configuración completa está en la guía Blynk IoT con ESP32.
1#define BLYNK_TEMPLATE_ID "TMPLxxxxxxx" // Blynk konsolundan kopyala / copy from the Blynk console
2#define BLYNK_TEMPLATE_NAME "Akilli Ev"
3#define BLYNK_AUTH_TOKEN "TokenBuraya"
4
5#include <WiFi.h>
6#include <BlynkSimpleEsp32.h>
7#include <DHT.h>
8
9const int LAMP_RELAY = 26; // aktif LOW röle / active-LOW relay
10DHT dht(13, DHT11);
11BlynkTimer timer;
12
13BLYNK_WRITE(V0) { // uygulamadaki anahtar / switch widget in the app
14 digitalWrite(LAMP_RELAY, param.asInt() ? LOW : HIGH);
15}
16
17BLYNK_CONNECTED() {
18 Blynk.syncVirtual(V0); // bağlanınca son durumu al / restore the last state
19}
20
21void sendSensors() {
22 float t = dht.readTemperature();
23 float h = dht.readHumidity();
24 if (isnan(t) || isnan(h)) return;
25 Blynk.virtualWrite(V1, t); // sıcaklık / temperature
26 Blynk.virtualWrite(V2, h); // nem / humidity
27}
28
29void setup() {
30 pinMode(LAMP_RELAY, OUTPUT);
31 digitalWrite(LAMP_RELAY, HIGH); // açılışta kapalı / off at boot
32 dht.begin();
33 Blynk.begin(BLYNK_AUTH_TOKEN, "AgAdi", "Sifre123");
34 timer.setInterval(5000L, sendSensors); // 5 sn'de bir: mesaj kotasını korur / every 5 s saves quota
35}
36
37void loop() {
38 Blynk.run();
39 timer.run();
40}¿Qué método de control elegir?
| Método | Qué necesitas | Desde fuera de casa | Dificultad | Ideal para |
|---|---|---|---|---|
| Servidor web en el ESP32 | ESP32 y la Wi-Fi de casa | No, solo en la misma red | Media | Presentaciones escolares, demos sin internet, código totalmente propio |
| Blynk IoT | ESP32, internet y una cuenta de Blynk | Sí | Fácil | Interfaz lista, gráficos y notificaciones |
| Bluetooth (HC-05) | Uno, HC-05 y una app de Android | No, unos 10 m | Fácil | Quien quiera seguir con el Uno (no funciona con iPhone) |
| Bot de Telegram | ESP32 e internet | Sí | Media | Avisos de alarma y órdenes cortas |
| MQTT + Home Assistant | ESP32 y un servidor local (p. ej., Raspberry Pi) | Sí, con configuración | Avanzada | Domótica real |
Para una presentación escolar, el servidor web del ESP32 es la opción más segura: no depende de internet ni de la nube y funciona con su propia red aunque no haya Wi-Fi en la sala. Si quieres seguir con el Uno y solo añadir Bluetooth, puedes hacer tu propia app de Android con App Inventor; pero como al Uno no le quedan pines, tendrás que renunciar a la pantalla o al servo de la ventana para hacer sitio al HC-05. Recibir un mensaje en el móvil cuando salta la alarma es posible con un bot de Telegram en el ESP32, y conectar la casa con aparatos reales, con MQTT y Home Assistant.
Casa inteligente con Raspberry Pi Pico
También puedes montar el mismo sistema en MicroPython con una Raspberry Pi Pico, y la Pico W, con Wi-Fi, se puede controlar desde el móvil igual que el ESP32 (consulta el servidor web con Pico W). Como la Pico funciona a 3,3 V, aquí también valen las reglas del ESP32: alimenta el divisor del LDR desde 3V3, reduce con un divisor las salidas analógicas de 5 V y elige un módulo relé que se active con 3,3 V. Las únicas entradas analógicas son GP26, GP27 y GP28. El código siguiente es la versión en MicroPython del módulo de luz con detector de movimiento:
1from machine import Pin, ADC
2import time
3
4pir = Pin(15, Pin.IN) # PIR OUT (3,3 V çıkış / 3.3 V output)
5ldr = ADC(26) # GP26: bölücü 3V3'ten / divider fed from 3V3
6relay = Pin(14, Pin.OUT, value=1) # aktif LOW röle, kapalı başla / active-LOW relay, start off
7
8LIGHT_MS = 20000 # son hareketten sonra ışık / light after last motion
9DARK = 20000 # bunun altı karanlık / below this is dark
10last = time.ticks_ms()
11on = False
12
13while True:
14 now = time.ticks_ms()
15 if pir.value():
16 last = now
17 if ldr.read_u16() < DARK: # yalnız karanlıkta yak / only when dark
18 on = True
19 if on and time.ticks_diff(now, last) > LIGHT_MS:
20 on = False
21 relay.value(0 if on else 1)
22 time.sleep_ms(50)Consejos para la presentación en clase
- Empieza con un problema: describe un problema real en una frase, como "luces encendidas en una casa vacía, una fuga de gas que nadie nota, personas mayores que pierden las llaves", y luego muestra cómo responde tu maqueta.
- Prepara un diagrama de bloques: sensores a la izquierda, el Arduino en el centro y actuadores a la derecha; etiqueta las flechas con las reglas ("oscuro + movimiento → lámpara"). El jurado no leerá tu código, pero recordará este diagrama.
- Prepara una demo en directo: acerca la tarjeta y enseña cómo se abre la puerta, mueve la mano delante del PIR, acerca al MQ-2 un algodón con alcohol (el alcohol también activa el sensor) y calienta el DHT11 con los dedos. Que cada demostración dure 10–20 segundos.
- Nada de fuego: no enciendas un mechero ni una vela dentro de una maqueta de cartón. La mayoría de los sensores de llama también reaccionan a la luz infrarroja de un mando de la tele colocado cerca; pruébalo antes y úsalo en la demostración.
- Ajusta los umbrales a la sala: si ese día la sala está a 22 °C, esperar a 28 °C arruinará la demo del ventilador; pon FAN_ON 2–3 grados por encima de la temperatura ambiente para que el ventilador arranque al calentar el sensor con los dedos.
- Mide y da cifras: por ejemplo, registra cuántos minutos al día está encendida la lámpara con y sin el PIR y expresa el ahorro en porcentaje. Un resultado con números convence mucho más que decir "funciona".
- Ten un plan B: graba un vídeo del sistema funcionando, lleva cables, un servo y una fuente de recambio, y apunta en un papel los números de las tarjetas y los datos de la Wi-Fi.
- Prepárate para las preguntas del jurado: para "¿Cómo sería en una casa de verdad?", ten respuestas breves sobre la seguridad con la tensión de red, los detectores certificados, la seguridad del RFID y qué hace la puerta si se va la luz.
Errores frecuentes y cómo solucionarlos
| Síntoma | Causa probable | Solución |
|---|---|---|
| El Arduino se reinicia o la pantalla se vuelve loca al moverse un servo | Los servos y relés se alimentan desde el pin 5V del Arduino | Fuente aparte de 5 V y 2–3 A, GND común, condensador de 470–1000 µF en la alimentación de los servos |
| El relé funciona al revés y está activado al encender | El módulo es activo a nivel bajo | Intercambia los valores de RELAY_ON y RELAY_OFF |
| La alarma salta cada vez que se enciende | El MQ-2 se está calentando y el PIR está aprendiendo el entorno | Mantén la espera WARMUP_MS; deja el MQ-2 encendido mucho tiempo antes del primer uso |
| La lámpara se enciende de día o se apaga y se vuelve a encender enseguida | DARK_LIMIT incorrecto o el LDR ve la luz de la lámpara | Ajusta el umbral según los valores del monitor serie y lleva el LDR a una pared exterior |
| No lee las tarjetas | Cableado del RC522 incorrecto o módulo conectado a 5 V | Revisa los pines SPI y prueba el módulo con el ejemplo DumpInfo |
| El DHT11 devuelve nan | Cable DATA en otro pin o falta la resistencia pull-up en el sensor suelto | Revisa el pin, usa un módulo o pon 10 kΩ entre DATA y VCC |
| El servo tiembla de vez en cuando | Alimentación débil; las interrupciones se detienen un instante al leer el DHT11 | Mejora la alimentación; si hace falta, desconecta el servo con detach() al terminar el movimiento |
| En el ESP32 el valor de gas siempre es 0 o 4095 | Un pin ADC2 choca con el Wi-Fi o falta el divisor | Usa un pin ADC1 como GPIO 34 o 35 y un divisor de tensión |
| El móvil no abre la página del ESP32 | El móvil está en la red de invitados o con datos móviles, o la red es de 5 GHz | Conéctate a la misma red de 2,4 GHz y toma la IP del monitor serie |
Un proyecto de casa inteligente con Arduino reúne en un solo montaje la lectura de sensores, la toma de decisiones, el control de motores y relés, la planificación de la alimentación y el control inalámbrico; por eso es un tema estupendo tanto para aprender como para presentar. Empieza con un módulo, prueba cada paso y haz crecer el sistema poco a poco. En la app BlueGrays encontrarás paso a paso, con esquemas y código, los proyectos de iluminación inteligente de escalera, iluminación inteligente con PIR y LDR, alarma de llama y gas, cerradura de puerta RFID y servidor web con ESP32.
Preguntas frecuentes
¿Qué necesito para hacer una casa inteligente con Arduino?
Para una maqueta básica bastan un Arduino Uno o un ESP32, un sensor de movimiento PIR, un LDR, un sensor de gas MQ-2, un sensor de llama, un DHT11, un módulo RFID RC522, dos servos SG90, un módulo de 2 relés, un zumbador y una pantalla LCD I2C. A eso se suman una protoboard, cables jumper, una fuente de 5 V y 2–3 A y material para la maqueta. La mayoría de los módulos son baratos; la placa, la pantalla, la fuente y la propia maqueta se llevan la mayor parte del presupuesto.
¿Es mejor Arduino o ESP32 para una casa inteligente?
Si no necesitas control desde el móvil, el Arduino Uno es más sencillo: funciona directamente con módulos de 5 V y la mayoría de los ejemplos están escritos para él. Elige el ESP32 si necesitas control por Wi-Fi desde el móvil, notificaciones o más pines; eso sí, como sus pines trabajan a 3,3 V, tendrás que tener más cuidado con los módulos relé y los sensores analógicos de 5 V.
¿Cómo controlo una casa inteligente con Arduino desde el móvil?
Lo más fácil es usar un ESP32 con un servidor web; así controlas la lámpara, el ventilador y la puerta con botones desde el navegador de un móvil conectado a la misma Wi-Fi. Para acceder desde fuera de casa puedes usar una app en la nube como Blynk IoT y, si quieres seguir con el Arduino Uno, un módulo Bluetooth HC-05 y una app de Android.
¿Con qué material se hace una maqueta de casa inteligente?
El material más práctico es el cartón pluma o el PVC espumado de 5 mm; se corta con un cúter y se pega con pegamento termofusible. Para una estructura más resistente puedes usar DM (MDF) de 3–4 mm. Una base de unos 50×40 cm, un tejado desmontable y un compartimento técnico aparte para la electrónica facilitan mucho el trabajo.
¿Se puede encender una lámpara de 230 V con Arduino?
Sí, con un módulo relé de 5 V, que separa eléctricamente el circuito de red del Arduino. Pero la tensión de red puede matar: haz las conexiones con el enchufe desconectado, mete el circuito en una caja cerrada y aislante y, en un proyecto de estudiantes, no trabajes nunca sin la supervisión de un adulto. Para una maqueta bastan lámparas de 5 V o 12 V.
¿Sirve una casa inteligente con Arduino para una feria de ciencias?
La casa inteligente es un tema muy habitual, así que una maqueta que funcione no suele bastar por sí sola. Si vinculas el proyecto a una pregunta de investigación medible, por ejemplo cuánta energía ahorra la luz con detector de movimiento o con qué rapidez reacciona la alarma de gas, resultará mucho más sólido a ojos del jurado.
Proyectos para hacer después de leer esto
Ver todos los proyectos
Temperatura y humedad con DHT11
¿Qué temperatura hace en tu habitación, y el aire está húmedo o seco? El sensor DHT11 mide la temperatura y la humedad, y el Arduino escribe los valores en una pantalla LCD de dos líneas, actualizándo

Iluminación inteligente de escaleras y pasillos
Pisas la escalera o entras en el pasillo y las luces se encienden escalón a escalón en la dirección en la que caminas. Hay un sensor de distancia en cada extremo; pases por el que pases, los ocho LED

Iluminación Inteligente ESP32 (PIR + LDR + Relé + OLED)
¡Convierte tu pasillo, baño o despensa en iluminación inteligente con ESP32! Utilizando un sensor de movimiento PIR, un sensor de luz LDR y un módulo de relé, construimos el escenario clásico "la luz se enciende cuando se detecta movimiento en la oscuridad" — si el ambiente ya está iluminado, el movimiento NO activa la luz, ahorrando energía durante el día. La luz permanece encendida durante 30 segundos; si el movimiento continúa, el temporizador se reinicia y la luz permanece encendida más tiem

Timbre y luz con sensor de movimiento
Cuando alguien se acerca a tu puerta, te enteras antes de que llame. En cuanto el sensor de movimiento detecta a alguien, se enciende el LED y el zumbador toca un timbre de tres notas de agudo a grave

Alarma con sensor de llama y gas
Un pequeño vigilante que te avisa enseguida si hay una fuga de gas o aparece una llama en algún sitio. El sensor de gas vigila el aire y el sensor de llama busca la luz del fuego; mientras todo va bie

Cerradura RFID ESP32 (RC522 + servo + OLED + zumbador + LED)
Vamos a construir una cerradura inteligente utilizando un ESP32, un módulo RFID RC522, un servomotor SG90, una pantalla OLED SSD1306, un zumbador activo y 2 LED. Cuando se lee una tarjeta, su código UID se compara con la lista de tarjetas autorizadas definida en el sistema; si es autorizada, el servomotor gira y se desbloquea la cerradura (LED verde + 2 pitidos cortos), y se vuelve a bloquear automáticamente tras 5 segundos. Si la tarjeta no está autorizada, se enciende el LED rojo, se emite una

Encender una bombilla de 220 V con mando a distancia
Enciende y apaga una bombilla de verdad de tu casa con un mando a distancia, sin levantarte del sofá. El Arduino lee la señal de luz invisible del mando; el botón de encendido activa el relé y enciend

Servidor web asíncrono ESP32 (con indicación de IP en la pantalla LCD)
En este proyecto, convertimos el ESP32 en un **servidor web asíncrono** que puedes controlar desde tu teléfono o tu ordenador, siempre que estén conectados a la misma red Wi-Fi. Gracias a la biblioteca ESPAsyncWebServer, el servidor puede procesar varias solicitudes al mismo tiempo (a diferencia del clásico `WebServer.h`, que se bloquea con una sola solicitud).
Más artículos
App BlueGrays
Monta este circuito paso a paso en tu teléfono
Esquema, código y lista de piezas en una sola pantalla. Más de 160 proyectos de Arduino, ESP32 y Pico listos para montar.
Escanea con tu teléfono
Apunta la cámara al código y se abrirá la tienda de apps de tu teléfono.
o ábrela en la tienda

