Control Domótico Ethernet Shield Arduino desde Internet

El control domótico de dispositivos a través de internet se ha convertido en una necesidad y una comodidad en los hogares modernos. Una de las plataformas más populares y accesibles para implementar este tipo de soluciones es Arduino, combinada con un Ethernet Shield. Este artículo explora en detalle cómo utilizar un Ethernet Shield con Arduino para controlar dispositivos conectados a una red local e incluso acceder a ellos desde internet, transformando su hogar en un espacio más inteligente y conectado.

Componentes básicos de un hogar inteligente

Fundamentos de Redes para el Control Domótico

Antes de adentrarnos en la implementación práctica, es crucial comprender algunos conceptos básicos de redes. Una Red de Área Local o LAN (por sus siglas en inglés Local Area Network) es un conjunto de dispositivos interconectados que abarcan un área geográfica reducida, como una casa, un departamento o un edificio. Típicamente, esta red está compuesta por dispositivos conectados mediante Wi-Fi o Ethernet a un punto central común, usualmente un router.

Diagrama de una red LAN doméstica típica

El router actúa como el eje central de la red, facilitando la comunicación entre todos los dispositivos conectados. Dispositivos como tablets, teléfonos inteligentes y microcontroladores como el ESP8266 suelen conectarse vía Wi-Fi, mientras que computadoras, teléfonos IP y sistemas como un Arduino con Ethernet Shield se conectan a través de cables Ethernet. Una ventaja fundamental de tener una red LAN es la capacidad de que todos los dispositivos dentro de ella interactúen entre sí sin requerir necesariamente una conexión a internet.

Para identificar de manera única cada dispositivo dentro de una red, se utilizan dos tipos de direcciones:

  • Dirección MAC (Dirección Física): Es un código de 6 bytes único e inmutable asignado a cada dispositivo de red por el fabricante.
  • Dirección IP: Es un código de 4 bytes que identifica a un dispositivo dentro de una red específica. A diferencia de la dirección MAC, la dirección IP puede ser asignada dinámicamente o configurada estáticamente. La forma en que se asignan las direcciones IP está determinada por la máscara de subred. Si una red utiliza una máscara como 255.255.0.0, significa que los dos primeros bytes de la dirección IP deben ser idénticos para todos los dispositivos dentro de esa red.

La puerta de enlace (gateway) es, esencialmente, la dirección IP del router. Aunque puede tener cualquier valor, lo habitual es que sea la primera dirección IP disponible en el rango de la red.

Asignación de Direcciones IP: Estática vs. Dinámica

Existen dos métodos principales para asignar direcciones IP a los dispositivos en una red:

  • Dirección IP Estática: Implica la configuración manual de los parámetros de red (dirección IP, máscara de subred, puerta de enlace) en cada dispositivo. La principal ventaja de este método es que el dispositivo siempre mantendrá la misma dirección IP, lo cual es crucial para acceder a él de forma predecible.
  • Dirección IP Dinámica (DHCP): En este escenario, el router (actuando como servidor DHCP) se encarga de asignar automáticamente los parámetros de red a los dispositivos que se conectan a la red. Si bien simplifica la configuración inicial, existe la posibilidad de que un dispositivo reciba una dirección IP diferente cada vez que se reinicia el router o el propio dispositivo.

Para el proyecto de control domótico con Arduino y Ethernet Shield, la configuración de una dirección IP estática es fundamental. Necesitamos conocer y fijar la dirección IP de nuestro Arduino para poder acceder a él de manera consistente a través de la red.

El Modelo Cliente-Servidor en Redes

La comunicación entre dispositivos en una red a menudo se rige por el modelo cliente-servidor. En este modelo, un dispositivo (el servidor) permanece a la espera de recibir mensajes u órdenes de otros dispositivos (los clientes). Un ejemplo cotidiano de este modelo es la interacción en un aula: el profesor actúa como servidor, esperando preguntas de los estudiantes (clientes). Otro ejemplo es el buscador de Google, donde su servidor responde a las consultas de búsqueda realizadas por los usuarios.

