You are on page 1of 19

Arduino Ethernet Shield Controla

Tu Casa Por Internet


Posted on 16 noviembre, 2014 Under Tutoriales de Arduino 187 Comments

Y si te dijera que con Arduino Ethernet Shield puedes crearte tu propio web server y
utilizarlo para domotizar tu casa? Ya sea para controlar tu vivienda o cualquier otro
elemento a travs de Internet, este shield de Arduino es una gran eleccin.
En este post te voy a ensear todos los pasos que debes seguir para configurar tu
Arduino Ethernet Shield y crear tu propia pgina web con la que podrs controlar tu
casa desde cualquier parte del mundo. Adems incluir un cdigo pensado para que
puedas pegarlo fcilmente a tu sketch de Arduino y adaptarlo a tu proyecto con unos
pocos cambios.

Tutorial Arduino Ethernet

Como te puedes imaginar, para este proyecto van a ser necesarios algunos
conocimientos de HTML y configuracin de redes, as como la librera Ethernet de
Arduino. No te preocupes por eso porque te lo voy a explicar todo paso a paso para que
te resulte lo ms simple posible.

El Problema de las IP

Cuando conectas tu Arduino Ethernet Shield con tu Router, ste le asigna una direccin
IP, es decir, una identificacin que le permite diferenciar a tu Arduino del resto de
ordenadores y dems elementos que tengas conectados a la red local de tu casa, as
que esa direccin que va a utilizar tu Arduino tienes que introducirla en tu sketch. El
problema es que esa IP es cambiante y cada vez que su valor cambie, tu sistema dejar
de funcionar.
Del mismo modo, la direccin de tu Router cambia salvo que tengas contratado un
sistema con IP esttica. Esto no es lo ms habitual ya que estos sistemas son ms
caros y a la compaa que te proporciona el Internet le interesa que t tengas una IP
dinmica.

Como lo que t quieres es implementar tu sistema sobre tu Arduino Ethernet Shield,


poder controlarlo desde cualquier parte del mundo (y no solo desde tu red de rea
local) y que este siga funcionando sin tener que modificar tu cdigo (sketch) con
independencia de lo que pase en tu red. Tienes que amenazar de muerte a tu proveedor
de Internet solucionar varios problemas:
1. Conseguir que conexin IP entre tu Arduino Ethernet Shield y tu Router (rea
local) no cambie.
2. Abrir los puertos de tu Router para permitir que entre y salga informacin.
3. Conseguir que la conexin entre tu Router e Internet no cambie (para que
puedas acceder siempre desde la misma direccin).
Si te ha entrado el miedo en el cuerpo por aquello de romper Internet, tranquilo. Lo
primero que debes saber es que desde la era de Internet todos los que somos un poco
curiosos y hemos encontrado algo en Google que hemos intentado probar, hemos
causado (ya sea por desconocimiento o intencin) tantos problemas que ya todos los
sistemas estn hechos anti-cafres. Lo segundo es que, como siempre te digo,
Arduino est pensado para ser fcil (y esto no iba a ser menos). Y lo tercero es que
desde EducaChip estamos para ayudarte. Vamos a ello.

Conexin Arduino Ethernet Shield Router

Te voy a decir algo que no te va a gustar: Cada Router se configura de una manera
distinta. Como supongo te estars imaginando, eso quiere decir que en este apartado
no puedo ayudarte mucho. No desesperes, aunque todos son distintos, todos son
similares y con un poco de paciencia no te costar realizar este paso.

Acceder a tu Router

Lo primero que debes hacer es acceder a tu Router desde tu navegador favorito. Para
ello necesitas saber cul es su puerta de enlace (o gateway en ingls). Te voy a poner
cmo se hara desde Windows. Si ests utilizando un sistema operativo diferente, el
funcionamiento es similar. En caso de que tengas dudas puedes dejar un comentario al
final de este post o buscarlo en Google (no te costar encontrarlo).

1. Pulsa el botn de inicio.


2. En la barra de bsquedas, escribe ejecutar y pulsa la tecla intro.
3. En la ventana que te acaba de aparecer escribe cmd y vuelve a pulsar intro.
4. Te habr salido otra ventana de fondo negro. Escribe en ella ipconfig.
5. Dentro del texto que se acaba de escribir en la ventana hay una seccin llamada
Adaptador de Ethernet (o similar). Busca en ella la puerta de enlace
predeterminada o gateway y apunta la direccin asociada (suele ser algo del
tipo 192.168.1.1).

