/* * Halfluck Temperature Controller Webserver * An open-source Temperature Controller for Arduino. * v1.4 23/7/2012 * * TempControllerWebServer.ino * * (cc) by Rob Hart * * http://www.halfluck.com * http://creativecommons.org/license/cc-gpl *targettemp * Compiled & Tested in Arduino 1.0.1 * using OneWire Library v2.1 http://www.arduino.cc/playground/Learning/OneWire * using Ethercard Library https://github.com/jcw/ethercard/ * */ #include #include #include "printf.h" char TargetTemperarureTextbox[10]; // Data in text box // ethernet interface mac address, must be unique on the LAN static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; static byte myip[] = { 192,168,1,150 }; //used for static IP byte Ethernet::buffer[1000]; // if you increase the size of the HTML code you may need to increase the buffer size (or it will stop working) //TODO BufferFiller bfill; const byte PinTemp = 0; // Dallas Ds1820 Temperature Sensors const byte PinSSR1 = 2; // Pin for SSR 1 const byte PinSSR2 = 3; // Pin for SSR 2 int currenttemp1 = 0; // curent temperature (1/16th degrees) sensor1 int lasttemp1 = 0; // previous temperature sensor 1 byte negativetemp1 = 0; // if negative temp display that byte fractlessthan10 = 0; // if less than 10 then add a zero first int SignBit, Whole, Fract, Tc_100; int TargetTemp = 0; // this is the placeholder for the target temperature byte Mode = 0; // 0 is Manual, 1 is Auto byte SSR1on = 0; // 0 is Off, 1 is On byte SSR2on = 0; // 0 is Off, 1 is On boolean auth=false; void setup () { if (ether.begin(sizeof Ethernet::buffer, mymac, 8) == 0); //Add alternative begin with 3rd parameter to specify CS pin to use. Only 8, 9 and 10 are usable. Default without 3rd parameter is pin 8. ether.staticSetup(myip); ether.hisport=85; pinMode(PinTemp, INPUT); // sets the digital pin as input pinMode(PinSSR1, OUTPUT); // sets the digital pin as input pinMode(PinSSR2, OUTPUT); // sets the digital pin as input TargetTemp = EEPROM.read(0); Mode = EEPROM.read(1); // //Stuff for DHCP Serial.begin(57600); Serial.println("\nDHCP]"); // // if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) // Serial.println( "Failed to access Ethernet controller"); // // Serial.println("Setting up DHCP"); // 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); } int tempread(void) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; float Temp; Temp=analogRead(PinTemp); Temp=(5.0*Temp*10000.0)/1024.0; return int(Temp); } const char http_OK[] PROGMEM = "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n\r\n"; const char http_AUTH[] PROGMEM = "GET /private/index.html HTTP/1.1" "Host: localhost" "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==;"; const char http_Found[] PROGMEM = "HTTP/1.0 302 Found\r\n" "Location: /\r\n\r\n"; const char http_Unauthorized[] PROGMEM = "HTTP/1.0 401 Unauthorized\r\n" "Content-Type: text/html\r\n\r\n" "

401 Unauthorized

