Arduino con controllo remoto via HTTP

Nei giorni precedenti avevo promesso di postare un codice che permettesse di controllare via web, tramite protocollo http, il nostro Arduino.

Seguendo il suggerimento di un codice facilmente reperibile in rete, ho apportato alcune modifiche ed ho implementato la visualizzazione dei valori di temperatura e luminosità di un ambiente.

Le applicazioni che possono essere create utilizzando questo codice sono una moltitudine, potreste collegare un termostato della caldaia, controllare se alcuni interruttori magneti collegati alle porte e finestre di casa vostra sono stati aperti o chiusi, controllare la temperatura del vostro appartamento, aprire il portone di casa, inviare un allarme acustico, ecc. ecc.

Se avete più idee e fantasia di me non esitate a comunicarmele!!!

Cosa ci serve?

  • Arduino UNO o qualunque Board Arduino
  • Ethernet Shield
  • Stadio pilota con relè
  • Breadboard
  • Fotoresistenza
  • Sensore di temperatura (MCP9700A)
  • Alcune resistenze
  • LED
  • Adattatore USB da 220V AC a 5V DC o Alimentatore DC (5V – 15V) jack maschio 2,1mm
  • Cavo USB (nel caso si utilizzi un alimentatore il cavo USB è superfluo)
  • Multipresa elettrica (da donare alla causa)
  • Cavetteria varia
  • Cavo di Rete RJ-45 (no cross se si utilizza un router o un hub)
  • Smartphone (GPRS – UMTS) o un dispositivo che permetta la navigazione WEB
  • Router con Connessione Internet

Qui sotto riporto un semplice schema dei collegamenti che ho fatto utilizzando il programma opensource Fritzing che consiglio vivamente.

Lo stadio pilota con relè ci serve in quanto Arduino non può erogare più di 40mA pertanto con un piccolo transistor, un diodo ed un paio di resistenze è  possibile controllare un relè alimentao a 5V DC. In questa maniera è possibile anche applicare a valle dello stadio pilota anche carichi alimentati a 220V in corrente alternata, nel mio caso ho collegato una multipresa elettrica con una lampadina da 220V 23W come carico.

Il codice che ho scritto su Arduino crea un mini Server WEB dove è possibile connettersi tramite un client collegato ad internet (nel mio caso un Nokia 5800) e controllare lo stato del sensore di temperatura e della fotoresistenza. In più passando un determinato parametro è possibile attivare via protocollo HTTP una o più uscite.

Qui a fianco sono riportati gli screenshots di quello che veniva visualizzato dal browser del mio Nokia 5800.

In alto i valori del sensore di temperatura e della fotoresistenza, in basso lo stato dell’uscita, nel mio caso il pin 9, e i link ACCENTI – SPEGNI che passano i paramenti ad Arduino per attivare o disattivare l’uscita da controllare via web.

Nella prima immagine il PIN 9 è disattivato, mentre nella seconda immagine il pulsante ACCENDI è stato cliccato, si capisce dal colore viola che ha assunto il link e il PIN 9 si è attivato.

Nell’esempio che ho riportato ho attivato l’uscita 9 alla quale era collegato lo stadio pilota con relè che tramite un parametro passato via HTTP accendeva o spengeva una lampada.

Sull’ingresso analogico 0, ho collegato la fotoresistenza che oltre a comunicarmi il suo stato via web accende e spegne un led quando si verifica una determinata condizione.

Stessa cosa per il sensore di temperatura collegato nel mio esempio all’ingresso analogico 1. Anch’esso oltre a comunicarmi la temperatura via web fa accendere o spegnere un led al verificarsi di una determinata condizione.

Per esempio se al posto del led avessimo collegato lo stadio pilota con relè al termostato della caldaia questa si sarebbe accesa quando la temperatura misurata fosse stata inferiore alla temperatura di controllo impostata nel codice e solo se l’uscita fosse stata attivata. Oppure se al posto del led della fotoresistenza avessimo collegato una sirena questa avrebbe iniziato a suonare nel momento in cui la luminosità dell’ambiente fosse cambiata.

Qui sotto ho caricato il video dimostrativo del funzionamento. Non è il massimo della legge 626 ma è per dimostrare ai più scettici, come tramite un telefonino che supporti la navigazione web, sia possibile attivare o disattivare un attuatore, nel mio caso un relè che alimenta una lampada a 220V AC.