Ahora que ya tienes la direccin con la que acceder a tu Router, basta con que la
escribas en tu navegador (en la zona donde normalmente escribes las URL).
Seguramente te pedir una contrasea. Si es la primera vez que accedes a tu Router
ser la contrasea por defecto. Suele ser algo tipo:

usuario: admin

contrasea: 1234

Si tienes no eres capaz de encontrar tu contrasea, aqu te dejo un enlace con


contraseas por defecto de Routers.

Configurar rea Local

Ahora que ests dentro de tu Router, debes decirle que siempre le de la misma IP a tu
Arduino Ethernet Shield.
Por defecto, la mayor parte de los Routers utilizan un sistema denominado DHCP segn
el cul van asignando IP locales a todos los elementos que se conectan a la red. Cada
cierto tiempo esas IP cambian (tambin pueden cambiar si conectas y desconectas
algn elemento) por lo que si inicias el programa Arduino Ethernet Shield sin modificar
esto, funcionar al principio, pero cuando esa direccin cambie se perder la
comunicacin y tendrs que modificar tu sketch. Para que esto no suceda tienes que
decirle al protocolo DHCP que te parece fantstico que juguetee con las IP pero que no
toque la de tu Arduino.
Todas las mquinas que conectas a tu red tienen un nmero identificativo denominado
MAC que, de cara a la red, es como un DNI o pasaporte. El MAC de tu Arduino puedes
fijarlo t (basta con que no haya varias mquinas con el mismo MAC) y por defecto es:

