Web thermostat with Arduino

By on May 4, 2011
Pin It
Prev4 of 4Next

The Sketch
The sketch contains 3 .PDE files. This is the main program.

Download ZIP File Download the Thermostat sketch

 

 

/* Thermostat with arduino

 created 2011
 by Boris Landoni

 This example code is in the public domain.

 http://www.open-electronics.org
 http://www.futurashop.it
 */

#include <SPI.h>
#include <Ethernet.h>
#include <avr/pgmspace.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#define SHARE_FEED_ID              5102     // this is your Pachube feed ID that you want to share to
#define REMOTE_FEED_ID             256      // this is the ID of the remote Pachube feed that you want to connect to
#define REMOTE_FEED_DATASTREAMS    4        // make sure that remoteSensor array is big enough to fit all the remote data streams
#define UPDATE_INTERVAL            20000    // if the connection is good wait 10 seconds before updating again - should not be less than 5
#define RESET_INTERVAL             10000    // if connection fails/resets wait 10 seconds before trying again - should not be less than 5
#define PACHUBE_API_KEY            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // fill in your API key 
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;

int puls1 = 5;                 // pulsante per il cambio di modalità di funzionamento
int puls2 = 2;                 // pulsante per il cambio di modalità di funzionamento
int in    = 3;                 // ingresso del termostato

