Come realizzare un controllo remoto con Arduino basato su http

Il mondo è sempre più connesso, non solo le persone sono presenti su internet ma anche gli oggetti, tramite semplici circuiti, possono collegarsi alla rete, condividendo dati ed interagendo con l’ambiente, acquisendo grandezze fisiche (tramite sensori) o pilotando carichi utilizzando degli attuatori.

Controllare da remoto uno di questi dispositivi è una operazione affascinante sia per l’utilità di questa tecnica sia, perché no, far stupire i nostri amici accendendo una luce di casa tramite web!

Per chi è alle prime esperienze con Arduino, potrebbe pensare che la realizzazione di questo circuito possa essere complicato e costoso.

Fortunatamente il materiale necessario si riduce a una board Arduino UNO e all’Ethernet shield, più qualche componente esterno.

In questo articolo preferisco fare un piccolo accenno nel descrivere il funzionamento del sistema all’interno della rete lan.

Per il controllo remoto, bisogna eseguire alcune configurazioni aggiuntive che vedremmo successivamente.
Lo schema illustra il funzionamento del progetto:

Controllo Remoto con Ethernet Shield ed Arduino UNO

I pc della rete e l’Arduino UNO (con ethernet shield) sono collegati tra loro tramite uno switch.

Il pc eseguirà, usando un browser, delle richieste http, per recuperare, ad esempio, il valore di una tensione applicata su un pin analogico, oppure accendere o spegnere un led, applicato su un pin digitale in uscita.

Colleghiamo la shield ethernet al nostro Arduino UNO, inseriamo un cavo lan dritto, (che dal connettore rg45 dello shield si collega ad una porta qualsiasi dello switch), inseriamo il cavo USB (che dall’Arduino UNO si collega alla porta del pc) e diamo alimentazione a tutto il sistema.

Apriamo l’IDE di Arduino e scriviamo questo codice:

I commenti nel codice spiegano a grandi linee il funzionamento dello stesso. Dopo aver inserito le due librerie che permettono di interfacciarsi all’ethernet shield, definiamo due array di byte, uno che contiene l’indirizzo fisico della scheda di rete (MAC address) e l’altro che contiene l’indirizzo ip.

Successivamente ho creato un oggetto Server che permette di rimanere in ascolto sulla porta specificata, in questo caso la porta 80, proprio quella utilizzata dal protocollo http.

La variabile Data_RX verrà impiegata successivamente per memorizzare i byte provenienti dal client.

Dentro il blocco setup() ci sono due importanti funzioni, la prima (Ethernet.begin(mac, ip);) serve per inizializzare il chip WIZnet con l’indirizzo mac e l’indirizzo IP, la seconda (ArduinoServer.begin();) avvia il server e lo mette in ascolto sulla porta 80 per le avvenutali richieste dei client.

Nel blocco loop() ho inserito un ritardo di 10ms, per il momento non eseguiamo altro.

Questo codice è utile per verificare, tramite un semplice ping, se l’ethernet shield è correttamente configurata e se risponde alle interrogazioni dei client.

Apriamo una finestra dei prompt dei comandi (Start->Esegui->cmd.exe)

Arduino prompt dei comandi

Digitiamo il comando ping seguito dall’indirizzo ip che abbiamo specificato nel codice dello skecth, nel mio caso:

ping 10.192.1.251

se i collegamenti sono corretti, e il codice viene caricato senza intoppi, otterremo la risposta della scheda come illustrato di seguito:

Arduino ethernet shield test ping

Questo semplice test ci permette di escludere problemi di alimentazione della board o errori doviti al cavo di collegamento.

Informazioni base su come configurare l’indirizzo ip

Certamente tutti voi sapete come configurare un indirizzo ip nella rete, ma penso sia necessario, per chi è alle prime armi, scrivere una piccola nota.
L’indirizzo ip identifica univocamente un dispositivo nella rete, probabilmente se utilizzate un router, questo assegnerà in modo automatico un indirizzo ad ogni dispositivo collegato (DHCP).