En el contexto de nuestro proyecto, el Arduino conectado al Ethernet Shield actuará como el servidor. Los clientes serán los navegadores web de cualquier dispositivo conectado a la misma red local (ordenador, smartphone, tablet).

Modelo Cliente Servidor, Explicación Simple

El Ethernet Shield: Conectando Arduino a la Red

El Ethernet Shield es un accesorio diseñado para placas Arduino (como Arduino UNO o Arduino MEGA) que les otorga la capacidad de conectarse a una red a través de un cable Ethernet. Este shield se basa generalmente en el chip Wiznet W5100, el cual soporta hasta cuatro conexiones de socket simultáneas y es ideal para diversas aplicaciones de Internet de las Cosas (IoT).

Arduino UNO con Ethernet Shield conectado

Características del Ethernet Shield W5100

Los Ethernet Shields basados en el chip W5100 presentan varios indicadores LED que proporcionan información sobre su estado operativo:

  • ON o PWR: Indica que tanto la placa Arduino como el Shield están recibiendo alimentación eléctrica.
  • 13: (Presente en algunas versiones, como la 2) Conectado al pin digital 13 del Arduino.
  • LINK: Señala la presencia de una conexión de red activa. Este LED parpadea cuando se transmiten o reciben datos.
  • 100M: Indica que la conexión de red se está realizando a una velocidad de 100 Mb/s.

Conexión Física del Ethernet Shield

Conectar un Ethernet Shield a un Arduino UNO o Arduino MEGA es un proceso relativamente sencillo. Ambos tipos de placas utilizan el bus SPI para la comunicación con el shield. En un Arduino UNO, este bus corresponde a los pines digitales 11, 12 y 13. En un Arduino MEGA, los pines SPI son el 50, 51 y 52, y el pin digital 53 se utiliza para la señal SS (Slave Select) del puerto SPI.

Es importante tener en cuenta que el uso del bus SPI para la comunicación con el Ethernet Shield implica que los pines digitales designados para SPI en la placa Arduino no podrán ser utilizados para otras funciones.

Librería Ethernet de Arduino

Para facilitar la interacción con el Ethernet Shield, Arduino proporciona una librería específica: la librería Ethernet. Esta librería está diseñada para trabajar con diversas versiones del Ethernet Shield y otros módulos que emplean los chips Wiznet W5100, W5200 o W5500. Las clases principales de esta librería son:

  • Ethernet: Una clase estática utilizada para inicializar la librería y configurar los parámetros de red del módulo Ethernet. Al ser estática, no requiere la creación de una instancia u objeto; se accede directamente a sus funciones.
  • EthernetServer: Permite que la placa Arduino actúe como un servidor, aceptando conexiones y datos de clientes.

Configuración de Red con la Librería Ethernet

La librería Ethernet ofrece varias sobrecargas para configurar la red. Una función común es Ethernet.init(pinSS), que configura el pin digital utilizado como SS (Slave Select) para controlar el módulo Ethernet.

Otra función clave es Ethernet.begin(mac, ip), que inicializa la librería Ethernet y configura los parámetros de red necesarios, incluyendo la dirección MAC y una dirección IP estática. Una sobrecarga de esta función permite especificar también la máscara de subred. Si se utiliza la sobrecarga Ethernet.begin(mac, ip, gateway), la librería intentará determinar la puerta de enlace automáticamente modificando el último byte de la dirección IP a '1'. En escenarios donde el router asigna los parámetros de red (DHCP), se puede utilizar una función diferente, aunque para nuestro propósito de control predecible, la IP estática es preferible.

Creando un Servidor con EthernetServer

La clase EthernetServer permite que el Arduino funcione como un servidor. A diferencia de Ethernet, EthernetServer no es una clase estática y requiere la creación de una instancia. Por ejemplo, EthernetServer server(80); crea un servidor que escucha en el puerto 80, el puerto estándar para HTTP.