"; static word homePage() { // bfill = ether.tcpOffset(); //$D = word data type //$L = long data type //$S = c string //$F = progmem string //$E = byte from the eeprom. //Uptime Stuff long days=0; long hours=0; long mins=0; long secs=0; secs = millis()/1000; //convect milliseconds to seconds mins=secs/60; //convert seconds to minutes hours=mins/60; //convert minutes to hours days=hours/24; //convert hours to days secs=secs-(mins*60); //subtract the coverted seconds to minutes in order to display 59 secs max mins=mins-(hours*60); //subtract the coverted minutes to hours in order to display 59 minutes max hours=hours-(days*24); //subtract the coverted hours to days in order to display 23 hours max char* SSR1stat; if ( digitalRead(PinSSR1) == HIGH ) { SSR1stat = "On" ; } else { SSR1stat = "Off"; } char* SSR2stat; if ( digitalRead(PinSSR2) == HIGH ) { SSR2stat = "On" ; } else { SSR2stat = "Off"; } if (Mode == 0) //If Manual { bfill.emit_p(PSTR( "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n" "\r\n" "" "" "" "Halfluck Webserver" "" "
" "
" "Temperature: " "
" "" "$D.$D °C
" "
" "Heat is $S " "
" "Pump is $S " "
" "
" "
" "
" "Uptime: $L Days $L Hours $L Mins $L Secs" "
"), Whole , Fract , SSR1stat, SSR2stat, days, hours, mins, secs ); return bfill.position(); } else //its AutoMode display Target Temp and Textbox for adjusting Temperature { bfill.emit_p(PSTR( "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n" "\r\n" "" "" "" "Halfluck Webserver" "" "
" "
" "Temperature: " "
" "" "$D.$D °C
" "
" "Target Temperature: " "$D.0 °C" "
" "Heat is $S " "
" //"Pump is $S " // "
" // "
" // "" // "" // "
" "Change Target Temp" "
" "
" "
" "
" "Uptime: $L Days $L Hours $L Mins $L Secs" "
"), //Whole , Fract , TargetTemp, SSR1stat, SSR2stat, days, hours, mins, secs ); Whole , Fract , TargetTemp, SSR1stat, days, hours, mins, secs ); return bfill.position(); } } void loop () { if (Mode == 1) //if auto mode { if ((currenttemp1<(TargetTemp*100)) && (currenttemp1>0)) // below low range { digitalWrite(PinSSR1, HIGH); // turn SSR1oning on SSR1on = 1; } else if ((currenttemp1>=(TargetTemp*100)) && (currenttemp1>0)) //ideal range { digitalWrite(PinSSR1, LOW); // turn SSR1oning off SSR1on = 0; } } currenttemp1 = tempread(); //Serial.print("temperatura ="); //Serial.println(currenttemp1); //Serial.print("temperatura ="); //Serial.println(currenttemp1byte); if ((currenttemp1 != lasttemp1) && (currenttemp1>0)) { Tc_100 = currenttemp1; // multiply by (100 * 0.0625) or 6.25 // Tf_100 = ((1.8)*Tc_100) + (32*100); // Farenheit Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; if (SignBit) // If its negative //TODO { negativetemp1 = 1; } else { negativetemp1 = 0; } if (Fract < 10) //TODO { fractlessthan10 = 1; } else { fractlessthan10 = 0; } lasttemp1 = currenttemp1; } word len = ether.packetReceive(); word pos = ether.packetLoop(len); if (pos) { // write to LED digital output delay(1); // necessary for my system //TODO bfill = ether.tcpOffset(); char *data = (char *) Ethernet::buffer + pos; if (strncmp("GET /", data, 5) != 0) { // Unsupported HTTP request // 304 or 501 response would be more appropriate bfill.emit_p(http_Unauthorized); } else { data += 5; if (data[0] == ' ') { // Return home page homePage(); } else if (strncmp( "?modeauto" , data, 9 ) == 0) { Mode = 1; EEPROM.write(1, Mode); digitalWrite(PinSSR1, LOW); // turn SSR1 off SSR1on = 0; // switch SSR off digitalWrite(PinSSR2, LOW); // turn SSR1 off bfill.emit_p(http_Found); } else if (strncmp( "?modemanual" , data, 11 ) == 0) { Mode = 0; SSR1on = 0; // switch SSR off EEPROM.write(1, Mode); digitalWrite(PinSSR1, LOW); // turn SSR1 off digitalWrite(PinSSR2, LOW); // turn SSR1 off bfill.emit_p(http_Found); } else if (strncmp( "?SSR1toggle" , data, 11 ) == 0) { if (SSR1on == 0) { SSR1on = 1; // switch SSR off digitalWrite(PinSSR1, HIGH); // turn SSR1 off } else { SSR1on = 0; // switch SSR off digitalWrite(PinSSR1, LOW); // turn SSR1 off } bfill.emit_p(http_Found); } else if (strncmp( "?SSR2toggle" , data, 11 ) == 0) { if (SSR2on == 0) { SSR2on = 1; // switch SSR off digitalWrite(PinSSR2, HIGH); // turn SSR1 off } else { SSR2on = 0; // switch SSR off digitalWrite(PinSSR2, LOW); // turn SSR1 off } bfill.emit_p(http_Found); } else if (strncmp( "?targettemp=" , data , 12 ) == 0) { if (ether.findKeyVal(data + 1, TargetTemperarureTextbox , sizeof TargetTemperarureTextbox , "targettemp") > 0) { byte value = atoi(TargetTemperarureTextbox); // command to convert a string to number if ((value >=0) && (value <=100)) //if the temperature entered is within the range of 0-100 { TargetTemp = value; EEPROM.write(0, value); } } bfill.emit_p(http_Found); } ether.httpServerReply(bfill.position()); } } }