Controllo remoto temperatura impostata sul web

Ciao a tutti,
sono nuovo del forum quindi spero di non aver sbagliato qualche passaggio nella presentazione e di aver scelto la categoria giusta :slight_smile:
Sto lavorando da alcuni mesi a un progetto che devo portare all'esame di maturità: questo progetto consiste nel controllo remoto di temperatura da remoto utilizzando una shield ethernet (non ufficiale wiznet) ed un arduino UNO R3. L'idea del progetto è quella di controllare il riscaldamento (tramite una lampadina 12V) ed il raffreddamento (tramite una ventola dei computer a 12 V) di 5 stanze separate ognuna con un sensore di temperatura TMP36. La gestione della temperatura deve avvenire in automatico quindi tramite il sensore di temperatura mette a confronto la temperatura della stanza con una temperatura regolata, accendendo la lampadina in caso temperatura stanza<temperatura impostata, mentre si accende la ventola in caso temperatura stanza > temperatura impostata.

Fino a qui tutto ok, riesco a creare una pagina web HTML piuttosto semplice ma che svolge il suo dovere, ma per adesso riesco ad accendere luci e ventole in modo manuale o impostando la temperatura sullo sketch. Ma quello che vorrei fare io è un pochino diverso:
per ogni stanza vorrei mettere un pulsante "accendi" e uno "spegni" di modo che quando viene premuto "accendi" nella stanza 1, per esempio, la temperatura sia controllata in modo automatico, ma vorrei impostare la temperatura sulla pagina web tramite una textarea. Riguardo a questo ho cercato un po' sul web e ho capito che devo utilizzare comandi GET/POST, (partendo dal presupposto che non conosco il linguaggio HTTP) ho pensato che nel mio caso è più opportuno utilizzare il comando POST perchè con il comando GET l'indirizzo verrebbe cambiato e quindi mi sconvolgerebbe tutto, tramite il comando POST questo non dovrebbe avvenire se non ho capito male, ditemi se sbaglio :sweat_smile: .
La mia prima domanda è: come posso utilizzare il comando POST in modo da impostare la temperatura da web e in modo che la stanza 1 si regoli in base alla temperatura che ho impostato?
Ricordo che questo deve avvenire solo nel caso in cui io prema l'appostito pulsante "Accendi" per la stanza 1, e che questo deve mantenersi anche se decidessi di controllare le altre stanze contemporaneamente.

Grazie in anticipo e spero di essermi espresso correttamente :slight_smile:

Posto lo sketch mentre aspetto se qualcuno riesce ad aiutarmi..

#include <String.h>
#include <SPI.h>
#include <Ethernet.h>
/* ***COMPILARE CON ARDUINO 1.0 o successivecontrollare un attuatore
via webcon sensori di temperatura 
 

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

int luce1 = 2; 
int luce2 = 3; 
int luce3 = 4;

int ventola1 = 7; 
int ventola2 = 8;
int ventola3 = 9; 


String readString; //string

boolean LEDON1 = false;  

boolean LEDON2 = false;

boolean LEDON3 = false;



/*termistore*/
float temp1; // variabile da calcolare
float temp2; // variabile da calcolare
float temp3; // variabile da calcolare


float tempPin1 = A1;   // pin analogico IN temperature sensor
float tempPin2 = A2;   // pin analogico IN temperature senso
float tempPin3 = A3;   // pin analogico IN temperature senso


float tempreg1 = 25.0;
float tempreg2 = 25.0;
float tempreg3 = 25.0;

/*end termistore*/

void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
pinMode(luce1, OUTPUT);
pinMode(luce2, OUTPUT);
pinMode(luce3, OUTPUT);

pinMode(ventola1, OUTPUT);
pinMode(ventola2, OUTPUT);
pinMode(ventola3, OUTPUT);


