Se non potesse comunicare con il mondo esterno, Arduino sarebbe soltanto un giocattolo e poco altro: solo uno strumento divertente per imparare i fondamentali dell’elettronica. Fortunatamente, Arduino è molto più e con l’aiuto di una semplice Ethernet shield possiamo metterlo in contatto con il mondo reale, tramite internet.
Vediamo allora come utilizzare la nostra Ethernet shield per interagire con il web!
Per prima cosa montiamo la shield su Arduino, colleghiamo un cavo di rete al router e il cavo USB ad Arduino. La shield si incastra senza problemi, due pin restano fuori ma fa lo stesso. Una volta sistemato il tutto, siamo pronti per “entrare in contatto” con internet.
La prima cosa da fare è aprire l’IDE di Arduino e importare le librerie <SPI.h> e <Ethernet.h>; se andate in alto, nel menu: Sketch > Importa libreria… e scegliete Ethernet, vedrete che in automatico verranno importate molte librerie. Potete cancellarle tutte tranne le due appena menzionate, non ci serviranno.
Per poter collegare Arduino al web, occorre prima di tutto indicare l’indirizzo MAC della Ethernet shield. Non è così complicato, potete trovare l’indirizzo sul retro della scheda oppure metterne uno fittizio. L’indirizzo MAC è solo per identificare la scheda nel caso ne abbiate più di una in rete, ma potete anche inventarne uno. L’unica cosa da ricordare è che va scritto in formato esadecimale (ossia, basta aggiungere 0x prima di ogni coppia di lettere e numeri), la seconda è che va dichiarato come un array di bytes. In realtà è molto semplice, vediamo:
byte mac[] = { 0xDD, 0xAB, 0xCE, 0xFF, 0xEE, 0xED }; // MAC address
Fatto questo, dobbiamo assegnare alla scheda un indirizzo IP, affinché non venga confuso con altri dispositivi presenti nella nostra rete locale. Per fare questo, possiamo impostare noi un indirizzo valido a piacere, oppure fare in modo che sia il ruoter ad assegnarcene uno (DHCP). Vediamo prima come impostarlo da soli:
byte ip[] = { 192, 168, 1, 10 }; // Scrivi un indirizzo valido per la tua rete locale
Bene! Tutto è pronto per partire. Per prima cosa, assicuriamoci che Arduino sia davvero in rete. Scriviamo con calma il codice per la connessione: per farlo dobbiamo utilizzare la funzione Ethernet.begin() che accetta come parametri il MAC address, l’indirizzo IP, il DNS, il gateway e la subnet. Tranquilli, sono quasi tutti facoltativi. Ci servono, in realtà, soltanto i due che abbiamo già creato: MAC e IP.
Ethernet.begin(mac,ip); // Connessione con IP pre-impostato
Se vogliamo utilizzare invece le funzionalità del DHCP (bisogna ovviamente che il nostro router abbia il DHCP abilitato), possiamo lasciare che sia il router ad assegnare in maniera automatica un IP ad Arduino. In questo caso, per connetterci, scriveremo soltanto:
Ethernet.begin(mac) // Connessione con IP assegnato tramite DHCP
La connessione con IP auto-assegnato (che è poi il DHCP) è l’unica variante di Ethernet.begin() che restituisce un valore, che è 1 quando la connessione ha successo. Ma proviamo a connetterci, e vedere se tutto funziona:
void setup() { // Imposto una connessione seriale per verificare i dati Serial.begin(9600); // Connessione Ethernet usando MAC e DHCP (IP dinamico) Ethernet.begin(mac); // Diamo alla Ethernet shield un secondo per inizializzarsi delay(1000); // Stampa sul monitor seriale l'indirizzo IP di Arduino Serial.print("Indirizzo IP: "); IPAddress myIPAddress = Ethernet.localIP(); Serial.println(myIPAddress); }
Fantastico! Il nostro Arduino è in rete!!
Quali fantastiche possibilità ci sono aperte, adesso? Tantissime! Arduino può lavorare in rete sia come server (per rispondere a delle chiamate, mostrare pagine web, o controllare i pin da un browser) – oppure come client, per inviare informazioni a un server o per leggere dati da un servizio o da pagina web. Vediamo di esplorare un po’ meglio quest’ultima possibilità.
Un esempio pratico
Mettiamo allora che siamo interessati alle quotazioni in borsa di una grossa azienda, e vogliamo che Arduino si colleghi ad internet per controllare l’andamento delle nostre azioni. Potremmo anche dirgli di salvarle su scheda microSD, o in un database, per ottenere delle statistiche; ma diciamo che per adesso vogliamo soltanto sapere le quotazioni odierne di Google (GOOG).
Per prima cosa, scriviamo l’indirizzo IP del server che vogliamo contattare. Se non sappiamo l’indirizzo IP, ma soltanto il nome del sito, possiamo lasciare che sia il software a tradurre l’indirizzo automaticamente per noi. È un servizio che si chiama DNS, ma lo vedremo tra breve. Per adesso diciamo che vogliamo andare all’indirizzo di www.google.com:
byte server[] = { 74,125,129,99 }; // Google (http://www.google.com)
Per contattare un sito, si procede in questo modo. È semplice. Basta aggiungere, nella funzione setup(), dopo la funzione Ethernet.begin(), il codice per la connessione. Mettiamo anche il codice per controllare se è tutto a posto.
EthernetClient client; // Imposto Arduino come client if (client.connect(server, 80)) { // Mi collego a Google Serial.println("Connesso"); } else { Serial.println("Connessione fallita"); }
Se volessimo lasciare al DNS, il compito di tradurre il nome del sito nel corrispondente indirizzo IP, dovremmo invece dichiarare il nome del sito come array di caratteri (che è il modo in cui un linguaggio di programmazione come quello utilizzato da Arduino “vede” le parole o le frasi), e poi collegarci in questo modo:
char serverName[] = "www.google.com"; EthernetClient client; // Imposto Arduino come client client.connect(serverName, 80); // Mi collego a Google
A questo punto, se tutto ha funzionato, chiediamo a Google la pagina del servizio finanziario che contiene tutte le informazioni relative all’andamento in borsa di Google. Bastano due righe di codice:
client.println("GET /finance?q=google HTTP/1.0"); client.println(); // FONDAMENTALE per poter leggere i risultati ottenuti!
Nella funzione loop(), andiamo a controllare che tutto stia procedendo correttamente:
void loop() { if (client.available()) { // Se la richiesta della pagina ha avuto successo char c = client.read(); // Leggo la risposta, carattere per carattere Serial.print(c); // Stampo i dati ricevuti sul monitor seriale } if (!client.connected()) { // Quando ho finito, mi scollego Serial.println("Disconnetto."); client.stop(); while(true) ; // Dato che non c'è più nulla da fare, lascio Arduino in attesa (loop infinito). } }
Dopo un paio di secondi, vedrete comparire sul monitor seriale delle parole senza senso. Google purtroppo non formatta il codice delle sue pagine – un po’ per risparmiare spazio, un po’ per rendere più difficile leggere i suoi segreti. Ma se vedete quelle scritte, allora tutto ha funzionato!
Per vedere qual è il valore delle nostre azioni, dobbiamo solo cercarlo all’interno della pagina, e dire ad Arduino di stamparlo! Tecnicamente quello che cerchiamo è il tag <span class=”pr”>: dopo quello c’è un tag che non ci interessa e poi il valore della quotazione.
// Cerco il valore che mi interessa // Gli apici (",') all'interno delle stringhe vanno scritti con lo slash davanti (\",\') if (client.find("<span class=\"pr\">")) { // Salto al successivo '>' client.find(">"); // Ottengo il valore float value = client.parseFloat(); // Stampo il risultato Serial.print("Il valore delle azioni di Google: "); Serial.println(value); }
Questo è tutto!
Download: arduino_ethernet.zip
Lorenzo ha detto:
come posso fare il collegamento ethernet tra due arduino?
studioarduino ha detto:
Ciao Lorenzo. Credo che dovresti usare due Arduino con Ethernet shield: uno come server, l’altro come client. Sto preparando uno studio su come utilizzare Arduino come server, spero potrà essere di aiuto. Torna presto!
Lorenzo ha detto:
Si su quel discorso ci ero arrivato, il problema sta nello scrivere i 2 sketch x il client e x il server al momento di definire la connessione ethernet fra i due attraversi un intellinet 🙂 grazie ciao 🙂
studioarduino ha detto:
Dovresti provare a impostarli entrambi con un IP fisso e dichiarare il primo come server: EthernetServer server(80), l’altro come client: EthernetClient client.
Per farli comunicare devi poi inviare dal client al server una stringa, e leggerla carattere per carattere, in modo da poter interpretare gli eventuali parametri.
Indipendentemente da cosa tu voglia realizzare, in buona sostanza il procedimento è questo!
Lorenzo ha detto:
Si, ma una volta messo l’ip fisso come devo fare nel codice per metterli in comunicazione tra di loro? Grazie
studioarduino ha detto:
Non c’è un “metodo standard” per far comunicare due Ethernet shield, dipende caso per caso, in base a cosa vuoi realizzare. Devi passare i dati di un sensore ad un altro Arduino?
Lorenzo ha detto:
A dire la verità dovevo passare lo stato di un pulsante da client a server…sai come metterli in comunicazione tramite uno switch ethernet 🙂
studioarduino ha detto:
Ho aggiunto un post per mostrare l’utilizzo di Arduino come server. C’è una parte che spiega come il client deve collegarsi al server, e un’altra su come il server deve interpretare la richiesta del client. Spero possa essere utile!
http://wp.me/p31Ef7-3W
Lorenzo ha detto:
Grazie provo a darci un occhiata e spero di capirci qualcosa
Pingback: Arduino server, Arduino client « studioarduino
Marco Bernardoni ha detto:
Ciao come posso usare arduino come web server e inviare email aprendo una modalita client.
studioarduino ha detto:
Ciao Marco.
Per la mia esperienza, ti posso dire che il modo più semplice per inviare un’e-mail è quello di utilizzare la funzione mail() di PHP (o un equivalente: Send in ASP, send_message in Ruby, ecc.).
Purtroppo su Arduino non è possibile installare un vero e proprio web server, con Apache e PHP; quindi ti posso suggerire di implementare l’invio delle e-mail su un server vero e proprio con Apache e PHP: sul server crei una pagina che accetti alcuni parametri (destinatario e messaggio, per esempio) e una funzione che spedisca l’e-mail tramite mail().
Una volta realizzata questa pagina, puoi creare uno sketch per collegare Arduino alla pagina del server, inviare i parametri necessari, e dire al server di inviare l’e-mail. Tieni conto che, a volte, la posta inviata da un server locale non viene consegnata, perché considerata spam. Quindi se fai delle prove dal tuo computer e l’invio non funziona, prova a spostare il codice su un server esterno.
Spero di esserti stato d’aiuto! Buona serata!
Marco Bernardoni ha detto:
Grazie mille, avevo ventilato anch’io l’idea di creare una pagina su un server esterno, magari sul mio sito internet, ma miravo a tenere arduino autonomo. Immaginavo che ci potessero essere delle limitazioni.
Marco Bernardoni ha detto:
Ciao,
ho riscritto lo sketch come mi hai consigliato cioe’ con l’invio mail tramite la funzione di PHP Mail, ma mi trovo ancora in difficolta’ non riesco a collegarmi al server esterno per eseguire lo script.
Ho dichiarato il server cosi’:
char server1[] = “www.maberweb.it”;
EthernetClient client;
E poi ho fatto una void che ho chiamato email:
void email() {
Serial.println(“email”);
Serial.print ( ” Connecting…” ) ; // L’oggetto Serial serve solo a monitorale cosa accade
if ( client.connect ( server1,80) )// Inizia la connessione al server
{
Serial.println ( ” Connected. ” ) ;
client.print ( “GET http://www.maberweb.it/InvioMail.php” ) ;
client.println (” HTTP/1.1″ ) ;
client.println ( “Host: http://www.maberweb.it” ) ;
client.println () ;
Serial.println ( “disconnecting.” ) ;
client.stop();
}
// if the server’s disconnected, stop the client:
else
{
Serial.println();
Serial.println ( “disconnecting.” ) ;
client.stop();
while ( client.status() != 0 ) delay ( 5 ) ;
}
}
Se digito la stringa di GET in internet explorer funziona benissimo.
Grazie ancora
studioarduino ha detto:
Ciao Marco! La prima cosa che mi viene in mente è che forse il client non risolve correttamente l’indirizzo del server: prova magari a stampare la variabile server1 per esserne sicuro. L’altra cosa, forse quella che non fa funzionare lo script, è che una volta collegato al server l’indirizzo della GET dovrebbe essere relativo: prova a scrivere semplicemente: client.print(“GET /invioMail.php”); – forse il problema è soltanto questo! Fammi sapere!
Pingback: Arduino e iOS | studioarduino
Christian ha detto:
Guida spettacolare, ho solo una piccola difficoltà.
Quando fai la ricerca in quello che restituisce il web server:
// Cerco il valore che mi interessa
// Gli apici (“,’) all’interno delle stringhe vanno scritti con lo slash davanti (\”,\’)
if (client.find(“”)) {
// Salto al successivo ‘>’
client.find(“>”);
// Ottengo il valore
float value = client.parseFloat();
// Stampo il risultato
Serial.print(“Il valore delle azioni di Google: “);
Serial.println(value);
}
Io faccio la stessa cosa su una mia pagina facendo una ricerca uguale ma su una pagina che gira sul webserver della mia rete locale
HTML della pagina:
Documento senza titolo
1
Codice Arduino
if (client.find(“”)) {
// Salto al successivo ‘>’
client.find(“>”);
// Ottengo il valore
//float value = client.parseFloat();
int value = client.parseInt();
// Stampo il risultato
Serial.print(“Valore: “);
Serial.println(value);
}
ma non mi restituisce niente, come mai secondo te ?
studioarduino ha detto:
Ciao Christian, grazie per il commento! Non hai postato il codice della tua pagina, però credo che l’errore possa dipendere da una discrepanza tra quello che scrivi (sul webserver) e quello che cerchi di leggere (su Arduino). È probabile che la chiamata alla funzione client.find(“”) non ti porti nel punto giusto del codice, o che il testo trovato in quel punto non sia un numero intero (nel qual caso non funziona client.parseInt()). Puoi provare a fare una ricerca più semplice, per testare cosa riesci a trovare, e poi aggiungere un po’ alla volta qualche client.find() per affinare la ricerca e trovare il valore che ti serve. Continua a seguirci, e buon divertimento con Arduino!
Cosimo ha detto:
Ciao, complimenti per la guida 🙂 volevo chiederti come poter inviare un file testo da arduino in rete. grazie!
studioarduino ha detto:
Ciao Cosimo! Un file di testo… Dipende da cosa devi realizzare. In teoria lo puoi caricare sulla scheda microSD della tua Ethernet Shield e leggerlo da Arduino… Per inviarlo dipende: intendi via FTP, o tramite form? Non è tanto semplice, ma qualcosa si dovrebbe riuscire a fare 🙂
Cosimo ha detto:
ho i due moduli, ethernet e sd, separati, quindi voglio prendere un file testo prova.txt dalla sd e inviarlo tramite l’ethernet sulla rete, c’è un comando?
studioarduino ha detto:
Un comando preciso non c’è. Si tratta più che altro di una routine, ossia di un insieme di comandi.
Ma a chi lo devi inviare il file? a un altro Arduino? a un server FTP?
Qui ho visto una discussione che forse ti può essere d’aiuto:
http://forum.arduino.cc/index.php?topic=93502.0
Federico ha detto:
mi dà questi errori:
$fixed_path/lsz.exe –escape –binary –overwrite $host_file_name $tty_port_id 1>&0
C:\Intel_Galileo_Arduino_SW_1.5.3_on_Windows_v0.7.5\arduino-1.5.3/hardware/arduino/x86/tools/izmir/clupload_win.sh: line 34: /dev/ttyS2: No such device or address
#mv the downloaded file to /sketch/sketch.elf
target_download_name=”${host_file_name##*/}”
echo “Moving downloaded file to /sketch/sketch.elf on target”
Moving downloaded file to /sketch/sketch.elf on target
#$fixed_path/lsz.exe –escape -c “cp sketch /sketch/sketch.elf” $tty_port_id 1>&0
$fixed_path/lsz.exe –escape -c “mv $target_download_name /sketch/sketch.elf; chmod +x /sketch/sketch.elf” $tty_port_id 1>&0
C:\Intel_Galileo_Arduino_SW_1.5.3_on_Windows_v0.7.5\arduino-1.5.3/hardware/arduino/x86/tools/izmir/clupload_win.sh: line 40: /dev/ttyS2: No such device or address
hai idea di come risolverli?
studioarduino ha detto:
Ciao Federico. Sinceramente non ne ho la minima idea!! Stai usando un Arduino Galileo su Windows, immagino. Probabilmente sbagli porta seriale (leggo: /dev/ttyS2: No such device or address). Purtroppo non ho a disposizione una scheda Galileo per verificare: magari puoi provare a dare un’occhiata a questa guida, è fatta molto bene. Qui invece ci sono alcuni accorgimenti, forse il tuo è solo un errore nel caricamento dello sketch. A presto!
met952 ha detto:
Ciao
Ottima guida…io però volevo riuscire a far comunicare arduino e LabView via internet con lo shield ethernet solo che ho due dubbi:
1) labview manda i comandi e arduino li legge quindi quale dei due è server e quale client?
2) utilizzando il protocollo TCP/IP che è comodo i LabView posso comunicare con arduino?
Grazie mille
Fabio ha detto:
Ciao, complimenti davvero spettacolare…
Volevo chiederti una cosa però:
“Vorrei realizzare un sito in C# collegato ad un database all’interno del server, quali attenzioni devo riporre nel costruire il database per poter collegare un arduino come sopra??? E’ fattibile secondo te??? Posso usare più o meno la procedura che hai usato sopra??? Può arduino modificare a sua volta valori nel database così da avere una comunicazione bidirezionale???”
Grazie mille sei un grande e perdona la valanga di domande 😀
Fabio