Utilizzando l’ethernet shield possiamo pilotare da remoto le uscite dell’Arduino

Continuiamo la serie di articolo per il controllo da remoto del nostro Arduino. Negli articoli precedenti abbiamo visto come sia semplice leggere lo stato dei pin digitali e come acquisire dei segnali con gli ingressi analogici della scheda.
Questo articolo vedrà di utilizzare il browser per inviare dei comandi alla board Arduino UNO, tramite protocollo http, per pilotare le uscite dei in digitali.

La prima operazione da decidere riguarda la scelta dei pin che intendiamo impiegare come uscite in questo esempio ho decido di configurare i pin2 e il pin3.

void setup()
{
//inizializza lo shield con il mac e l'ip
Ethernet.begin(mac, ip);
//inizializza l'oggetto server
ArduinoServer.begin();
//definisco i pin6 e pin7 come ingressi
pinMode(6, INPUT);
pinMode(7, INPUT);

//definisco i pin2 e pin3 come uscite
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
}

 

Adesso dobbiamo capire come inviare via browser dei comandi all’Arduino. Questo è possibile utilizzando la barra degli indirizzi del browser, infatti inserendo del testo dopo l’indirizzo ip della board possiamo recuperarlo utilizzando la funzione read(). Per capire meglio, l’esempio seguente illustra le varie fasi:

inserisco, nel browser, l’indirizzo ip della board e del testo aggiuntivo:

http://10.192.1.251/testo_personalizzato

dopo aver premuto il tasto invio o il pulsante vai, il browser invierà alla board questa informazione:

GET /testo_personalizzato HTTP/1.0

I singoli byte letti dalla funzione read() vengono concatenati per ricostruire l’intera stringa http. Questo avviene creando un oggetto String  e utilizzando l’istruzione di concatenamento +=

//Dichiaro un oggetto String
String msg = "";

...

//leggo i byte disponibili
//provenienti dal client
Data_RX = pc_client.read();

//ricostruisco la stringa ricevuta concatenando i singoli byte
msg += Data_RX;

...

 

Quando termino di leggere tutti i byte inviati dal browser, l’oggetto msg conterrà l’intero dato, così come inviato dal browser

GET /testo_personalizzato HTTP/1.0

utilizzando il metodo indexOf() dell’oggetto msg posso controllare se all’interno di questa stinga è presente un particolare teso, ad esempio per verificare la presente del testo HTTP dovrò scrivere

int occorrenza = msg.indexOf(“HTTP”);

il valore restituito rappresenta il numero di occorrenze trovate all’interno della stringa msg, in questo caso il testo HTTP è presente una sola volta quindi la variabile occorrenza conterrà il valore 1.

Di conseguenza per pilotare l’uscita pin2 al livello alto potremmo scrivere sulla barra dell’indirizzo del browser qualcosa del tipo

http://10.192.1.251/PIN2ON

in questo caso la stringa msg sarà uguale a

GET /PIN2ON HTTP/1.0

il metodo indexOf dovrà cercare la stringa PIN2ON e, in base al risultato, attivare o meno l’uscita dell’Arduino. Il codice seguente realizza quanto esposto

...

//cerco all'interno della stringa il parametro che mi interessa
cmd = msg.indexOf("LEDON");

if (cmd > 0)
digitalWrite(2, HIGH);
else
digitalWrite(2, LOW);

...

 

Per chiarezza inserisco tutto il codice dello sketch :

/*
Semplice Controllo remoto
Settembre 2011
Marco Lai
*/

//Librerie impiegate per il progetto
#include <SPI.h>
#include <Ethernet.h>

//Creao un array di byte per specificare il mac address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//creo un array di byte per specificare l'indirizzo ip
byte ip[] = {10, 192, 1, 251}; //modificate questo valore in base alla vostra rete

char Data_RX;

String msg = "";
int cmd = 0;

//creao un oggetto server che rimane in ascolto sulla porta
//specificata
Server ArduinoServer(80);

void setup()
{
//inizializza lo shield con il mac e l'ip
Ethernet.begin(mac, ip);
//inizializza l'oggetto server
ArduinoServer.begin();

//definisco i pin2 e pin3 come uscite
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);

}

void loop()
{
//IMPORTANTE pulisco la variabile msg
msg = "";

Client pc_client = ArduinoServer.available();

//controllo se pc_client è true
if (pc_client != false)
{
//controllo continuamente che il client sia connesso
while (pc_client.connected())
{
//Controllo se ci sono byte disponibili per la lettura
if (pc_client.available())
{
//leggo i byte disponibili
//provenienti dal client
Data_RX = pc_client.read();

//ricostruisco la stringa ricevuta concatenando i singoli byte
msg += Data_RX;

//Attendo che tutti i byte siano letti
//quando Data_RX contiene il carattere
//di nuova line capisco tutti i byte sono
//stati letti
if (Data_RX == '\n')
{
//cerco all'interno della stringa il parametro che mi interessa
cmd = msg.indexOf("LEDON");

//Invio la risposta al client
//invio lo status code
pc_client.println("HTTP/1.1 200 OK");
//imposto il data type
pc_client.println("Content-Type: text/html");
pc_client.println();
//invio codice html
pc_client.print("<html><body>");
pc_client.print("<head>");
//questo codice html permette di eseguireil refresh automatico
//della pagina html
pc_client.print("<META HTTP-EQUIV='refresh' CONTENT='5; /'>");
pc_client.print("</head>");

//Piloto l'uscita e invio lo stato al browser
if (cmd > 0)
{
digitalWrite(2, HIGH);
pc_client.print("<p>PIN2 Attivo</p>");
}
else
{
digitalWrite(2, LOW);
pc_client.print("<p>PIN2 NON Attivo</p>");
}

pc_client.print("</body></html>");

//aspetto 1 ms affinche la risposta giunga al browser del client
delay(1);
//esco dal ciclo while una volta completato l'invio della risposta
break;
}
}
}
//chiudo la connessione
pc_client.stop();
}
}

 

Utilizzando questo metodo possiamo attivare le uscite dell’Arduino ma anche inviare altri comandi che ad esempio generano un segnale pwm piuttosto che inviare dati tramite la porta UART ad altri dispositivi; le possibilità sono tante e permettono un controllo remoto completo ed efficiente.