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.