prog_char string_0[] PROGMEM  = "<html><head><title>Boris's Project</title><META HTTP-EQUIV=\"Refresh\" CONTENT=\"3600\"></head>";
prog_char string_1[] PROGMEM  = "<body><center><br><form> <input type=button value=\"Refresh \" onClick=\"window.location.reload()\"> </form><br><br><h2>Remote Control Thermostat   ";
prog_char string_2[] PROGMEM  = " C</h2><form method=GET><font size= 5>Boiler ";
prog_char string_3[] PROGMEM  = "</font><br><font size= 3>Input Thermostat ";
prog_char string_4[] PROGMEM  = "</font><br><table><td><input type=\"radio\" name=\"statourl\" value=\"1\" onClick=\"this.form.submit()\"  ";
prog_char string_5[] PROGMEM  = "></td><td>Sensor</td><td><input type=\"radio\" name=\"statourl\" value=\"2\" onClick=\"this.form.submit()\" ";
prog_char string_6[] PROGMEM  = "></td><td>Manual</td><td><input type=\"radio\" name=\"statourl\" value=\"3\" onClick=\"this.form.submit()\" ";
prog_char string_7[] PROGMEM  = "></td><td>Thermostat</td><br></table> </form><form method=GET>";
prog_char string_8[] PROGMEM  = "<table><tr><td><input type=submit name=b11 value=\"Boiler ON\"></td><td><input type=submit name=b10 value=\"Boiler OFF\"></td><td>";
prog_char string_9[] PROGMEM  = "</td></tr></table></form><form method=GET>Temperature: <input type=\"text\" size=\"2\" name=temp value=#* MAXLENGTH=2>";
prog_char string_10[] PROGMEM  = "<input type=\"submit\" value=\"Set temperature\"><br></form>";
prog_char string_11[] PROGMEM = "<br><OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\""; 
prog_char string_12[] PROGMEM = "codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab";
prog_char string_13[] PROGMEM = "#version=6,0,0,0\" WIDTH=\"200\" HEIGHT=\"100\" id=\"gauge\"><PARAM NAME=\"movie\""; 
prog_char string_14[] PROGMEM = "VALUE=\"http://apps.pachube.com/scaredycat/gauge.swf?xml_source=";
prog_char string_15[] PROGMEM = "http%3A//apps.pachube.com/scaredycat/getData.php";
prog_char string_16[] PROGMEM = "%3Fm%3D0%26f%3D5102%26s%3D0%26u%3D30%26l%3D0%26n%3D5%26t%3D";
prog_char string_17[] PROGMEM = "Temperatura%26w%3Dfalse%26c1%3D33FF33%26c2%3DEFE415%26c3%3DEF8B15%26c4%3DFF3333%26";
prog_char string_18[] PROGMEM = "in%3Dtrue\" /><PARAM NAME=\"quality\" VALUE=\"high\" /><param name=\"wmode\" value=\"transparent\">";
prog_char string_19[] PROGMEM = "<param name=\"allowScriptAccess\" value=\"sameDomain\" /><EMBED src=\"";
prog_char string_20[] PROGMEM = "http://apps.pachube.com/scaredycat/gauge.swf?xml_source=";
prog_char string_21[] PROGMEM = "http%3A//apps.pachube.com/scaredycat/getData.php";
prog_char string_22[] PROGMEM = "%3Fm%3D0%26f%3D5102%26s%3D0%26u%3D30%26l%3D0%26n%3D5%26t%3D";
prog_char string_23[] PROGMEM = "Temperatura%26w%3Dtrue%26c1%3D33FF33%26c2%3DEFE415%26c3%3DEF8B15%26c4%3DFF3333%26in%3Dtrue\"";
prog_char string_24[] PROGMEM = "quality=\"high\" wmode=\"transparent\" WIDTH=\"200\" HEIGHT=\"100\""; 
prog_char string_25[] PROGMEM = "NAME=\"gauge\" allowScriptAccess=\"sameDomain\" swLiveConnect=\"true\""; 
prog_char string_26[] PROGMEM = "TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"";
prog_char string_27[] PROGMEM = "http://www.macromedia.com/go/getflashplayer\"></EMBED></OBJECT>";
prog_char string_28[] PROGMEM = "<br><br><script type=\"text/javascript\" src=\"http://www.google.com/jsapi\">";
prog_char string_29[] PROGMEM = "</script><script language=\"JavaScript\" src=\"http://apps.pachube.com/google_viz/viz_multi.js\">";
prog_char string_30[] PROGMEM = "</script><script language=\"JavaScript\">createViz([5102,5102],[0,1],800,400,[\"ff0000\",\"0000ff\"],0,40);</script>";
prog_char string_31[] PROGMEM = "";
prog_char string_32[] PROGMEM = "";
prog_char string_33[] PROGMEM = "<font size= 2>Powered by Open-Electronics.org - Boris Landoni</font>"; //please don't remove :-)
prog_char string_34[] PROGMEM = "";
prog_char string_35[] PROGMEM = "";
prog_char string_36[] PROGMEM = "";
prog_char string_37[] PROGMEM = "";
prog_char string_38[] PROGMEM = "";
prog_char string_39[] PROGMEM = "";
prog_char string_40[] PROGMEM  = "<br></center></body></html>";
prog_char string_41[] PROGMEM  = "<font color=\"red\">ON</font>";
prog_char string_42[] PROGMEM  = "OFF";
prog_char string_43[] PROGMEM  = "checked";
prog_char string_44[] PROGMEM  = "on";
prog_char string_45[] PROGMEM  = "off";

PROGMEM const char *string_table[] = // change "string_table" name to suit
{ 
string_0,
string_1,
string_2,
string_3,
string_4,
string_5,
string_6,
string_7,
string_8,
string_9,
string_10,
string_11,
string_12,
string_13,
string_14,
string_15,
string_16,
string_17,
string_18,
string_19,
string_20,
string_21,
string_22,
string_23,
string_24,
string_25,
string_26,
string_27,
string_28,
string_29,
string_30,
string_31,
string_32,
string_33,
string_34,
string_35,
string_36,
string_37,
string_38,
string_39,
string_40,
string_41,
string_42,
string_43,
string_44,
string_45
};

char buffer[150]; // make sure this is large enough for the largest string it must hold