Per eseguire questi esperimenti dobbiamo disattivare il DHCP (sebbene sia possibile sfruttare questa funzione con Arduino ritengo, per semplicità, di non impiegarla) ed assegnare un indirizzo ip statico univoco ad ogni dispositivo della vostra rete.
Per fare ciò dovete andare nelle impostazioni del router e disattivare DHCP, poi per ogni pc della vostra rete, assegnate un indirizzo ip utilizzando le impostazioni della connessione di rete, tramite il pannello di controllo. Potete seguire questo link che mostra un video su come eseguire questa operazione

http://www.webip.info/cambiare_ip_windows_xp.php

Questo tutorial, invece, è per chi possiede Windows 7

Come impostare un indirizzo IP statico su Windows 7

Ad esempio potremmo impostare il nostro pc con l’indirizzo 192.168.1.10 e la nostra Ethernet Shield con indirizzo 192.168.1.20

Come rispondere ai client

Una volta definiti gli indirizzi ip dei dispositivi della rete, possiamo iniziare a scrivere il codice che effettivamente risponde alle richieste dei client.
All’interno del blocco loop() bisogna creare un oggetto dalla classe Client, necessario ad ascoltare (listening) le richieste dei client.


L’idea di base è che il server aspetta la connessione di un client, controlla se ci sono dati da leggere e di conseguenza crea un oggetto Client.

La funzione ArduinoServer.available() non è bloccante quindi viene eseguita ciclicamente all’interno del blocco loop(), di conseguenza il valore restituito dalla funzione in mancanza di una richiesta client è false.

E’ necessario quindi controllare se l’oggetto pc_client istanziato sia diverso da false prima di poter instaurare la connessione.

All’interno del blocco if utilizzo un ciclo while per eseguire il codice necessario a scambiare dati tra client e server fintanto che la connessione con il client è attiva

Riassumendo, quando la connessione è stabilita, Arduino esegue il codice all’interno del blocco while, questa è la parte più interessante perchè possiamo leggere e scrivere dati attraverso il protocollo di comunicazione http.

Continuiamo controllando se effettivamente ci sono byte da leggere impiegando la funzione read() dell’oggetto pc_client:

 

Ora eseguiamo un semplice test per verificare che il codice sin qui scritto funzioni.

Per avere un riscontro utilizziamo la classe Serial per inviare informazioni di debug tramite Serial Monitor. Inizializziamo, tramite Serial.Begin(9600), la porta seriale nel blocco setup().

Adesso posso controllare il contenuto della variabile Data_RX inviandoli al Serial Monitor.

 

Apriamo Serial Monitor con il relativo pulsante

Serial Monitor

Avviamo il nostro browser preferito, su un pc nella rete dove è collegato l’Arduino con Ethernet shield, e nella barra degli indirizzi digitiamo l’ip assegnato via codice all’ethernet shield.

Il browser eseguirà una richiesta GET che sarà elaborata dall’Arduino e visualizzata sul serial monitor.

Ecco il risultato:

Inserire indirizzo ip arduino

Dati inviati dal browser all'arduino

Anche in questo caso questo semplice test ci da la conferma che il codice appena scritto funziona egregiamente.

Continuiamo ad aggiungere il codice di risposta che l’Arduino invierà al browser che ha effettuato la richiesta GET

 

Verifico il valore di ogni byte letto, tramite l’istruzione if, fino a quando non ricevo un carattere di nuova linea \n (ox0A in esadecimale). Quando si verifica questa condizione la richiesta del client è stata letta completamente e quindi possiamo iniziare ad inviare la nostra risposta tramite la funzione println() dell’oggetto pc_client.

La prima stringa da inviare riguarda lo status code del protocollo http, composta dalla versione del protocollo http(HTTP/1.1) e dal codice 200 OK che specifica al client la corretta elaborazione dei dati.
La seconda stringa specifica il tipo di dati (http Content types) che stiamo inviando al client con il protocollo http.
Queste due stringhe costituiscono l’header della risposta http.

A questo punto inviamo la stringa con il codice html che compone la pagina che verrà inviata al browser sul client. Terminata anche questa operazione non ci resta che uscire dal blocco while con l’istruzione break, e terminare la chiusura della connessione con la funzione stop() per predisporci ad elaborare ulteriori richieste.

Nel prossimo articolo vedremmo come sfruttare gli ingressi analogici per acquisire dei segnali e i pin digitali per attivare dei led.