In questo quattordicesimo capitolo, vedremo come utilizzare Arduino per accedere una lampada da remoto sfruttando un semplice relè.
Per completare l’introduzione alla scheda Ethernet ufficiale di Arduino, è molto utile introdurre il prossimo programma, che mostra come sia possibile accendere un LED da remoto, sfruttando una pagina WEB, che viene generata dallo stesso microcontrollore.
1° Programma: Come accendere da remoto un LED
/** Questo programma mostra come sia possibile inserire del codice HTML all'interno della pagina web del webserver di Arduino*/ #include <SPI.h> #include <Ethernet.h> int pinLED = 9; // pin a cui è connesso il LED boolean acceso = false; // Mac Address di Arduino byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Viene inizializzata la libreria Ethernet di Arduino e il webserver gira sulla porta 80 EthernetServer server(80); void setup() { pinMode(pinLED,OUTPUT); digitalWrite(pinLED,LOW); Serial.begin(9600); // Viene inilizzato il webserver e la connessione di rete Ethernet.begin(mac); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // Vengono ascoltati nuovi client EthernetClient client = server.available(); if (client) { Serial.println("new client"); // Finisce una richiesta HTTP boolean currentLineIsBlank = true; String postText =""; while (client.connected()) { if (client.available()) { char c = client.read(); if(postText.length()<10){ postText +=c; } // Se viene completato l'invio della richiesta HTTP, allora il server invia la risposta if (c == '\n' && currentLineIsBlank) { // Viene fatta una risposta HTTP, in pratica viene creata una pagina WEB in HTML client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // Dopo la risposta la connessione si interrompe client.println(); client.println("<meta charset=UTF-8>"); // serve per inserire i caretteri speciali client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head> <TITLE>Arduino</TITLE> </head>"); // Viene creato il Titolo client.println("<body> <h1> Benvenuto nel Webserver Arduino </h1>"); // Viene inserito del testo client.println("<h3> Attraverso questa pagina è possibile accendere e spegnere un LED </h3>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } // Se l'utente ha premuto l'icona per accendere il LED if(postText.indexOf("?on") >0){ digitalWrite(pinLED,HIGH); Serial.println("Accendi LED"); acceso = true; } // Se l'utente ha premuto l'icona per spegnere il LED if(postText.indexOf("?off") >0 ){ digitalWrite(pinLED,LOW); Serial.println("Spegni LED"); acceso = false; } // Viene cambiata la pagina WEB a seconda che il LED sia spento, oppure acceso if(acceso){ client.println("<a href=\"./?off\"> <img src = \"http://ismanettoneblog.altervista.org/blog/wp-content/uploads/2014/03/led-red.png\"alt = \"Spegni\" ></a>"); client.println("<h3> Il LED è accesa </h3>"); }else{ client.println("<a href=\"./?on\"> <img src = \"http://ismanettoneblog.altervista.org/blog/wp-content/uploads/2014/03/led-green.png\"alt = \"Accendi\" ></a>"); client.println("<h3> Il LED è spento </h3>"); } delay(1); // Viene chiusta la connessione client.stop(); Serial.println("client disconnected"); } }
Ed ecco l’output:
Benvenuto nel Webserver Arduino
Attraverso questa pagina è possibile accendere e spegnere un LED
Il LED è accesa
Quanto è spento il LED, la pagina web si aggiorna e diventa:
Benvenuto nel Webserver Arduino
Attraverso questa pagina è possibile accendere e spegnere un LED
Il LED è spento
Arduino non fa altro che creare una pagina web e rilevare che icona è stata premuta dall’utente. La richiesta che viene effettuata, viene relativa dal pacchetto che viene inviato dal Computer al microcontrollore.
Sebbene la scheda Ethernet ufficiale di Arduino sia davvero ben fatta, è possibile trovare sul mercato un dispositivo che svolge le stesse funzioni, ma che costa molto meno. Il suo nome è ENC28J60.
Ecco il datasheet del dispositivo:
Per maggiori informazioni introduttive al ethernet controller ENC28J60, consiglio di dare un’occhiata agli ottimi tutorial di Luca Dentella, reperibili dal seguente link http://www.lucadentella.it/category/enc28j60-arduino/. Tuttavia, nel corso di questo capitolo e in quelli successivi, sarò possibile conoscere il dispositivo da più vicino. Ora che abbiamo introdotto tutti i componenti, possiamo passare al progetto di comandare da remoto una lampada.
Con Arduino è possibile fare davvero tanti progetti divertenti e utili, sopratutto per facilitare alcune operazioni in casa. Ora vedremo come utilizzarlo, per accendere una lampada da remoto, oppure qualsiasi dispositivo che è collegato alla presa elettrica di casa nostra.
Vediamo un po’ quali sono i dispositivi che occorrono per realizzare questo progetto:
Hardware
- 1 x Arduino Uno Costo 12 Euro, acquistabile su Ebay
- 1 x Scheda Ethernet ENC28J60 Costo 5 Euro, acquistabile su Ebay oppure Ethernet Shield
- 1 x Relè da 220 V 10 A Costo 3 Euro, acquistabile su Ebay
Software
- Arduino IDE
- Libreria per ENC28J60
- Sketch codice relay + Lampada + WebServer
Che cos’è un relay ?
Un relay, dal punto di vista esterno è un semplice interruttore in grado di far passare corrente o no. Questo fenomeno avviene grazie un principio fisico, basato sull’accoppiamento magnetico che viene generato attraverso un passaggio una piccola corrente di eccitazione, che viene erogata dallo stesso Arduino. Ci sono due configurazioni per quanto riguarda il relay:
- NO (Normally open)
- NC (Normally closed)
Queste due configurazioni si differenziano soltanto per il codice che è necessario scrivere in Arduino. La prima configurazione, in caso di spegnimento del relay, non fa passare corrente (il circuito rimane aperto) e affinché la lampada venga accesa è necessario far uscire da Arduino un segnale “HIGH”. La configurazione NC è duale; in caso il relay non fosse alimentato, la corrente passa in questo dispositivo e affinché la lampada sia spenta, è necessario fare un uscire da Arduino un segnale “LOW”.
Ricapitolando dal punto di vista del codice:
Configurazione NO
digitalWrite(relay,LOW); // Luce spenta
delay(1000);
digitalWrite(relay, HIGH); // Luce accesa
Configurazione NC
digitalWrite(relay,LOW); // Luce accesa
delay(1000);
digitalWrite(relay, HIGH); // Luce spenta
Per chi volesse approfondire maggiormente per quanto riguardo questo elemento circuitale, puoi visitare la pagina web di Wikipedia, nella quale si parla delle varie tipologie di relè.
Come collegare i vari cavi tra i dispositivi
I collegamenti che devono essere fatti per far funzionare il progetto sono abbastanza semplici. Abbiamo due dispositivi da collegare ad Arduino: 1) il relè e 2) la scheda Ethernet.
Per quanto riguarda la prima, occorrerà alimentare il relè con 5 V, massa e il pin Out, va collegato al pin di Arduino impostato nel codice, che in questo caso è il 5.
Ora vedremo due programmi per Arduino, uno che funziona per la Scheda Ufficiale Ethernet, mentre l’altro per l’ENC28J60
Il codice per Arduino per il progetto è davvero molto simile a quello per l’accensione di un LED da remoto. Infatti il meccanismo di funzionamento di Relay, dal punto di vista per Arduino è identico a quello per un LED. L’unica variazione introdotta, riguarda il cambio dell’icona per l’accensione della lampada.
/** Questo programma permette di accedere e spegnere una lampada da remoto */ #include <SPI.h> #include <Ethernet.h> int pinLED = 9; // pin a cui è connesso il LED boolean acceso = false; // Mac Address di Arduino byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Viene inizializzata la libreria Ethernet di Arduino e il webserver gira sulla porta 80 EthernetServer server(80); void setup() { pinMode(pinLED,OUTPUT); digitalWrite(pinLED,LOW); Serial.begin(9600); // Viene inilizzato il webserver e la connessione di rete Ethernet.begin(mac); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // Vengono ascoltati nuovi client EthernetClient client = server.available(); if (client) { Serial.println("new client"); // Finisce una richiesta HTTP boolean currentLineIsBlank = true; String postText =""; while (client.connected()) { if (client.available()) { char c = client.read(); if(postText.length()<10){ postText +=c; } // Se viene completato l'invio della richiesta HTTP, allora il server invia la risposta if (c == '\n' && currentLineIsBlank) { // Viene fatta una risposta HTTP, in pratica viene creata una pagina WEB in HTML client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // Dopo la risposta la connessione si interrompe client.println(); client.println("<meta charset=UTF-8>"); // serve per inserire i caretteri speciali client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head> <TITLE>Arduino</TITLE> </head>"); // Viene creato il Titolo client.println("<body> <h1> Benvenuto nel Webserver Arduino </h1>"); // Viene inserito del testo client.println("<h3> Attraverso questa pagina è possibile accendere e spegnere lampada, connessa ad un relè </h3>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } // Se l'utente ha premuto l'icona per accendere il LED if(postText.indexOf("?on") >0){ digitalWrite(pinLED,HIGH); Serial.println("Accendi LED"); acceso = true; } // Se l'utente ha premuto l'icona per spegnere il LED if(postText.indexOf("?off") >0 ){ digitalWrite(pinLED,LOW); Serial.println("Spegni LED"); acceso = false; } // Viene cambiata la pagina WEB a seconda che il LED sia spento, oppure acceso if(acceso){ client.println("<a href=\"./?off\"> <img src = \"http://ismanettoneblog.altervista.org/blog/wp-content/uploads/2014/02/bt_OFF.png\"alt = \"Spegni\" ></a>"); client.println("<h3> La lampada è accesa </h3>"); }else{ client.println("<a href=\"./?on\"> <img src = \"http://ismanettoneblog.altervista.org/blog/wp-content/uploads/2014/02/bt_ON.png\"alt = \"Accendi\" ></a>"); client.println("<h3> La lampada è spenta </h3>"); } delay(1); // Viene chiusta la connessione client.stop(); Serial.println("client disconnected"); } }
Mentre l’Ethernet Shield è semplice da collegare ad Arduino, il microcontrollore ENC28J60 è leggermente un po’ più complicato; infatti sono da collegare ben 6 cavi flessibili. Ci sono i due soliti cavi di alimentazione, VCC(3.3 V, però !) e GND e 4 che servono per ricevere ed inviare i dati su Internet. Ecco una tabella che riassume i collegamenti:
ENC | PATA | Arduino |
---|---|---|
VCC | wire 2 | 3.3v |
GND | wire 1 | GND |
SCK | wire 5 | Pin 13 |
SO | wire 7 | Pin 12 |
SI | wire 6 | Pin 11 |
CS | wire 4 | Pin 8 |
Installazione software dei vari componenti
Le funzioni che permettono di far funzionare la scheda ethernet, non sono presenti in Arduino IDE. Per questo motivo è necessario installare questa libreria, all’interno della cartella “libreries” di Arduino. Per farlo basta scaricare il file in formato .zip, scompattarlo e spostarlo nella cartella di Arduino, senza aprire il programma. In alternativa, è possibile fare questa procedura direttamente dal software IDE.
Ora che la libreria è presente, possiamo procedere al caricamento del file sul nostro Arduino Uno.
/** Questo codice permette di accendere una lampada connessa al relè da remoto, sfruttando la scheda di rete ENC28J60 SCK -> 13 SO -> 12 SI -> 11 CS -> 8 Vcc -> 3.3 V GND -> GND */ #include <EtherCard.h> #define RELAY_PIN 5 #define REQUEST_RATE 5000 static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; char* on = "ON"; char* off = "OFF"; boolean relayStatus; char* relayLabel; char* linkLabel; byte Ethernet::buffer[700]; void setup () { Serial.begin(9600); Serial.println("Getting IP via DHCP"); if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println( "Failed to access Ethernet controller"); if (!ether.dhcpSetup()) Serial.println("DHCP failed"); ether.printIp("My IP: ", ether.myip); // ether.printIp("Netmask: ", ether.mymask); ether.printIp("GW IP: ", ether.gwip); ether.printIp("DNS IP: ", ether.dnsip); Serial.println(); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); relayStatus = false; relayLabel = off; linkLabel = on; } void loop () { word len = ether.packetReceive(); word pos = ether.packetLoop(len); if(pos) { if(strstr((char *)Ethernet::buffer + pos, "GET /?ON") != 0) { relayStatus = true; relayLabel = on; linkLabel = off; } else if(strstr((char *)Ethernet::buffer + pos, "GET /?OFF") != 0) { relayStatus = false; relayLabel = off; linkLabel = on; } digitalWrite(RELAY_PIN, relayStatus); BufferFiller bfill = ether.tcpOffset(); bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n" "<html><head><meta name='viewport' content='width=200px'/></head><body>" "<div style='position:absolute;width:200px;height:200px;top:50%;left:50%;margin:-100px 0 0 -100px'>" "<div style='font:bold 14px verdana;text-align:center'>Relay is $S</div>" "<br><div style='text-align:center'>" "<a href='/?$S'><img src='http://ismanettoneblog.altervista.org/blog/wp-content/uploads/2014/02/bt_$S.png'></a>" "<div>Controlla la lampada<div>" "</div></div></body></html>" ), relayLabel, linkLabel, linkLabel); ether.httpServerReply(bfill.position()); } }
Ora per poter testare entrambi i programmi, le operazioni da fare sono uguali.
Il primo passo è quello di ottenere l’indirizzo ip locale, di Arduino. Per farlo ci sono varie possibilità; la prima è quella di aprire il seriale, oppure l’altra possibilità è quello di scaricarsi un programma per effettuare scansioni degli host, presenti nella propria rete locale.
Ora che abbiamo l’indirizzo IP, apriamo il browser presente nel nostro telefonino e digitiamo il relativo indirizzo. Comparirà una pagina web simile a questa:
Una volta premuto il bottone verde, comparirà una nuova pagina, con la quale sarà possibile spegnere la luce.
Per poter accendere anche da remoto la lampada, occorre aprire la porta 80, dalla pagina di controllo del nostro Router, scegliendo l’IP corrispettivo.