Ayuda Ethernet desde fuera

Hola,

con una placa ethernet y dentro de la red de casa con la aplicacion NETIO o sin ella todo funciona , puedo encender led,etc.

Pero al hacerlo desde fuera problemas: he abierto el puerto, dicho que la ip para la placa sea siempre la misma, habilitado el DHCP para la mac e ip, tambien colocado direccion Dyndns expresa, pero no funciona.
todo esto es igual a una camara ip que tengo.

Las preguntas son

-notais que falte algo,
-al poner la direccion dyndns en el sketch no lo admite sino lo pongo entre comillas que si compila, estara bien.
-la direccion mac 0x55,0x54, etc equivaldra a 55:54: del router etc.
-en la ip pongo la ip publica y tampoco funciona

hay un ejemplo en

que explica todo pero al final en el progr. pone una ip interna

el ejemplo con NETIO es
he quitado el gateway y subnet pero no complicarme la vida funciona igual
/*

Simple Webserver sketch for NetIO Application

Tutorial on http://netio.davideickhoff.de

*/

#include <SPI.h>
#include <Ethernet.h>

// CONFIGURATION

byte mac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 }; // MAC address 84.85.88.16.0.36
byte ip[] = { 192, 168, 1, 50 }; // ip-address, please change to fit your network
//byte gateway[] = { 192, 168, 1, 1 }; // Gateway
//byte subnet[] = { 255, 255, 255, 0 };

// example has an RGB diode connected to three pins
int redLed = 5;
int greenLed = 6;
int blueLed = 7;

EthernetServer server(3200);
String readString = String(100); // string for fetching data from address

void setup(){
Ethernet.begin(mac, ip);
server.begin();

// configure LED pins
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);

Serial.begin(9600);
}

