Conectar Arduino a una red Ethernet

EtherShield

Objetivos

    • Montar el Shield Ethernet W5100
    • Conectarlo a nuestra LAN (red local).
    • Configurar los valores por DHCP.
    • Configurar los valores manualmente

Material requerido

 arduino
  • Arduino Uno o similar. Esta sesión acepta cualquier otro modelo de Arduino.
 Img_3_4
  •  Una Protoboard.
 Img_3_6-300x185
  • Algunos cables de Protoboard.
EtherShield-150x150
  • Un Un Shield Ethernet (W5100).
RJ45_Cable-300x192
  • Un cable rj45.
concentrador
  • Acceso a la red local.

A este tipo de placas prediseñadas para encajar en los pines de nuestros arduinos se les llama genéricamente Shields (Escudos), y en esta sesión vamos a utilizar un shield Ethernet que nos da acceso a la red local de que dispongamos.

El Shield Ethernet y W5100.

EtherShield

El shield tiene un conector ethernet estándar RJ45. Este shield dispone de unos conectores que permiten conectar a su vez otras placas encima y apilarlas sobre la placa Arduino.

Arduino usa los pines digitales 10, 11, 12, y 13 (SPI) para comunicarse con el W5100 en el ethernet shield. Estos pines no pueden ser usados para entradas o salidas genéricas.

El botón de reset del shield resetea ambos, el W5100 y la placa Arduino.

El shield contiene LEDs para información:

  • ON: indica que la placa y el shield están alimentadas.
  • LINK: indica la presencia de un enlace de red y parpadea cuando el shield envía o recibe datos.
  • 100M: indica la presencia de una conexión de red de 100 Mb/s (de forma opuesta a una de 10Mb/s).
  • RX: parpadea cuando el shield recibe datos.
  • TX: parpadea cuando el shield envía datos.

El jumper soldado marcado como “INT” puede ser conectado para permitir a la placa Arduino recibir notificaciones de eventos por interrupción desde el W5100, pero esto no está soportado por la librería Ethernet. El jumper conecta el pin INT del W5100 al pin digital 2 de Arduino.

Para encajar el shield en nuestro Arduino:

  • Hacedlo con el Arduino apagado.
  • Los pines tienen que encajar con suavidad primero, y después presionar cuidadosamente para que se una a Arduino. Sin forzarlo.
  • Aseguraros de que todos y cada uno de los pines encaja en los conectores de abajo.

Una vez que haya encajado podéis alimentar el Arduino y luego conectar el cable de red, debería tener un aspecto similar a este, y veréis parpadear una serie de LEDs:

SKU083549C
Con el cable Ethernet con RJ45 en ambos extremos, uno de ellos va al Shield y el otro al Router o Swicth de que dispongas.

Probando la conexión con DHCP

