Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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.
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.
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).
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
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:
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.
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.
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
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.
Namecheap: A parte de dominios a muy buen precio, esta web ofrece servicio de
DNS dinmico gratuito.
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.
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:
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
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