Serial.begin(9600);
}
void loop(){  
  /*inizio calcolo temperatura*/  
temp1 = ((5 * analogRead(tempPin1) * 100.0 ) / 1024) - 50;
temp2 = ((5 * analogRead(tempPin2) * 100.0 ) / 1024) - 50;
temp3 = ((5 * analogRead(tempPin3) * 100.0 ) / 1024) - 50;


/*fine calcolo temperatura*/   

/*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); 
      
    //INIZIO COMANDO STANZE (LAMPADE E VENTOLE)
   //STANZA 1
   if(readString.indexOf("L=2") > 0) {        
     LEDON1 = true; 
    Serial.print("ON pin ");    
   }
    else  if(readString.indexOf("L=1") > 0) {        
    LEDON1 = false; 
    Serial.print("OFF pin ");    
   }
   if (LEDON1 == true) {
     if (temp1 < tempreg1-1) {
       
      digitalWrite(ventola1, LOW);
      digitalWrite(luce1, HIGH); 
      Serial.print("luce1 on "); 
      Serial.println(luce1); 
      }
      else if(temp1>tempreg1+1) {   
      digitalWrite(luce1,LOW);
      digitalWrite(ventola1, HIGH); 
      Serial.print("ventola1 on "); 
      Serial.println(ventola1);   
    }
   }
     else if (LEDON1 == false){
       digitalWrite(luce1,LOW);
       digitalWrite(ventola1,LOW);
     }
     
     //STANZA 2
if(readString.indexOf("L=3") > 0) {        
     LEDON2 = true; 
    Serial.print("ON pin ");    
   }
    else  if(readString.indexOf("L=4") > 0) {        
    LEDON2 = false; 
    Serial.print("OFF pin ");    
   }
   if (LEDON2 == true) {
     if (temp2 < tempreg2-1) {
       
      digitalWrite(ventola2, LOW);
      digitalWrite(luce2, HIGH); 
      Serial.print("luce2 on "); 
      Serial.println(luce2); 
      }
      else if(temp2>tempreg2+1) {   
      digitalWrite(luce2,LOW);
      digitalWrite(ventola2, HIGH); 
      Serial.print("ventola2 on "); 
      Serial.println(ventola2);   
    }
   }
     else if (LEDON2 == false){
       digitalWrite(luce2,LOW);
       digitalWrite(ventola2,LOW);
     }

     
     //STANZA 3
if(readString.indexOf("L=5") > 0) {        
     LEDON3 = true; 
    Serial.print("ON pin ");    
   }
    else  if(readString.indexOf("L=6") > 0) {        
    LEDON3 = false; 
    Serial.print("OFF pin ");    
   }
   if (LEDON3 == true) {
     if (temp3 < tempreg3-1) {
       
      digitalWrite(ventola3, LOW);
      digitalWrite(luce3, HIGH); 
      Serial.print("luce3 on "); 
      Serial.println(luce3); 
      }
      else if(temp3>tempreg3+1) {   
      digitalWrite(luce3,LOW);
      digitalWrite(ventola3, HIGH); 
      Serial.print("ventola3 on "); 
      Serial.println(ventola3);   
    }
   }
     else if (LEDON3 == false){
       digitalWrite(luce3,LOW);
       digitalWrite(ventola3,LOW);
     }
     
    // 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>");   
    //iniza il body 
    client.println("<div style='width:1280px; height:720px;'>"); //risoluzione per jiayu G4S 1280x720 
    client.println("<h1>STATUS SENSORI</h1><hr />");
    //Scrive sul browser il valore del termistore 
    client.println("<p>TEMPERATURA stanza 1 = ");  
    client.print(temp1);
    client.println(" C 
</p>");
    client.println("<p>TEMPERATURA stanza 2 = ");  
    client.print(temp2);
    client.println(" C 
</p>");
    client.println("<p>TEMPERATURA stanza 3 = ");  
    client.print(temp3);
    client.println(" C 
</p>");
   
      // link per aggiornare pagina e valori e autorefresh ogni 5"
      client.print("<META HTTP-EQUIV='refresh' CONTENT='5; /'>");
      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(luce1);
       client.println("</h1>");
      client.println("
");
      //scrivo il LED status
      client.print("<font size='5'>PIN status: ");
      if (LEDON1) { 
        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=2'>ACCENDI</a> | <a href='/?L=1'>SPEGNI</a></h2>");  
        
         client.print("<h1>PIN control n. ");
      client.print(luce2);
       client.println("</h1>");
      client.println("
");
      //scrivo il LED status
      client.print("<font size='5'>PIN status: ");
      if (LEDON2) { 
        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=3'>ACCENDI</a> | <a href='/?L=4'>SPEGNI</a></h2>");  
        
          client.print("<h1>PIN control n. ");
      client.print(luce3);
       client.println("</h1>");
      client.println("
");
      //scrivo il LED status
      client.print("<font size='5'>PIN status: ");
      if (LEDON3) { 
        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=5'>ACCENDI</a> | <a href='/?L=6'>SPEGNI</a></h2>");  
        
     
       client.println("</h1>");
      client.println("
");
      //scrivo il LED status
      client.print("<font size='5'>PIN status: ");
      
        // firma  
      client.println("<hr />");
      client.print("<h4>PROGRAMMA DI GABRIELE VERSINO</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  
}

Hai una UNO leleversino ... non ne usciamo vivi se ci metti anche il POST e dei textarea vari + javascript :cold_sweat:

Probabilmente prenderò un Mega perché non mi bastano i pin di uscita considerando che la shield me ne occupa già alcuni, e adesso stavo provando a vedere se riuscivo a adattare lo stesso con un comando GET.. Ma sono comunque in alto mare perché non sono riuscito a trovare esempi che facciano al caso mio... Consigli? ::slight_smile: :slightly_smiling_face:

pablos:
non ne usciamo vivi se ci metti anche il POST e dei textarea vari + javascript :cold_sweat:

:smiley:

oggi ho cercato qualche soluzione ed ho trovato..

client.print("<form method=get action=?>");
client.print("<textarea name='D' rows='1' cols='10'></textarea>"); 
client.print("<input type=submit value=invia>");
client.print("</form>");
    
if (readString.indexOf("D=")>0){

   String stringa = readString.substring(8,12);    
   Serial.println(stringa);  //stampa la stringa, ovvero il valore di temperatura decimale scritto nella textarea (es. 25.0) 
   client.println(stringa);

}

Ora il mio problema è convertire la stringa in float in modo che possa assegnarlo al valore della temperatura regolata (tempreg) che deve confrontare con il valore della temperatura della stanza (temp).
come posso fare? :confused:

L'avevo fatto nel 2011 con la 0.22, ora dovrebbe essere corretto

Semplice esempio di inserimento stringa in un campo input text, il messaggio inviato con [form name="input" method="POST]

Nel char(c) trovi la stringa inviata con POST

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

byte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED};  
byte ip[] = { 192,168,2,177};
EthernetServer server(80);

void setup(){
  
  delay(1000);
  Ethernet.begin(mac,ip);
  Serial.begin(9600);  
  server.begin();
}

void loop(){  
  EthernetClient  client = server.available();
  if(client){

    while(client.connected()){        
      while(client.available()){
        char c = client.read();
        Serial.print(c);     
      }
      
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println();
        client.println("<html><head><title>Prova POST</title>");
        client.println("</head><body>");
        client.println("<form name=\"input\" method=\"POST\">");
        client.println("Testo di input: <input type=\"text\" name=\"variabile\" />");
        client.println("<input type=\"submit\" value=\"Invia\" />");
        client.println("</form></body></html> ");
      delay(1);
      client.stop();
       Serial.println();   
    }
  }
}

Ahh l'hai trovato .. ok

comunque sarebbe più corretto cercare il testo inserito nel form NON con
String stringa = readString.substring(8,12);

se la tua stringa cambia lunghezza sballa tutto

va cercata tra "=" e "\n" della linea if (readString.indexOf("D=")>0){

Suggerisco di aumentare la lunghezza del nome di quell'oggetto, D= potrebbe essere trovato in altre linee dell'header

per la conversione guarda qui "String to float"

Usa la funzione F() per risparmiare ram su tutti i client.print statici
client.print(F(""));

sostuisci questi int con byte, recuperi 6 byte di ram .. a una UNO 6 byte fanno gola :slight_smile:

int luce1 = 2;
int luce2 = 3;
int luce3 = 4;
int ventola1 = 7;
int ventola2 = 8;
int ventola3 = 9;

altrimenti levali proprio e ne recuperi 12

perchè questi li hai dichiarati float?
float tempPin1 = A1; // pin analogico IN temperature sensor
float tempPin2 = A2; // pin analogico IN temperature senso
float tempPin3 = A3; // pin analogico IN temperature senso
levali e recuperi altri 12 byte

Non puoi permetterti con un chip così piccolo di trascinarti variabili pubbliche inutili, sostituisci i numeri dei pin direttamente nelle funzioni, sempre che non siano strttamente necessarie

Se non ti ricordi cosa fanno fatti un promemoria ll'inizio dello sketch

es
//pin 2 luce1
//pin 3 luce2
//pin 4 luce3
//pin 7 ventola1
//pin 8 ventola2
//pin 9 ventola3
//A1; pin analogico IN temperature sensor
//A2; pin analogico IN temperature senso
//A3; pin analogico IN temperature senso

Wow Pablo grazie mille per i molti consigli :slight_smile: alla fine ieri sono riuscito in qualche modo a fare funzionare tutto, avevo solo un ulteriore problema: quanto mettevo la terza textarea la pagina non veniva visualizzata e non capivo perché :slight_smile: ora non posso postare lo sketch essendo a cellulare :slightly_smiling_face: comunque modifichero' il programma come mi hai consigliato, ma lo sviluppero su un arduino mega perché ho bisogno di comandare 5 stanze e con un arduino uno riesco a comandarne solo 3 per mancanza di pin.. A sto punto proverò con tutti e due i metodi (Post e get), ho solo un ulteriore dubbio: come faccio a estrarre la stringa dalla char(c) per assegnarlo a tempreg?
Grazie mille per i consigli :slight_smile:

Ciao a tutti! Sono riuscito a risolvere i problemi sopracitati, ora Ho un ulteriore dubbio: come faccio a accedere alla mia pagina web da remoto? Ho letto da qualche parte che devo utilizzare un servizio dns oppure mi basta impostare l'indirizzo in ascolto sulla porta 80. Ho provato con quest'ultimo metodo ma non mi funziona e lo trovo strano che possa funzionare, fino ad adesso sono riuscito solo tramite indirizzo IP pubblico, qualcuno potrebbe farmi chiarimenti? Premetto che ho un ADSL alice della telecom ma dovrei farlo funzionare anche sulla rete di scuola di cui praticamente non so nulla, e l'indirizzo IP pubblico che trovo tramite un semplice sito myIP non funziona ed è sempre uguale? Possibile accedervi da remoto o devo rassegnarmi? Grazie mille

ma dovrei farlo funzionare anche sulla rete di scuola di cui praticamente non so nulla, e l'indirizzo IP pubblico che trovo tramite un semplice sito myIP non funziona

Se devi usare l'IP pubblico della scula in entrata c'è poco da fare devi contattare l'amministratore di rete che dovrà assegnarti un un ip interno, una porta per il forward, autorizzare protocolli e percorsi di rete, non si sa mai che tu finisca per sbaglio nei file della presidenza o segreteria :slight_smile: ...
La vedo dura però che ti vengano dati questi privilegi.

Immaginavo grazie lo stesso :slight_smile: invece per quanto riguarda l'ADSL alice, ho letto che molti fanno il port mapping dell'ip su cui è connesso arduino indirizzando sulla porta 80 sia in entrata che in uscita e funziona, possibile? Io non sono riuscito facendo in questo modo.. Avrò sbagliato qualcosa io?