1 byte mac[] = {
2 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

Salvo que tengas especial inters por utilizar un MAC concreto puedes utilizar este.
Una vez tienes tu MAC, debes decirle a tu Router que a ese MAC le de siempre la misma
IP. Los pasos son los siguientes:

1. Accede a las propiedades de tu DHCP a travs de los mens de tu Router, es


decir, busca por los mens la palabra DHCP o DHCP Settings (suele estar en:

Configuracin >> LAN >> DHCP).

2. En este men podrs ver cosas interesantes como el rango de IP que asigna tu
DHCP (puede que te venga como IP Pool Range o como direcciones IP inicial y
final). Lo que debes buscar es algo tipo Reserva de direcciones IP o MACBase Assignment que es donde vas a enlazar la MAC de tu Arduino Ethernet
Shield con una IP concreta.
3. Abre el men de para asignar la IP. Seguramente te aparecer un recuadro para
enlazar un MAC a una IP. Rellena los datos utilizando el MAC de tu Arduino
Ethernet Shield y la IP que desees (por ejemplo 192.168.1.177) y asegrate de
guardar los cambios.
Si has conseguido llegar a este punto, mi ms sincera enhorabuena. Entiendo que
todos estos datos son realmente abstractos y puede resultar complicado para alguien
sin experiencia. En caso de que ests teniendo algn tipo de problema, aqu estamos
para ayudarte, as que reljate, toma aire y deja tu comentario. Intentaremos ayudarte.

Puertos del Router

Si has completado los pasos anteriores no deberas tener ningn problema en crear tu
propia red de rea local, es decir, si el proyecto que vas a implementar con tu Arduino
Ethernet Shield nicamente necesita conexin entre los elementos de tu casa (del
Router hacia dentro) no necesitas tocar nada ms. Ahora bien, si tu idea es utilizar tu
sistema desde cualquier parte del mundo debes permitir el acceso a tu sistema.
Gracias a que en el paso anterior conseguiste darle una IP fija a tu Arduino Ethernet
Shield, ahora ser muy fcil abrir nicamente el puerto que va a utilizar tu shield de
Arduino.
De nuevo todo esto lo tienes que hacer desde tu Router. Los pasos a seguir son los
siguientes (todo esto te sonar si, en su da, ya abriste los puertos del eMule):

1. Debes buscar en los mens de tu Router algo tipo NAT, Virtual Servers o Port
Forwarding. El nombre vara en funcin del Router pero vas buscando modificar
los puertos as que puedes guiarte por la palabra Port. Si no terminas de
encontrar la manera de llegar a ese men, no te costar mucho dar con l con
una rpida bsqueda en Google (poniendo el modelo de tu Router).
2. Una vez ests en men de puertos de tu Router, activa la opcin de Port
Forwarding y, para la IP local que le diste a tu Arduino Ethernet Shield, abre un
puerto (tpicamente el puerto 80 aunque puedes abrir otros como el puerto 5400).
De nuevo no te olvides de guardar los cambios.

Conexin Router Internet

Hasta ahora has conseguido que tu Router siempre le de la misma IP a tu Arduino


Ethernet Shield y que este tenga acceso a Internet. En realidad ya est todo hecho. El
nico problema es que a la hora de acceder desde fuera de tu red local a tu shield de
Arduino desconoces qu direccin tiene, es decir, no sabes qu IP tiene tu Router. Para
solucionar este problema tienes varias opciones:

Contratar Una IP Esttica

Como ya te he dicho antes, si contratas una IP esttica no tendras que preocuparte por
saber en cada momento cul es la direccin de tu Arduino Ethernet Shield. Puedes
hablar con tu proveedor de Internet y, por un poco ms de dinero al mes (depende del
proveedor pero no suele ser excesivamente caro, entorno a 1), bastara con que
recordases esa direccin para acceder en cualquier momento y desde cualquier sitio a
tu sistema domtico.

Dejar Tu IP Dinmica

Si acostumbras a mantener tu Router siempre encendido debes saber que tu IP no


cambia cada cinco minutos. De nuevo, depende del proveedor. Normalmente cambiar
una vez por semana por lo que si ests frecuentemente en casa y consultas tu IP con
regularidad (puedes ver cul es tu IP pblica en este link), puedes ahorrarte dinero y
esfuerzo y utilizar este mtodo. Ten en cuenta, eso s, que si tu IP cambia y no ests en
casa para consultarla, no podrs acceder al sistema.

Utilizar Un Servicio de DDNS

Este es mi mtodo favorito.


El sistema de las DDNS consiste bsicamente en un dominio (como lo es en esta
pgina www.educachip.com) que est asociado en cada momento a tu IP actual, es
decir, un nombre fijo elegido por ti (y por lo tanto ms fcil de recordar que una
direccin IP) que est siempre actualizado y dirija la conexin hacia tu Arduino Ethernet
Shield.
El problema de este mtodo es que depende de tu Router. Existen muchos servicios
tanto de pago como gratuitos de DDNS y cada Router soporta unos u otros. Que
tu Router no soporte uno en concreto no implica que no puedas utilizarlo pero debers
descargarte la aplicacin correspondiente de ese servicio DDNS y actualizar la IP desde

el ordenador, es decir, tendrs que tener un ordenador siempre encendido, por lo que lo
mejor es que utilices uno de los que tu Router soporta para que la actualizacin de la IP
se haga desde el Router, sin necesidad de aplicaciones.
Los servicios de DDNS de pago rondan los 20 (25$) al ao. No es muy caro (cuesta
ms o menos lo que tener una IP esttica) pero en mi opinin es mejor que realices un
nico pago y te compres un buen Router que soporte DDNS gratuitas (lo que adems,
dependiendo del Router que tengas ahora, puede incluso mejorar la velocidad de tu
red). Sea cual sea tu eleccin aqu te dejo unos cuantos servicios de DDNS para que
elijas el que ms te convenga:

DynDNS: Servicio de pago (desde hace poco tiempo) pero lder en el sector y
uno de los ms soportados por los Routers.

Donweb: Gratuito y en Espaol pero relativamente nuevo y poco habitual en los


Routers. Es el que yo utilizo y actualmente estoy intentando conseguir que
funcione desde un Router que no soporte este sistema (ya te ir contando mis
avances).

No-IP: La alternativa tpica a DynDNS. Es gratuito pero requiere que reactives la


cuenta una vez al mes y lo utilices desde un PC.

Namecheap: A parte de dominios a muy buen precio, esta web ofrece servicio de
DNS dinmico gratuito.

TZO: Pertenece a la misma empresa que DynDNS y, como te puedes imaginar,


tanto su precio como su disponibilidad en Routers es similar.

Como a pesar de que cada pgina tiene sus peculiaridades todas funcionan de forma
similar, no voy a entrar a explicarte como conseguir tu servicio de DDNS. Basta con que
entres en la pgina que prefieras (lo ideal es que sea una soportada por tu Router), te
hagas una cuenta como haras en cualquier otra web y accedas a la seccin de DDNS.
Si tienes algn problema realizando este proceso puedes dejar tu comentario al final del
post.
Una vez tengas tu DDNS entra de nuevo en la configuracin de tu Router (aprendiste
cmo hacerlo al principio de este artculo), accede a la seccin de DNS dinmicas y

escribe en las zonas correspondientes tanto el nombre de dominio como tus datos de
usuario.

Actualizar DDNS Con Arduino

En el paso anterior te dije que si tu Router no soporta un determinado sistema de


DDNS, tienes que descargarte una aplicacin y tener tu PC encendido siempre. Esto no
es del todo as ya que puedes implementar un cdigo que haga que tu Arduino Ethernet
Shield actualice automticamente la IP.
No es el tema de este post as que dejar la explicacin en profundidad de este mtodo
para otra ocasin. Aun as, est bien que sepas que se puede hacer (por si quieres
investigarlo). Ten en cuenta que este mtodo te aporta versatilidad (porque no
dependes del Router y puedes implementar el sistema en distintos sitios sin necesidad
de realizar tantos cambios) pero aade carga de trabajo y espacio al microcontrolador
cuando puedes dejar que eso lo haga el Router.

Cdigo

Ahora que ya eres un experto en redes, programar tu Arduino Ethernet Shield debera
ser pan comido. Aun as te voy a dejar dos cdigos para tu Arduino:

El primer cdigo es el proporcionado por el propio equipo de Arduino, al que le


he modificado los comentarios para que te resulte ms fcil entenderlo,
modificarlo y lo adaptes a tu propio proyecto sin problemas.

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9

#include <SPI.h>
#include <Ethernet.h>
//Se introducen los valores correspondientes a MAC, IP local, Puerta de Enlace y
Mscara de Red
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
//Se inicializa la librera Ethernet con el Puerto que se va utilizar en la transmisin
EthernetServer server(80);
void setup() {
// Se establece comunicacin con el monitor serial (para ver si el sistema est
funcionando correctamente)
Serial.begin(9600);
// while (!Serial) {
// ; // Se espera a que se conecte el puerto serie (solo para Arduino Leonardo)
// }
// Comienzo de la conexin
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
//Se muestra por el monitor serial que la conexin est establecida
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
// Se espera a que alguien acceda a la pgina web
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// una peticin http termina con una lnea en blanco
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
//Si se llega al final de la lnea se recive un nuevo carcter de
//lnea y si se trata de una lnea en blanco la peticin http ha terminado

3
//as que se enva la respuesta
0
if (c == '\n' && currentLineIsBlank) {
3
// cabezera tpica http
1
client.println("HTTP/1.1 200 OK");
3
client.println("Content-Type: text/html");
2
client.println("Connection: close"); // se cierra la conexin una vez se ha
3 respondido a la peticin
3
client.println("Refresh: 5"); // se refresca la pgina automticamente cada
3 5 segundos
4
client.println();
3
client.println("<!DOCTYPE HTML>");
5
client.println("<html>");
3
6
// se muestran en la web los valores de las entradas analgicas
3
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
7
int sensorReading = analogRead(analogChannel);
3
client.print("analog input ");
8
client.print(analogChannel);
3
client.print(" is ");
9
client.print(sensorReading);
4
client.println("<br />");
0
}
4
client.println("</html>");
1
break;
4
}
2
if (c == '\n') {
4
// se comienza una nueva lnea
3
currentLineIsBlank = true;
4
}
4
else if (c != '\r') {
4
// se ha obtenido un carcter en la lnea actual
5
currentLineIsBlank = false;
4
}
6
}
4
}
7
// se le da tiempo al navegador para recibir los datos
4
delay(1);
8
// se cierra la conexin
4
client.stop();
9
Serial.println("client disonnected");
5 }
0 }
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6