void loop(){
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.print(c);
if (readString.length() < 100) {
//store characters to string
readString = readString + c;
}
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();

// conditions for get parameters
if(readString.indexOf("red=") > -1) {
digitalWrite(redLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
}
else if(readString.indexOf("green=") > -1) {
digitalWrite(greenLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
}
else if(readString.indexOf("blue=") > -1) {
digitalWrite(blueLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
}

if(readString.indexOf("status=") > -1 ) {
// status requests
if (readString.indexOf("red") > -1)
client.print(digitalRead(redLed));
else if (readString.indexOf("green") > -1)
client.print(digitalRead(greenLed));
else if (readString.indexOf("blue") > -1)
client.print(digitalRead(blueLed));
else
client.print("invalid parameter");
} else if(readString.indexOf("read=") > -1 ) {
//generic response according to incoming GET parameter
client.print(String(readString.substring(readString.indexOf("=")+1, readString.indexOf("_"))));
} else {
client.print("OK");
}

//clear string for next read
readString="";

break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}

Pues así, a primera vista, lo que falta es el default gateway. A no ser que tengas configurado el router en monopuesto, no puedes poner una IP pública directamente en el arduino.

Te explico. Cuando abres un puerto en el router, lo que estás diciéndole al router, es que los paquetes enviados a la IP pública de éste, y hacia cierto puerto específico (en tu caso el 3200), sean re-enviados a cierta ip privada, dentro de la red privada del router. Una vez recibido el paquete por el arduino, este, tiene que ser capaz de devolver una respuesta, a través del default gateway (o sea, el router), pero si no le dices la IP del router, el arduino no es capaz de saber a quien devolver el paquete.

La librería ethernet, por defecto, suele poner el default gateway acabado en 1, si no se le indica otro.

Yo he probado tu código, abriendo el puerto 3200 en el router hacia la ip del arduino, y poniendo en un navegador http://a.b.c.d/3200 , desde una red externa al router, como por ejemplo desde un smartphone (siendo a.b.c.d la ip pública de mi router) me sale como resultado un OK, de forma que el problema, es de configuración del router.

De todas formas, a mi me gusta indicar todos los parámetros a la configuración de ethernet, de forma que yo añadiría el gateway, la subnet y el dns, que aunque no haga falta, es necesario en el begin de ethernet, si quieres indicar un gateway.

El código quedaría de la siguiente forma:

/*

Simple Webserver sketch for NetIO Application

Tutorial on http://netio.davideickhoff.de

*/

#include <SPI.h> 
#include <Ethernet.h>

// CONFIGURATION 

byte mac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 };  // MAC address 84.85.88.16.0.36
byte ip[]  = { 192, 168, 1, 50 };                     // ip-address, please change to fit your network
byte gateway[] = { 192, 168, 1, 1 };                  // Gateway
byte subnet[]  = { 255, 255, 255, 0 };
byte dn[] = { 192, 168, 1, 1 };
// example has an RGB diode connected to three pins
int redLed = 5;
int greenLed = 6;
int blueLed = 7;

EthernetServer server(3200);
String readString = String(100);      // string for fetching data from address

void setup(){
    Ethernet.begin(mac, ip, dn, gateway, subnet);
    server.begin();

    // configure LED pins
    pinMode(redLed, OUTPUT);
    pinMode(greenLed, OUTPUT);
    pinMode(blueLed, OUTPUT);

    Serial.begin(9600); 
 }

void loop(){
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
       if (readString.length() < 100) {
            //store characters to string
            readString = readString + c;
        }
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          
          
           // conditions for get parameters
          if(readString.indexOf("red=") > -1) {
           digitalWrite(redLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
          }
          else if(readString.indexOf("green=") > -1) {
           digitalWrite(greenLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
          } 
          else if(readString.indexOf("blue=") > -1) {
           digitalWrite(blueLed, (readString.indexOf("=1") > -1) ? HIGH : LOW);
          } 

          if(readString.indexOf("status=") > -1 ) {
            // status requests
            if (readString.indexOf("red") > -1) 
              client.print(digitalRead(redLed));
            else if (readString.indexOf("green") > -1) 
              client.print(digitalRead(greenLed));
            else if (readString.indexOf("blue") > -1) 
              client.print(digitalRead(blueLed)); 
            else 
              client.print("invalid parameter");         
          } else if(readString.indexOf("read=") > -1 ) {
            //generic response according to incoming GET parameter
            client.print(String(readString.substring(readString.indexOf("=")+1, readString.indexOf("_"))));
          } else {
            client.print("OK");
          }

          //clear string for next read
          readString="";
          
          

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}

Saludos
Primero tienes que ver que el puerto que uses no este bloqueado por tu proveedor de Internet. En mi caso el 80 no lo puedo usar.

Pues probar también colocando el router en zona desmilitarizada. Usar NoIP es otra forma gratuita de convertir una IP dinámica en una fija y con un cuasi dominio.

Hola,

muchas gracias por vuestras respuestas.
he podido entender un poco mejor como funciona Carmeloco

Funciona pero no lo acabo de entender.

Creo el problema era que en el DHCP del router habia puesto mal el MAC adress confundido con el byte mac, pero al intentar ponerlo bien no me deja
dice:

DHCP Static IP Lease Error

The Broadband Router cannot add the new static IP lease since either the Mac address or the IP

address conflict with previous rules.

lo he dejado sin nada y funciona pero no se como da paso a una MAC desconocida, todo el resto de aparatos que tengo estan en esta lista. Aunque ponga otra ip u otra MAC siempre dice lo mismo el router es el de movistar.

Respecto al gateway aun lo entiendo menos, si solo le indico Ip y Mac funciona pero si pongo gateway no funciona, he leido que el gateway de ip publica procede de una formula sacada de esta ip. sale un numero raro.no lo he probado

Respecto al DDNS ,hay que dar de alta un nuevo nombre en la cuenta de Dyndns, este nombre ponerlo en el Dinamic DNS del router y este mismo nombre en la config de NETIO.

Saludos

Por lo que veo, tus conocimientos sobre redes no son muy amplios. Mira de buscar manuales e información por internet, ya que mezclas varios conceptos.

Si le pones una ip fija al arduino, el dhcp no lo necesitas para nada. Para abrir un puerto al exterior, se usa nat, no dhcp.

La mac, no es necesaria añadirla al router.

Tengo publicada en la sección de documentación un Tutorial: Control de Arduino con el móvil por Internet

Quizás te ayude.

Jopapa
www.jopapa.me