Las funciones clave de EthernetServer incluyen:

  • available(): Verifica si hay un cliente conectado esperando datos.
  • read(): Permite recibir datos enviados por el cliente.
  • print() y println(): Se utilizan para enviar datos de vuelta al cliente, de manera similar a como se usan con la clase Serial.

Implementación Práctica: Control de un LED desde la Red Local

A continuación, se describe un ejemplo práctico para controlar un LED conectado a un pin digital del Arduino, utilizando el Ethernet Shield para hacerlo accesible desde la red local.

1. Hardware Necesario

  • Placa Arduino (UNO o MEGA)
  • Ethernet Shield W5100
  • Cable Ethernet
  • Fuente de alimentación externa para el Arduino (opcional, si no se alimenta por USB)
  • LED y resistencia (para el ejemplo de control)
  • Sensor DHT11 (opcional, para lectura de temperatura y humedad)

2. Configuración del Software (Arduino IDE)

a) Librerías Requeridas

Se deben incluir las librerías Ethernet.h y SPI.h al inicio del sketch.

#include <SPI.h>#include <Ethernet.h>#include <DHT.h> // Si se usa el sensor DHT11

b) Configuración de Red y MAC

Es necesario definir una dirección MAC única para el Ethernet Shield y una dirección IP estática. La dirección MAC puede obtenerse de la documentación del shield o generarse programáticamente. Para la dirección IP, se debe elegir una IP estática dentro del rango de la red local que no esté en uso por otro dispositivo y que no sea asignada por DHCP.

// Define la dirección MAC del Ethernet Shieldbyte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };// Define la dirección IP estática para el Arduino// Asegúrate de que esta IP no esté en uso y esté dentro del rango de tu red local.IPAddress ip(192, 168, 1, 15); // Ejemplo: IP interna// Define la puerta de enlace (la IP de tu router)IPAddress gateway(192, 168, 1, 1); // Ejemplo: IP del router

Para determinar la dirección IP adecuada, puedes consultar la configuración de red de tu ordenador. En Linux o macOS, usa el comando ifconfig en la terminal. En Windows, usa ipconfig en la consola. La IP del Arduino debe ser similar a la de tu ordenador, pero con un último byte diferente para evitar conflictos.

c) Creación del Servidor Web

Se instancia la clase EthernetServer para escuchar en un puerto específico, comúnmente el puerto 80 para HTTP.

// Crea una instancia del servidor en el puerto 80EthernetServer server(80);

d) Función setup()

En la función setup(), se inicializa la comunicación serie (para depuración), el Ethernet Shield y se configura el pin del LED.

void setup() { Serial.begin(9600); // Inicializa el Ethernet Shield // Ethernet.begin(mac, ip); // Si usas IP estática // O si el router asigna la IP (no recomendado para control predecible): // Ethernet.begin(mac); // Si defines gateway y subnet mask explícitamente: IPAddress subnet(255, 255, 255, 0); // Máscara de subred común Ethernet.begin(mac, ip, gateway, gateway, subnet); // Asumiendo que gateway es también DNS server // Comprueba si el Ethernet Shield está conectado correctamente if (Ethernet.hardwareStatus() == EthernetNoHardware) { Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); while (true) { delay(1); // do nothing, just loop forever } } else { Serial.println("Ethernet shield is connected."); } // Inicia el servidor web server.begin(); Serial.print("Servidor iniciado en IP: "); Serial.println(Ethernet.localIP()); // Configura el pin del LED pinMode(4, OUTPUT); // Pin donde conectaremos el LED}

e) Función loop()

La función loop() se encarga de escuchar las peticiones de los clientes, procesarlas y enviar respuestas.

