Creare un update client per sincronizzare l’ host no-ip.com con l’indirizzo del router
L’articolo precedente illustrava come creare un account no-ip.com con relativo host che tenesse traccia dell’ip del router “domestico”. Questa procedura richiede l’installazione di un update client sul pc, nella rete domestica, capace di aggiornare periodicamente l’host remoto.
L’operazione risulta scomoda poiché il PC deve rimanere acceso per effettuare l’aggiornamento. Fortunatamente esiste un metodo basato su richiesta http che permette di utilizzare direttamente Arduino per sincronizzare l’host con l’ip del router.
La richiesta di aggiornamento va indirizzata a uno di questi URL
http://dynupdate.no-ip.com/nic/update
https://dynupdate.no-ip.com/nic/update
mentre la struttura della richiesta deve seguire questo formato
GET /nic/update?hostname=Nomehost&myip=IndirizzoIP HTTP/1.0 Host: dynupdate.no-ip.com Authorization: Basic NomeUtentePasswordBase64 User-Agent: NomeClient/Versione IndirizzoMail
dove
NomeHost = Il nome dell’host come registrato nella procedura Create Host del sito no-ip.com
IndirizzoIP = Qui va messo l’indirizzo ip che vogliamo associare all’host remoto
NomeUtentePasswordBase64 = Qui dobbiamo inserire il nome utente e la password del nostro account no-ip in formato Base64. Il nome utente e la password vanno separati da un segno di due punti (Nomeutente:Password)
NomeClient = Il nome del client che esegue l’aggiornamento (Nome di libera scelta)
Versione = La versione del client che esegue l’aggiornamento (Nome di libera scelta)
IndirizzoMail = il nostro indirizzo mail (Mail di libera scelta)
quindi la richiesta assumerà questa struttura
GET /nic/update?hostname=host.no-ip.com&myip=192.168.1.1 HTTP/1.0 Host: dynupdate.no-ip.com Authorization: Basic aW86YW1vIGlsIHRhZWt3b25kbw== User-Agent: arduino_ethernet/1.0 info@gmail.com
Il problema principale è che Arduino non si riesce a ottenere, direttamente e in modo semplice, l’ip dinamico del router per poterlo inserire nella richiesta http. Fortunatamente omettendo totalmente questo parametro, il servizio dynupdate.no-ip.com utilizza l’ip della connessione che corrisponde proprio all’indirizzo dinamico del nostro router. La richiesta, per funzionare, va riscritta in questo modo:
GET /nic/update?hostname=host.no-ip.com HTTP/1.0 Host: dynupdate.no-ip.com Authorization: Basic aW86YW1vIGlsIHRhZWt3b25kbw== User-Agent: arduino_ethernet/1.0 info@gmail.com
Utilizziamo per questo test direttamnete lo scketch di esempio proposto dall’IDE (File->Examples->Ethernet->WebClient) e modifichiamolo secondo le nostre esigenze.
Per creare la connessione, nello skecth non è possibile immettere direttamente l’url del servizio (dynupdate.no-ip.com) ma il suo relativo indirizzo ip ottenibile tramite il sito mostraip.it.
Modifichiamo il codice:
#include <Dhcp.h> #include <Dns.h> #include <Ethernet.h> #include <EthernetClient.h> #include <EthernetServer.h> #include <EthernetUdp.h> #include <SPI.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac ethernet byte ip[] = { 192, 168, 1, 190 }; //indirizzo locale dell’Arduino byte server[] = {8, 23, 224, 120}; //dynupdate.no-ip.com //creo un client che punta al //servizio dynupdate.no-ip.com sulla porta 80 EthernetClient client; void setup() { //Avvio la connessione Ethernet.begin(mac, ip); //inizializzo la seriale Serial.begin(9600); //aspetto che il chip wiznet sia inizializzato delay(1000); Serial.println("Connessione in corso…"); //se la connessione avviene con successo //invio la richiesta http if (client.connect(server, 80)) { Serial.println("Connesso"); client.println("GET / nic / update ? hostname = host.no - ip.com HTTP / 1.0"); client.println("Host: dynupdate.no - ip.com"); client.println("Authorization: Basic aW86YW1vIGlsIHRhZWt3b25kbw == "); client.println("User - Agent: arduino_ethernet / 1.0 info@gmail.com"); client.println(); } else { //Problemi nella connessione Serial.println("connessione fallita!"); } } void loop() { //restituisco il messaggio inviato dal servizio if (client.available()) { char c = client.read(); Serial.print(c); } //Quando il server si disconnette fermo il client if (!client.connected()) { Serial.println(); Serial.println("Disconessione"); client.stop(); //ciclo infinito for (;;) ; } }
Questo procedimento, secondo me, risolve il fastidioso problema di tenere il pc accesso per eseguire la sincronizzazione tra l’ip del router e l’host remoto, permettendo quindi di creare soluzioni web-based impiegando Arduino.
In allegato trovate un semplice programma che vi permette di convertire il vostro nome utente e la password in una stringaBase64, per far girare il programma dovete avere installato il .net framework 2.0
Related posts
13 Comments
Lascia un commento Annulla risposta
Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.
Articoli popolari
Sorry. No data so far.
.Net micro framework Arduino Arduino Webserver Domotica Flyport I2C IOT Netduino OpenPicus raspberry RTC Speed Test
Ciao Marco,
ho fatto una cosa simile (su Netduino) ma con con DynDns e devo dire che No-Ip ha una maggiore semplicità nelle API, perchè permette di omettere l’indirizzo IP ricavandolo dalla richiesta (come tu hai evidenziato). Con DynDns, invece, è necessario prima ricavare qual’è il proprio IP pubblico (facendo una richiesta GET ad un indirizzo specifico su DynDns, ed estraendo l’IP dalla risposta) per poi inviarlo nella richiesta di aggiornamento.
Buon lavoro,
Paolo.
Ciao Paolo
grazie per il tuo approfondimento. In effetti no-ip risulta più semplice per realizzare un update client sia con Arduino che con Netduino.
A presto e buon lavoro anche a te
Marco
Scrivo qui perchè da novizio non so come raggiungerti. Sono ancora fermo qui: Come realizzare un controllo remoto con Arduino basato su http — Io ho una scheda ENC28j60 della ekitszone.com che per tutto il resto va bene ma qui mi sono piantato.
Se compilo la prima parte dove si mette in ascolto mi da errore con questa scritta : C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:47: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:51: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:55: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:60: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:64: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:68: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:72: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:77: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:81: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:85: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:89: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:93: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:97: error: ‘Ethernet’ is not a class or namespace
se invece cerco di compilare con “controllo remoto” mi dice :
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:31: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:31: error: ISO C++ forbids declaration of ‘Ethernet’ with no type
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp: In function ‘int Ethernet()’:
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:31: error: ‘int Ethernet()’ redeclared as different kind of symbol
C:\arduino-0022\libraries\Ethernet\/Ethernet.h:23: error: previous declaration of ‘EthernetClass Ethernet’
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp: At global scope:
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:34: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:38: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:43: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:47: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:51: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:55: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:60: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:64: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:68: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:72: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:77: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:81: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:85: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:89: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:93: error: ‘Ethernet’ is not a class or namespace
C:\arduino-0022\libraries\Ethernet\Ethernet.cpp.cpp:97: error: ‘Ethernet’ is not a class or namespace
Cosa sto sbagliando? dipende dalla scheda che uso? spero aver una risposta che mi permetta di proseguire perchè mi piacerebbe terminare un progettino (ma ino ino rispetto a quelli che vedo in giro) anche per mia soddisfazione.
Grazie per la dovizia di spiegazioni ed esmpi che metti in rete, sei un punto di riferimento !!! ciao, Arrigo – Trento
Ciao Arrigo
il codice dell’articolo è riferito alla libreria Ethernet scritta per il chip Wiznet5100 montato sulla Ethernet shield e sull’ Arduino Ethernet. Gli errori che genera il compilatore sono giustificati perchè si riferiscono appunto a questo chip mentre nel tuo caso stai utilizzando il chip ENC28J60 della Microchip che ha bisogno, per poterlo utilizzare, della libreria che puoi scaricare sul sito ekitszone.com.
In definitiva il codice che ho scritto non può funzionare sulla tua ethernet shield per incompatibilità, ecco perchè ottieni questi errori.
Per usare la tua shield devi usare la libreria scritta appositamente per la shield.
A presto
Marco
Ciao Marco
in questi giorni ho letto molto dei tuoi lavori-articoli e vedo che sono ottimi per ciò che voglio fare. Provvederò a sostituire la scheda Ethernet in modo da poter seguire (copiare!) i tuoi insegnamenti e vediamo se riuscirò ad accendere la caldaia a casa dei nonni via internet senza arrivare al freddo. Le soluzioni telefonino-dtmf hanno lascito un po di delusione allora ho pensato ad arduino2009 che ho qui e la schedina 4 relè così accenderò la caldaia, leggerò le temperature ecc. e magari anche un piccolo antifurto all’ingresso.
Questo per dirti grazie della tua dedizione. io presto pubblicherò un piccolo articolo si Grix così da condividere gli sforzi anche di un principiante.
Ciao e buon lavoro, Arrigo
Ottimo!
Allora ti auguro buon divertimento con Arduino
A presto
Marco
Ciao Marco,
Ho praticamente copiato il tuo codice, compilandolo con Arduino 1.0 effettuando le piccole modifiche per sfruttare la nuova libreria.
Però quando parte il programma, mi rimanda connessione fallita! e Disconnessione.
Anche con Arduino 0022 ho lo stesso risultato.
Saluti
Ciao
ho riprovato il codice e funziona corretamente. controlla se hai un firewall sul router o se stai usando un proxy.
fammi sapere
ciao
Marco
Ciao Marco,
Non utilizzo un proxy e nelle ipostazioni del mio router il firewall è disabilitato; tuttavia ho da farti un’altra richiesta.
Ho la necessità che il mio arduino si colleghi al seguente sito:
http://www.indirizzo-ip.com/ip.php?.txt
che restituisce IP dinamico del mio router, senza tag html e senza grafica.
Quindi il mio Arduino dopvrebbe collegarsi al sito, ricevere l’IP ed inviarlo su seriale.
Puoi aiutarmi magari usando la libreria Webduino ?
Grazie Saluti
Ciao Domenico
vedo un po come fare e ti mando il codice.
Ciao
Marco
Ciao Marco,
Ho lo stesso stesso problema di Domenico, il comando ” if (client.connect()) ” mi butta direttamente fuori con connessione fallita; non capisco per quale motivo.
Io uso Arduinio 1.0.1, di seguito c’è il codice opportunamente modificato.
#include
#include
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac ethernet
byte ip[] = { 192,168,0,15 }; //indirizzo locale dell’Arduino
byte gateway[] = { 192,168,0,1 }; //indirizzo del mio router
byte server[] = {8,23,224,120}; //dynupdate.no-ip.com
//creo un client che punta al
//servizio dynupdate.no-ip.com sulla porta 80
EthernetClient client;
void setup() {
//Avvio la connessione
Ethernet.begin(mac, ip,gateway);
//inizializzo la seriale
Serial.begin(9600);
//aspetto che il chip wiznet sia inizializzato
delay(1000);
Serial.println(“Connessione in corso…”);
//Serial.println
//se la connessione avviene con successo
//invio la richiesta http
Serial.println(“Connesso”);
client.println(“GET /nic/update?hostname=davide1974.no-ip.org HTTP/1.0”);
client.println(“Host: dynupdate.no-ip.com”);
client.println(“Authorization: Basic ********************************** “);
client.println(“User-Agent: arduino_ethernet/1.0 info@gmail.com“);
client.println();
}
//Problemi nella connessione
//Serial.println(“connessione fallita!”);
//}
//}
void loop()
{
//restituisco il messaggio inviato dal servizio
if (client.available()) {
char c = client.read();
Serial.print(c);
}
//Quando il server si disconnette fermo il client
if (!client.connected()) {
Serial.println();
Serial.println(“Disconessione”);
client.stop();
//ciclo infinito
for(;;)
;
}
}
Grazie
Ciao,
Sei riuscito a risolvere il problema descritto ?
Saluti
Scusami Marco, ho sbagliato è questo il codice che dovevo spedirti:
#include
#include
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac ethernet
byte ip[] = { 192,168,0,15 }; //indirizzo locale dell’Arduino
byte gateway[] = { 192,168,0,1 };
byte server[] = {8,23,224,120}; //dynupdate.no-ip.com
//creo un client che punta al
//servizio dynupdate.no-ip.com sulla porta 80
EthernetClient client;
void setup() {
//Avvio la connessione
Ethernet.begin(mac, ip,gateway);
//inizializzo la seriale
Serial.begin(9600);
//aspetto che il chip wiznet sia inizializzato
delay(1000);
Serial.println(“Connessione in corso…”);
//Serial.println
//se la connessione avviene con successo
//invio la richiesta http
if (client.connect(server, 80)) {
Serial.println(“Connesso”);
client.println(“GET /nic/update?hostname=davide1974.no-ip.org HTTP/1.0”);
client.println(“Host: dynupdate.no-ip.com”);
client.println(“Authorization: Basic ZG90d*************hvby5pdDphYzNhYzM=”);
client.println(“User-Agent: arduino_ethernet/1.0 info@gmail.com“);
client.println();
}
else
{
//Problemi nella connessione
Serial.println(“connessione fallita!”);
}
}
void loop()
{
//restituisco il messaggio inviato dal servizio
if (client.available()) {
char c = client.read();
Serial.print(c);
}
//Quando il server si disconnette fermo il client
if (!client.connected()) {
Serial.println();
Serial.println(“Disconessione”);
client.stop();
//ciclo infinito
for(;;)
;
}
}