0
6
1
6
2
6
3
6
4
6
5
6
6
6
7
6
8
6
9
7
0
7
1
7
2
7
3
7
4
7
5
7
6
7
7
7
8
7
9
8
0
8
1
8
2
8
3
8
4
8
5
8
6
8
7

Este segundo cdigo te va a encantar. Es una muestra de que la pequea


capacidad de un Arduino no est reida con la calidad y se puede crear una web

funcional y a la vez esttica. No es creacin ma. El cdigo HTML lo ha realizado


un webmaster y diseador web de categora. Calidad, eficacia, eficiencia y estilo
son su sea de identidad. Si este tema te interesa, te recomiendo que le eches
un vistazo a sus perfiles en las redes sociales. Actualmente est empezando un
nuevo proyecto, un startup que sin duda nos dejar boquiabiertos. Los
comienzos nunca son fciles pero l lleva la clave del xito en el ADN.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

EthernetServer server(80);
void setup() {
// Serial.begin(9600);
// while (!Serial) {
// ;
// }
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
if (c == '\n' && currentLineIsBlank) {

45
46
client.println("HTTP/1.1 200 OK");
47
client.println("Content-Type: text/html");
48
client.println("Connection: close");
49
client.println("Refresh: 5");
50
client.println();
51
client.println("<!DOCTYPE HTML>");
52
client.println("<html lang='es'>");
53
client.println("<head>");
54
client.println("<meta charset='UTF-8'>");
55
client.println("<title>");
56
client.println("Casa domtica con EducaChip");
57
client.println("</title>");
58
client.println("<link");
59
client.println("href='http://fonts.googleapis.com/css?family=Roboto:300|
60 Playfair+Display:400'");
61
client.println("rel='stylesheet'");
62
client.println("type='text/css'/>");
63
client.println("<link rel='stylesheet'");
64
client.println("href='http://static.tumblr.com/pjglohe/2qinf00ga/estilos.min.c
65 ss'>");
66
client.println("</head>");
67
client.println("<body>");
68
client.println("<div class='page-wrap'>");
69
client.println("<header class='header'>");
70
client.println("<h1>");
71
client.println("La casa domtica de EducaChip");
72
client.println("</h1>");
73
client.println("<div class='educachip'>");
74
client.println("<span>Realizado por </span>");
75
client.println("<a href='http://www.educachip.com' target='_blank'>");
76
client.println("www.educachip.com");
77
client.println("</a>");
78
client.println("</div>");
79
client.println("</header>");
80
client.println("<section class='content-wrap'>");
81
client.println("<div class='device'>");
82
client.println("<div class='device-name'>");
83
client.println("<h2>");
84
client.println("Dispositivo #1");
85
client.println("</h2>");
86
client.println("</div>");
87
client.println("<div class='forms'>");
88
client.println("<form class='transition button on'>");
89
client.println("<input type='button' value='ON'/>");
90
client.println("</form></div><div class='forms'>");
91
client.println("<form class='transition button off'>");
92
client.println("<input type='button' value='OFF'/>");
93
client.println("</form>");
94
client.println("</div>");
95
client.println("</div>");
96
client.println("<div class='device'>");
97
client.println("<div class='device-name'>");
98
client.println("<h2>");
99
client.println("Dispositivo #2");
10
client.println("</h2>");
0
client.println("</div>");
10
client.println("<div class='forms'>");
1
client.println("<form class='transition button on'>");
10
client.println("<input type='button' value='ON'/>");
2
client.println("</form>");

10
client.println("</div>");
3
client.println("<div class='forms'>");
10
client.println("<form class='transition button off'>");
4
client.println("<input type='button' value='OFF'/>");
10
client.println("</form>");
5
client.println("</div>");
10
client.println("</div>");
6
client.println("</section>");
10
client.println("</div>");
7
client.println("</body>");
10
client.println("</html>");
8
10
break;
9
}
11
if (c == '\n') {
0
11
currentLineIsBlank = true;
1
}
11
else if (c != '\r') {
2
11
currentLineIsBlank = false;
3
}
11
}
4
}
11
5
delay(1);
11
6
client.stop();
11
Serial.println("client disonnected");
7 }
11 }
8
11
9
12
0
12
1
12
2
12
3
12
4
12
5
12
6
12
7
12
8
12
9
13
0
13
1
13
2
13

3
13
4

Aqu te dejo una muestra de cmo luce el resultado.

You might also like