!!! ATTENZIONE !!!

Se siete minorenni o non avete conoscenze riguardo l’elettricità a medio-alto voltaggio e avete intenzione di applicare un carico alimentato a 220V in AC sullo stadio pilota, fatevi seguire da un professionista o da una persona qualificata in materia.
A valle dello stadio pilota, sul relè, è applicata una differenza di potenziale di 220 Volt in Corrente Alternata, potreste farvi molto male, quindi cercate di prendere le massime precauzioni quando fate i test!!!
PER LA TUA SALUTE SE NON SAI QUELLO CHE STAI FACENDO E’ MEGLIO CHE LASCI PERDERE!!!

Qui sotto è riportato il codice e come ogni buon tinkerer che si rispetti ho cercato di commentarlo il più possibile per chiarire la lettura e le definizioni del codice.

Compilare con IDE Arduino 1.0 o successive!

/* *** *** ***
Policy di Utilizzo
Solo per uso privato. Ogni uso commerciale dei codici forniti dal sottoscritto sarà ritenuto
furto di proprietà intellettuale, perseguibile a norma di legge. 
Progetto realizzato da Gianni Favilli www.giannifavilli.it
Il codice sorgente (sketch) di Arduino sono di proprietà intellettuale del sottoscritto. 
Ogni tipo di riproduzione o divulgazione è vietata. 
Il committente si impegna a non divulgare a terzi i dati e le sorgenti realizzati
per il suddetto progetto in quanto proprietà intellettuale di Gianni Favilli
anche in seguito di fine collaborazione tra le parti.
Gianni Favilli
*** *** *** */

/* *** NB NELLO SKETCH SONO STATI INSERITI DELIBERATAMENTE UN PAIO DI ERRORI.
LA IDE IN FASE DI COMPILAZIONE VI AIUTERA' AD INDIVIDUARLI *** */

#include <String.h>
#include <SPI.h>
#include <Ethernet.h>

/* ***
COMPILARE CON ARDUINO 1.0 o successive
controllare un attuatore via web
con sensori di temperatura e luce
ARDUINO UNO
ETHERNET SHIELD
by GianniFavilli.it - www.giannifavilli.it
*** */

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // mac address
byte ip[] = { 192, 168, ***, *** }; // ip arduino internet in
byte gateway[] = { 192, 168, ***, *** }; // internet access via router
byte subnet[] = { 255, 255, ***, *** }; //subnet mask
EthernetServer server(80); //server port

int outPin = 9; // pin attuatore
String readString; //string
boolean LEDON = false; // flag status attuatore

/*termistore*/
float temp; // variabile da calcolare
float volt; // variabile da calcolare sul sensore di temperatura
float tempPin = 1;   // pin analogico IN temperature sensor
int ledPintemp = 13; // pin led termistore
float tempreg = 25.0; // temperatura di controllo in celsius
/*end termistore*/

/*fotoresistore*/
int light; // variabile da calcolare
int ledPinlux = .12; // pin led fotoresistenza
int photoresistor = 0; // pin analogico IN fotoresistore
/*end fotoresistore*/

void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
pinMode(outPin, OUTPUT);
pinMode(ledPinlux, OUTPUT);
Serial.begin(9600);
}