void loop() { // Escucha las peticiones de los clientes EthernetClient client = server.available(); if (client) { // Si hay un cliente conectado Serial.println("Nuevo cliente conectado"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // Imprime el caracter recibido en el monitor serie // Una solicitud HTTP termina con una línea en blanco if (c == '\n' && currentLineIsBlank) { // Envía una respuesta HTTP estándar client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // Línea en blanco para terminar las cabeceras // Contenido HTML de la página web client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head><title>Control LED Arduino</title></head>"); client.println("<body>"); client.println("<h1>Control de LED</h1>"); client.println("<p><a href=\"/?lighton=ON\">Encender LED</a></p>"); client.println("<p><a href=\"/?lighton=OFF\">Apagar LED</a></p>"); client.println("</body>"); client.println("</html>"); // Finaliza la conexión con el cliente break; // Sale del bucle while (client.connected()) } // Si el caracter es un salto de línea, activa la bandera if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { // Si no es un retorno de carro, desactiva la bandera currentLineIsBlank = false; } } } // Procesa la solicitud para encender o apagar el LED if (client.connected()) { // Asegurarse de que el cliente sigue conectado después de enviar la respuesta String request = client.readStringUntil('\n'); // Lee la línea de la solicitud Serial.println(request); if (request.indexOf("/?lighton=ON") != -1) { digitalWrite(4, HIGH); // Enciende el LED Serial.println("LED encendido"); } if (request.indexOf("/?lighton=OFF") != -1) { digitalWrite(4, LOW); // Apaga el LED Serial.println("LED apagado"); } } // Espera un poco para que el cliente termine de recibir la respuesta delay(1); // Cierra la conexión con el cliente client.stop(); Serial.println("Cliente desconectado"); }}

3. Acceso desde la Red Local

Una vez cargado el sketch en el Arduino con el Ethernet Shield conectado a la red local, puedes acceder a la página web generada desde cualquier navegador en la misma red. Simplemente introduce la dirección IP estática asignada al Arduino, seguida del puerto (si no es el 80, aunque en este ejemplo sí lo es). Por ejemplo: 192.168.1.15.

Al visitar esta dirección, verás dos enlaces: "Encender LED" y "Apagar LED". Al hacer clic en ellos, se enviará una solicitud al Arduino (por ejemplo, /?lighton=ON), que el script interpretará para activar o desactivar el LED conectado al pin 4.

Acceso desde Internet: Superando Barreras

La posibilidad de controlar dispositivos desde internet, es decir, desde fuera de la red local, añade una capa significativa de funcionalidad. Sin embargo, esto presenta desafíos técnicos mayores.

1. Redirección de Puertos (Port Forwarding)

Para que un servidor web local (nuestro Arduino) sea accesible desde internet, es necesario configurar el router para que redirija el tráfico entrante de internet hacia la dirección IP y el puerto del dispositivo Arduino. Este proceso se conoce como redirección de puertos o Port Forwarding.

Cada router tiene una interfaz de configuración diferente, pero generalmente se accede a ella introduciendo la dirección IP de la puerta de enlace (la IP del router) en un navegador web. Dentro de la configuración del router, se debe buscar la sección de "Port Forwarding" o "Redirección de Puertos". Allí, se configura una regla que asocie un puerto externo (por ejemplo, el puerto 80 para HTTP) a la dirección IP interna del Arduino y su puerto correspondiente.

Ejemplo de configuración de Port Forwarding en un router

2. Dirección IP Pública y DNS Dinámico

El acceso desde internet requiere conocer la dirección IP pública de tu red doméstica. Esta es la dirección IP que tu proveedor de servicios de internet (ISP) te asigna. Si tu ISP te proporciona una dirección IP estática, el proceso es más sencillo, ya que tu IP pública no cambiará.

Sin embargo, la mayoría de los usuarios domésticos tienen direcciones IP dinámicas, que pueden cambiar periódicamente. En este caso, para acceder consistentemente a tu red, se recurre a servicios de DNS Dinámico (DDNS). Estos servicios te permiten asociar un nombre de dominio (ej. mihogar.ddns.net) a tu dirección IP pública cambiante. Se instala un pequeño software en tu red (a veces integrado en el router, o en un dispositivo como un PC o incluso el propio Arduino si es compatible) que actualiza automáticamente el servicio DDNS cada vez que tu IP pública cambia.

3. Consideraciones de Seguridad

Abrir el acceso a tus dispositivos desde internet conlleva riesgos de seguridad. Es fundamental:

  • Utilizar contraseñas robustas si tu sistema lo permite.
  • Mantener el firmware del router y del Arduino actualizado.
  • Limitar el acceso solo a los puertos necesarios.
  • Considerar el uso de protocolos de comunicación más seguros si manejas información sensible.
  • Evitar la exposición de información personal o sensible en las páginas web servidas por el Arduino.

Ampliando las Posibilidades: Más Allá del Control de un LED

La arquitectura cliente-servidor y el uso del Ethernet Shield abren un abanico de posibilidades para la domótica:

  • Lectura de Sensores: Integrar sensores de temperatura y humedad (como el DHT11), sensores de luz, movimiento, etc., y mostrar sus lecturas en una página web accesible desde cualquier lugar.
  • Control de Múltiples Dispositivos: Gestionar relés para controlar luces, electrodomésticos, motores, sistemas de riego, etc.
  • Automatización: Crear escenarios donde los dispositivos se activen o desactiven en función de horarios, lecturas de sensores o comandos recibidos.
  • Integración con Plataformas IoT: Utilizar servicios como Ubidots para enviar y recibir datos, permitiendo la visualización en dashboards y el control a través de aplicaciones móviles específicas. El proceso de enviar datos a Ubidots (POST) y recibir datos de Ubidots (GET) se puede implementar utilizando el Ethernet Shield y la librería adecuada.

Ejemplo con Sensor DHT11

Para integrar un sensor DHT11, se necesitaría añadir la librería DHT, definir el pin donde está conectado el sensor y modificar la función loop() para leer los valores del sensor y presentarlos en la página web servida por el Arduino.

// ... (declaraciones anteriores) ...#define DHTPIN 2 // Pin digital donde está conectado el sensor DHT11#define DHTTYPE DHT11 // Tipo de sensor DHTDHT dht(DHTPIN, DHTTYPE);// ... (setup() y loop() modificados) ...void setup() { // ... (inicialización serie y ethernet) ... dht.begin(); // Inicializa el sensor DHT pinMode(4, OUTPUT); // Pin para el LED // ... (resto de setup) ...}void loop() { // ... (lectura del cliente) ... if (client) { // ... (código para manejar la conexión del cliente) ... if (currentLineIsBlank) { // ... (enviar cabeceras HTTP) ... client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head><title>Control Domotico</title></head>"); client.println("<body>"); client.println("<h1>Estado del Hogar</h1>"); // Mostrar estado del LED client.print("<p>LED: "); client.print(digitalRead(4) == HIGH ? "Encendido" : "Apagado"); client.println("</p>"); // Mostrar lecturas del sensor DHT11 float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) { client.println("<p>Error al leer el sensor DHT!</p>"); } else { client.print("<p>Humedad: "); client.print(h); client.print(" %</p>"); client.print("<p>Temperatura: "); client.print(t); client.print(" &deg;C</p>"); } client.println("<p><a href=\"/?lighton=ON\">Encender LED</a></p>"); client.println("<p><a href=\"/?lighton=OFF\">Apagar LED</a></p>"); client.println("</body>"); client.println("</html>"); break; } // ... (resto del código para procesar peticiones de LED) ... } // ... (delay y client.stop) ...}

El Ethernet Shield, junto con Arduino, ofrece una plataforma robusta y flexible para la implementación de soluciones de control domótico. Desde la monitorización básica de sensores hasta el control avanzado de múltiples dispositivos, la conexión a internet abre un mundo de posibilidades para automatizar y mejorar la comodidad y eficiencia de nuestros hogares. Es importante abordar este tipo de proyectos con una comprensión clara de los principios de red y las consideraciones de seguridad para asegurar un funcionamiento fiable y protegido.

tags: #control #domotico #con #ethernet #shield #y