Ethernet Shield: problema nel gestire un host

Salve. Sto realizzando un controllo da remoto con Arduino Uno e scheda Wiznet W500 e sono riuscito a gestire senza problemi lo Shield in rete locale, sia con l'esempio "WebServer" e sia con uno sketch che ho trovato in rete per comandare dei led.
Ora sto provando a comandare lo Shield da una rete esterna (quella dello smartphone): per questo ho creato un host su no-ip.com e ne ho inserito i dati all'interno di questo sketch:

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 
modified for no-ip client example
by Jerry Sy aka doughboy
 */

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// 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() {
  // start the serial library:
  Serial.begin(9600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // 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("dynupdate.no-ip.com", 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    //replace yourhost.no-ip.org with your no-ip hostname
    client.println("GET /nic/update?hostname=ilmiohost.no-ip.biz HTTP/1.0");
    client.println("Host: dynupdate.no-ip.com");
    //encode your username:password (make sure colon is between username and password) 
    //to base64 at http://www.opinionatedgeek.com/dotnet/tools/base64encode/
    //and replace the string below after Basic with your encoded string
    //clear text username:password is not accepted
    client.println("Authorization: Basic *****************"); 
    client.println("User-Agent: ilmionhost Client/0.0 lamiamail");
    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:
    for(;;)
      ;
  }
}

E questa è la mia risposta sul serial monitor:

https://drive.google.com/file/d/0B4bjpRHcU_eSRkM3NFJPbHBoWm8/edit?usp=sharing

Quello che ho capito è di essere riuscito ad accedere con l'Arduino al mio host, almeno credo. Il problema sta nel fatto che quando accedo al mio host (dallo smartphone o da PC) all'indirizzo http://www.noip.com/nic/update?hostname=ilmiohost.no-ip.biz mi appare sempre e comunque la scritta "nochg" (oppure la scritta "good" seguita dall'indirizzo IP), indipendentemente da ciò che scrivo nel void loop. Come faccio quindi a far apparire, ad esempio, la pagina dello sketch "WebServer" nel mio host? Perché ho provato ad unire lo sketch che ho riportato sopra con "WebServer" ma nulla da fare. Grazie.

Benvenuto. :slight_smile:
Ti invitiamo a presentarti qui: Re: Presentazioni nuovi iscritti, fatevi conoscere da tutti! (Part 1) - Generale - Arduino Forum
e a leggere il regolamento: [REGOLAMENTO] Come usare questa sezione del forum - Italiano - Arduino Forum

nid69ita:
Benvenuto. :slight_smile:

Grazie dell'accoglienza. ^^

Nessuno ha suggerimenti?

Personalmente non ti saprei aiutare.
Pazienta, speriamo che qualcuno che conosce un pò la Ethernet sappia risponderti.

Ma nel tuo sketch non c'e' un WebServer. Credo che devi metterlo, lavorare su porta 80 e poi forse il firewall del tuo router deve essere configurato per permettere dall'esterno di ricevere e inviare dati sulla porta 80.
Ma non me ne intendo. Aspetta risposte più autorevoli.

quelle risposte che ottieni sono simbolo di successo .

qui puoi vedere Interpret Response

in effetti non c'è nessuna pagina da visualizzare.
Devi distinguere prima di tutto la differenza tra client e server. In parole povere il server non fa mai domande, ma è sempre in ascolto , il client si collega al server > fa la domanda > il server risponde > fine della connsessione

tu fai solo una richiesta al server no-ip esso ti risponde e fine della connessione, in quel momento arduino è un webclient e non un webserver.

ora devi aggiungere la parte webserver che non deve essere mischiata alle linee di istruzioni del webclient, ma sarà un pezzo di codice indipendente dove arduino sarà in ascolto poichè diventa server

ciao

nid69ita:
Credo che devi metterlo, lavorare su porta 80 e poi forse il firewall del tuo router deve essere configurato per permettere dall'esterno di ricevere e inviare dati sulla porta 80.

Da quanto ho visto in rete so che c'è un modo per raggiungere l'host dall'esterno senza modificare le impostazioni del router (attraverso appunto il servizio di no-ip.com o un altro sito simile), ed è ciò che vorrei fare perché ammesso che tutto funzioni avrei bisogno di collegare l'Arduino ad una rete diversa da quella di casa mia e su cui non posso cambiare configurazioni.

pablos:
quelle risposte che ottieni sono simbolo di successo .

qui puoi vedere Interpret Response
Integrate with No-IP DDNS - API Response Information