byte mac[] = { 0xDE, 0xAD, 0xBA, 0xAF, 0xFA, 0xAD };
byte ip[] = { 192, 168, 0, 172 };
byte gateway[] = { 192, 168, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };
byte remoteServer[] = { 173,203,98,29 };            // pachube.com
float remoteSensor[REMOTE_FEED_DATASTREAMS];        // we know that feed 256 has floats - this might need changing for feeds without floats
String inString = String(35);
Server server(80);
const int led = 6;
const int rele = 7;
String temp="";
String statourl="";
int tam=0; 
int st1=42,st2=42,st3=42,st4=42,st5=43,st6=44;
//float tempCold;
unsigned long pubblica;
unsigned long lampeggio;
int stato=1; // se 0 controllo con sensore temperatura integrato, se 1 controllo manuale, se 2 controllo con termostato esterno
float tempC=0;

void setup()
{
      pinMode(puls1, INPUT);
      pinMode(puls2, INPUT);
      pinMode(in, INPUT);
      pinMode(led, OUTPUT); 
      pinMode(rele, OUTPUT); 
      Serial.begin(9600);
      Ethernet.begin(mac, ip,gateway,subnet); 
      server.begin();
      Serial.println("Serial READY");
      Serial.println("Ethernet READY");
      Serial.println("Server READY");
        sensors.begin();
        Serial.print("Found ");
        Serial.print(sensors.getDeviceCount(), DEC);
        Serial.println(" devices.");
        Serial.print("Parasite power is: "); 
        if (sensors.isParasitePowerMode()) Serial.println("ON");
        else Serial.println("OFF");
        if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
        Serial.print("Device 0 Address: ");
        printAddress(insideThermometer);
        Serial.println();
        // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
        sensors.setResolution(insideThermometer, 9);       
        Serial.print("Device 0 Resolution: ");
        Serial.print(sensors.getResolution(insideThermometer), DEC); 
        Serial.println();

}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

void printWebPage(Client *client)
{
    int tmp=0;
    int temperatura=0;
      // send a standard http response header
      client->println("HTTP/1.1 200 OK");
      client->println("Content-Type: text/html");
      client->println();

      strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0]))); // Necessary casts and dereferencing, just copy. 
      client->println( buffer ); 
      //Serial.println( buffer ); 
      for (int i = 1; i < 41; i++)
      {
          if (i==9)
          {
              strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));  //butto tutto nell'array buffer
              for (tmp=0 ; tmp < sizeof(buffer); tmp++)
              {
                if (buffer[tmp]=='#')
                {
                  //Serial.println( "trovato ##### " ); 
                  temperatura = EEPROM.read(0);
                  Serial.print("dato in mem : ");
                  Serial.println(temperatura);
                  buffer[tmp] =  char ((temperatura/10)+48);
                  tmp++;
                  buffer[tmp] =  char ((temperatura % 10)+48);                      
                }

              }
          }
          else
          {
            strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy. 
          }
          client->println( buffer );

          switch(i){

              case 1: 
                  itoa (tempC, buffer, 10); client->print( buffer ); Serial.print( buffer ); client->print( "," ); Serial.print( "," ); itoa ((int(tempC * 100) % 100), buffer, 10); client->print( buffer ); Serial.print( buffer ); break;
              case 2: 
                  if(digitalRead(rele)) st4=41;
                  else st4=42;  
                  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[st4]))); client->println( buffer ); Serial.println( buffer ); break;
              case 3:                    
                  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[st6]))); client->println( buffer ); Serial.println( buffer ); break;
              case 4: 
                if (stato==1){
                  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[st5]))); client->println( buffer ); Serial.println( buffer ); break;
                  }                 
              case 5: 
                if (stato==2){
                  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[st5]))); client->println( buffer ); Serial.println( buffer ); break;
                  }
              case 6: 
                if (stato==3){
                  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[st5]))); client->println( buffer ); Serial.println( buffer ); break;
                  }
          }
          delay(30);
      }

}