Tenemos que comprobar que la conexión es válida. Normalmente incluirá un LED bajo el conector que se encenderá con el cable conectado al Swicth, y se apagará si lo sueltas. (Y lo mismo ocurrirá en el Swicth, que encenderá un piloto en el frontal, cuando detecte la conexión Ethernet.

Vamos lo primero a buscar una dirección IP valida. Para ello y por simplificar vamos a comprobar si en vuestra red existe un servidor DHCP,  para asignarnos una dirección IP al arrancar.

Vamos a probar con uno de los ejemplos que vienen con la librería Ethernet, que por cierto viene preinstalada en el IDE de Arduino.

Tenemos que importar en primer lugar un par de librerías, SPI y Ethernet. Podéis hacerlo directamente desde \\Programa\incluir libreria.

#include <Dhcp.h>
#include <EthernetClient.h>
#include <EthernetUdp.h>
#include <Dns.h>
#include <EthernetServer.h>
#include <Ethernet.h>

#include <SPI.h>

Ahora vamos a definir una dirección mac. Lo normal es que no os de problemas la habitual, pero si vais a usar más de un Shield, necesitareis cambiar al menos una. Tiene que ser diferentes para cada nodo.

byte mac[] = {0x00,0xAA,0xBB,0xCC,0xDE,0x02};

Y ahora vamos a crear una instancia de cliente Ethernet:

EthernetClient client;

En el setup, inicializamos el puerto serie:

void setup()
   {
       Serial.begin(9600);
       while (!Serial){
      }
   }

En las versiones actuales de la librería Ethernet, si no suministramos una dirección IP propia, al inicializar Ethernet, intentara conseguir una dirección mediante DHCP automáticamente, y devolverá 1 si lo consigue y 0 en caso contrario:

if (Ethernet.begin(mac) == 0) //Si devuelve error
   {       
    Serial.println("No ha sido posible configurar Ethernet por DHCP");
    while (true); // No sigas,....
   }

Si por el contrario devuelve un valor positivo, habrá rellenado un array Ethernet.localIP()[4],de 4 bytes, con la dirección IP obtenida del DHCP.

Serial.print("Mi direccion IP es: ");
for (byte B = 0; B < 4; B++)   
   {
       Serial.print(Ethernet.localIP()[B], DEC);
       Serial.print(".");
    }
 Serial.println();

El programa imprimirá, la dirección IP obtenida.

Podemos conocer más datos de red con las siguientes instrucciones:

Serial.print(“Router por defecto : “);
for (byte B = 0; B < 4; B++) {
Serial.print(Ethernet.gatewayIP()[B], DEC);
Serial.print(“.”);
}
Serial.println();

Serial.print(“Subred: “);
for (byte B = 0; B < 4; B++) {
Serial.print(Ethernet.subnetMask()[B], DEC);
Serial.print(“.”);
}
Serial.println();
Serial.print(“DNS: “);
for (byte B = 0; B < 4; B++) {
Serial.print(Ethernet.dnsServerIP()[B], DEC);
Serial.print(“.”);
}
Serial.println();

La salida es esta:

IMAGEN

Si recurrís al DHCP, tenéis que ser conscientes de que tiene un coste en uso de memoria. Si queréis economizarla especificad solamente la IPAddress.ip y Arduino asignara por defecto al Gateway la dirección 1 dentro de la subred.

Que hacemos si no tenemos DHCP

Si en nuestra red no hay disponible un servidor DHCP, o necesitamos la memoria que usa, tenemos que determinar nuestro rango de direcciones y asignarlas manualmente a nuestro Shield Ethernet.

En Windows tenemos que abrir la configuración de red. El procedimiento depende mucho de la versión, pero si podéis abrir la consola del sistema acabaremos enseguida.

Normalmente, al pulsar el boto de inicio, abajo del todo hay una ventana en la que puedes escribir que pone “Buscar programas y archivos”, escribe CMD y pulsa intro. Te saldrá la consola. Escribe el comando  ipconfig (en linux ifconfig) y pulsa intro.

En windows:

Selecc_01

En linux:

ifconfig

Esos valores muestran los datos de tu conexión. Como mi dirección IP es la 192.168.1.50, lo lógico es probar una dirección del tipo 192.168.1.xx, donde xx es un valor entre 0 y 255, que no coincida con otra dirección de tu red.

Para forzar a nuestro Shield a una dirección determinada, sin recurrir al DHCP, podéis hacerlo creando antes de llamar a Ethernet.begin (mac), uno o varios arrays de 4 bytes:

byte mac[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192,168,1, 177);
IPAddress gateway(192,168,1, 1);
IPAddress subnet(255, 255, 0, 0);
  • Con definir la IPAddress.ip es suficiente. El resto de los valores se asignan por defecto.
  • Además si no vamos a salir a Internet, ni acceder a nuestro Arduino desde internet, no será necesario definir la Gateway.

En Mac podemos ir a Preferencias del Sistema, Red y nos saldrá la configuración directamente:

Img_60_2-600x522

Accediendo a una página WEB desde Arduino.

El IDE incluye un ejemplo muy interesante de acceso a Google por Ethernet y para hacerle una consulta. Vamos a cargarlo y comprobar que nuestra conexión y configuración funcionan correctamente.

Haremos una petición desde nuestro programa de búsqueda en Google y mostraremos el resultado en el puerto serie.

Es importante que tengáis en cuenta lo siguiente:

  •  El volumen de información que genera el acceso a páginas Web es descomunal, aun en los casos más sencillos, porque hay mucha información de gestión que normalmente el usuario no ve y que ahora va a aparecer.
  • Os recomiendo que pongáis la velocidad del puerto serie a 115.200 bps, porque si no, la consola va a tardar lo suyo.
  • Una vez que haya finalizado la recepción de texto HTML en la consola, podéis seleccionar y copiar el texto en un editor externo como el notepad, y guardarlo con la extensión HTML y no txt cuidado.
  • Haciendo doble click en el fichero así guardado os abrirá el navegador con la respuesta,

Si vas a buscar datos concretos en el texto recibido prepararos para hacer parsing (análisis) abundante y es fácil que un UNO se os quede corto de memoria.

Aquí teneis una copia del ejemplo Ethernet\WebClient:

#include <SPI.h>
#include <Ethernet.h>byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = “www.google.com”;    // name address for Google (using DNS)// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println(“Failed to configure Ethernet using DHCP”);
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println(“connecting…”);

// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println(“connected”);
// Make a HTTP request:
client.println(“GET /search?q=arduino HTTP/1.1”);
client.println(“Host: www.google.com”);
client.println(“Connection: close”);
client.println();
} else {
// if you didn’t get a connection to the server:
Serial.println(“connection failed”);
}
}

void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}

// if the server’s disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println(“disconnecting.”);
client.stop();

// do nothing forevermore:
while (true);
}
}