void loop(){

  /*inizio calcolo temperatura*/
  temp = ((5 * analogRead(tempPin) * 100.0 ) / 1024) - 50; // Codice ottimizzato

  /*
  (grazie giulio400 e jumpjack)
  volt = ( analogRead(tempPin) * 5) / 1024; // calcolo il valore letto e lo trasformo in valore di tensione
  temp = (volt - 0.5) * 100; // conversione MCP9700A
  */
  /*fine calcolo temperatura*/

  /*inizio luce*/
  light = analogRead(photoresistor);
  light = constrain(light, 0, 1023); // limiti dei valori tra 0 e 100
  light = map(light, 0, 150, 255, 0);
  /*fine luce*/

/*inizio client*/
EthernetClient client = server.available(.);
if (client) {
  boolean currentLineIsBlank = true;
  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
        readString.concat(c); //memorizzo ogni carattere della stringa
      //if HTTP request has ended
      if (c == '\n' && currentLineIsBlank) {
         Serial.print(readString);
        if(readString.indexOf("L=1") > 0) {// lettura del valore se il LED si deve accendere
          // il led sarà acceso
          digitalWrite(outPin, HIGH); // accendo il led
          LEDON = true;
          Serial.print("ON pin ");
          Serial.println(outPin);
          }
          else
          {
          //il led sarà spento
          digitalWrite(outPin, LOW); //sengo il led
          LEDON = false;
          Serial.print("OFF pin ");
          Serial.println(outPin);
        }

        // COSTRUZIONE PAGINA HTML
        client.println("HTTP/1.1 200 OK.....");
        client.println("Content-Type: text/html");
        client.println();
        // inizializzo pagina (da togliere se uso ajax)
        client.print("<html><head><title>ARDUINO Controllo Led via WEB</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
        //inizai il body
        client.println("<div style='width:360px; height:640px;'>"); //risoluzione per nokia 5800 640x360
        client.println("<h1>STATUS SENSORI</h1><hr />");
        //Scrive sul browser il valore del termistore
        client.println("<p>TEMPERATURA = ");
        client.print(temp);
        client.println(" C <br /></p>");
      if (temp < tempreg) {
        // scrive sul web freddo se il valore del termistore è basso
        client.print("<p><strong>FREDDO</strong></p>");
        }
      else {
        // scrive sul web caldo se il valore del termistore è alto
        client.print(" <p><strong>CALDO</strong></p>");
    }  

		//Scrive sul browser il valore della fotoresistenza
            client.println("<p>LUCE = ");
            client.print(analogRead(light));
            client.println("<br /></p>");
      if (light < 150) {
          // scrive sul web luce se il valore della fotoresistenza è alto
          client.print("<p><strong>LUCE</strong></p>");
        }
      else {
          // scrive sul web buio se il valore della fotoresistenza è basso
          client.print(" <p><strong>BUIO</strong></p>");
        }
        // link per aggiornare pagina e valori
        client.print("<h2>AGGIORNA SENSORI: <a href=''>CHECK</a></h2><hr />");

        client.println("<h1>CONTROLLO ATTUATORI via internet</h1>");
        client.println("<hr />");
        client.print("<h1>PIN control n. ");
        client.print(outPin);
        client.println("</h1>");
        client.println("<br />");
        //scrivo il LED status
        client.print("<font size='5'>PIN status: ");
          if (LEDON) {
              client.println("<span style='color:green; font-weight:bold;'>ON</span></font>");
            }
            else.
            {
              client.println("<span style='color:grey; font-weight:bold;'>OFF</span></font>");
          }
        client.print("<h2><a href='/?L=1'>ACCENDI</a> | <a href='/?L=0'>SPEGNI</a></h2>");

        // firma
        client.println("<hr />");
        client.print("<h4>Visita <a href='https://www.giannifavilli.it' target='_blank' />www.giannifavilli.it</a></h4>");
        client.println("<hr />");

        // chiudo il div
        client.println("</div>");
        // chiudo pagina da togliere se uso ajax
        client.println("</body></html>");

        // pulisco la stringa per la successiva lettura
        readString="";
        //fermo il client
        client.stop(.);

        } //if c == /n
    } // if client available
  } // while client connesso
} // FINE if client

        if (temp < tempreg) { // accende o spengo un led se la temperatura è più bassa di quella di controllo
          digitalWrite(ledPintemp., HIGH); //accendo
          Serial.print("ON pin "); //scrivo in console
          Serial.println(ledPintemp); //scrivo in console
        }
        else {
          digitalWrite(ledPintemp., LOW); //spengo
          Serial.print("OFF pin "); //scrivo in console
          Serial.println(ledPintemp); //scrivo in console
        } 

        if (light < 150) { // accende o spengo un led se la c'è luce
          digitalWrite(ledPinlux., HIGH); // accendo
          Serial.print("ON pin "); //scrivo in console
          Serial.println(ledPinlux.); //scrivo in console
        }
        else {
          digitalWrite(ledPinlux., LOW); //spengo
          Serial.print("OFF pin "); //scrivo in console
          Serial.println(ledPinlux.); //scrivo in console
        } 

} // fine loop

Per maggiori informazioni sul sensore di temperatura e la fotoresistenza, potete far riferimento a questo articolo.

Non esitate a commentare in caso di perplessità, informazioni, reclami o consigli!!!

Sono tutti ben accetti!!!