void verificaingressi()
{
  int temperatura = EEPROM.read(0);
  if (!digitalRead(puls1))
      {
        stato=stato+1;
        if (stato>3)
        {
          stato=1;
        }   
       EEPROM.write(1, stato);     
       digitalWrite(led,HIGH);
       delay(1000);
       digitalWrite(led,LOW);
       delay(1000);
       lampeggio=4000; //così lampeggia poi subito
      }

            if (stato==1)
      {
        if (tempC<temperatura )
        { 
           digitalWrite(rele,HIGH);
           //st4=41;         
        }
        else
        {
          if (tempC>(temperatura+1))
          {
            digitalWrite(rele,LOW);
            //st4=42; 
          }
        }
      }

        if (!digitalRead(in))
        {           
           if (stato==3) digitalWrite(rele,HIGH);
           st6=44;         
        }
        else
        {
            if (stato==3) digitalWrite(rele,LOW);
            st6=45;         
        }
}

void loop()
{

      stato = EEPROM.read(1);

      verificaingressi();
      sensors.requestTemperatures(); // Send the command to get temperatures

      tempC = sensors.getTempC(insideThermometer);
      if (millis() < pubblica) pubblica = millis();

      if ((millis() - pubblica) > UPDATE_INTERVAL){
          pubblica = millis();  

          Serial.println("Pubblico");      
          Serial.print("Temp C    : ");
          Serial.println(tempC); 
          if (tempC<50 && tempC>-20)
          {
            pachube_in_out(tempC);
          }          
      }

      if (millis() < lampeggio)  lampeggio = millis();
      if ((millis() - lampeggio) > 5000){    //ogni 5 sec faccio lampeggiare il led giallo
          lampeggio = millis();  
          for (int i = 0; i < stato; i++)
          {
                   //Serial.println("lamp"); 
                   digitalWrite(led,HIGH);
                   delay(250);
                   digitalWrite(led,LOW);
                   delay(250);
          }                      
      }

      Client client = server.available();

      int led=0;
      int tmp=0;
      if (client) {

      // an http request ends with a blank line
      boolean current_line_is_blank = true;
      while (client.connected()) {

      if (client.available()) {

      char c = client.read();
      if (inString.length() < 35) {
      inString.concat(c);

      } 
      if (c == '\n' && current_line_is_blank) {

          if(inString.indexOf("b10")>=0){      
            digitalWrite(led,LOW);
            stato=2;           
          }          
          if(inString.indexOf("b11")>=0){      
            digitalWrite(led,HIGH);
            stato=2;            
          }         

          if(inString.indexOf("b40")>=0){      
            digitalWrite(led,LOW);
          }          
          if(inString.indexOf("b41")>=0){      
            digitalWrite(led,HIGH);
          }            
          if(digitalRead(rele)) st4=41;
          else st4=42;  

          if (inString.indexOf("temp")>=0){ 
            char tempArr[20];
            temp=inString.substring(inString.indexOf('p')+2, inString.indexOf(" H"));
            temp.toCharArray(tempArr, 5);
            EEPROM.write(0, atoi(tempArr));
            tmp = EEPROM.read(0);
            stato=1;            
          }

          if(inString.indexOf("statourl")>=0){   
             char statoArr[20];  
            statourl=inString.substring(inString.indexOf('l')+2, inString.indexOf(" H"));
            statourl.toCharArray(statoArr, 5);
            stato=(atoi(statoArr));
          }     

      EEPROM.write(1, stato);
      verificaingressi();
      printWebPage( &client);
      break;
      }
      if (c == '\n') {
      // we're starting a new line
      current_line_is_blank = true;
      } else if (c != '\r') {
      // we've gotten a character on the current line
      current_line_is_blank = false;
      }
      }
      }
      // give the web browser time to receive the data
      delay(1);
      inString = "";
      client.stop();
      }
}

<Previous page

Prev4 of 4Next

About Boris Landoni

Boris Landoni is the technical manager of Open-Electronics.org. Skilled in the GSM field, embraces the Open Source philosophy and its projects are available to the community.

8 Comments

  1. Pingback: business model innovation design » "Look around your house

  2. Pingback: Control de temperatura vía Web con Arduino | Automatismos Mar del Plata

  3. Pingback: Arduino | Pearltrees

  4. Pingback: Happy new year from Open-Electronics.org: best posts in 2016, thank you! | Open Electronics

Leave a Reply

Your email address will not be published. Required fields are marked *