in effetti non c'è nessuna pagina da visualizzare.
Devi distinguere prima di tutto la differenza tra client e server. In parole povere il server non fa mai domande, ma è sempre in ascolto , il client si collega al server > fa la domanda > il server risponde > fine della connsessione

tu fai solo una richiesta al server no-ip esso ti risponde e fine della connessione, in quel momento arduino è un webclient e non un webserver.

ora devi aggiungere la parte webserver che non deve essere mischiata alle linee di istruzioni del webclient, ma sarà un pezzo di codice indipendente dove arduino sarà in ascolto poichè diventa server

ciao

Scusate ho sbagliato non inserendolo subito, ma il codice completo è questo (in cui ottengo la stessa e identica risposta dell'esempio che ho riportato di sopra pur essendoci la parte dello sketch "WebServer")

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 
modified for no-ip client example
by Jerry Sy aka doughboy
 */

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// 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() {
  // start the serial library:
  Serial.begin(9600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // 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("dynupdate.no-ip.com", 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    //replace yourhost.no-ip.org with your no-ip hostname
    client.println("GET /nic/update?hostname=ilmiohost.no-ip.biz HTTP/1.0");
    client.println("Host: dynupdate.no-ip.com");
    //encode your username:password (make sure colon is between username and password) 
    //to base64 at http://www.opinionatedgeek.com/dotnet/tools/base64encode/
    //and replace the string below after Basic with your encoded string
    //clear text username:password is not accepted
    client.println("Authorization: Basic *****************"); 
    client.println("User-Agent: ilmionhost Client/0.0 lamiamail");
    client.println();
  } 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  // listen for incoming clients
  EthernetClient client = client.connect("dynupdate.no-ip.com", 80);
  
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(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");  // the connection will be closed after completion of the response
	  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");       
          }
          client.println("</html>");
          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();
    Serial.println("client disonnected");
  }
}

In cui ho modificato questa riga di codice dell'esempio "WebServer"
" EthernetClient client = server.available(); "
Con
" EthernetClient client = client.connect("dynupdate.no-ip.com", 80); "
Ma sono abbastanza incerto su questa parte.

Grazie delle risposte.

Da quanto ho visto in rete so che c'è un modo per raggiungere l'host dall'esterno senza modificare le impostazioni del router (attraverso appunto il servizio di no-ip.com o un altro sito simile), ed è ciò che vorrei fare perché ammesso che tutto funzioni avrei bisogno di collegare l'Arduino ad una rete diversa da quella di casa mia e su cui non posso cambiare configurazioni.

non puoi farlo.

Il servizio no-ip serve solo per far conoscere al client che chiama arduino l'ip del router nel caso cambiasse.
Raggiungere arduino all'interno di una rete sconosciuta impostato come webserver e senza impostare i dovuti forwarding e porte non lo puoi fare.

Se tu hai un router che ha un IP verso l'esterno es 216.239.32.0 un gateway interno tipo 192.168.1.1 e il tuo arduino 192.168.1.177 (Ip statico) . Come faccio dall'esterno a raggiungere una macchina all'interno di una rete locale?

chiamo da "internet" l'ip 216.239.32.0:14500 dove nel router è stato stabilito che tutte le richieste e dati che arrivano sulla porta 14500 devono essere reindirizzati verso l'ip interno 192.168.1.177 su porta 80.
Se tu volessi aggiungere un altro arduino nella stessa rete lo indirizzi con 192.168.1.178 e lo chiami con es. 216.239.32.0:14600 .... e così via.
Quello che fa no-ip è farti conoscere quel 216.239.32.0 che potrebbe cambiare (Ip dinamico), tra le altre cose lo hai messo nel setup() operazione del tutto inutile se arduino resta accesso a tempo indeterminato nel giro di qualche giorno non lo trovi più.

Se tu vuoi piazzare arduino in qualsiasi rete e fregartene delle sue impostazioni allora ti conviene fare l'opposto.
Ti prendi uno spazietto web host anche free, ti crei una paginetta in php su questo server e raccogli le informazioni che arduino ogni tanto gli spedisce.
Arduino sarà un client che ricava un ip tramite il protocollo DHCP così non devi neppure sapere gli IP di quella rete, eviti eventuali conflitti, esso manderà i dati al tuo server, tu ti colleghi alla pagina su questo server e ottieni gli stessi risultati. Per commutare un pin in questo caso dovrai farlo sulla risposta del server, potrai farlo solo quando arduino chiama però.

pablos:
non puoi farlo.

Capisco, ti ringrazio : ) Vorrà dire che proverò a gestire una pagina php come hai detto, anche se mi sembra abbastanza complicato considerando che conosco veramente poco al riguardo.