Advertisement
vulture2600

Web Server for Thermostat RTC

Feb 13th, 2014
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.71 KB | None | 0 0
  1. /*--------------------------------------------------------------
  2. Ajax server sketch that serves web page from SD card and sends serial commands to another Arduino
  3. running a thermostat and recieves variable values to send to web client.
  4. steve.a.mccluskey@gmail.com
  5.  
  6.   Modified from sketch found at
  7.   http://startingelectronics.com/tutorials/arduino/ethernet-shield-web-server-tutorial/SD-card-AJAX-XML-web-server/
  8.   Original Author:  W.A. Smith, http://startingelectronics.com
  9.   References:   - WebServer example by David A. Mellis and
  10.                   modified by Tom Igoe
  11.                 - SD card examples by David A. Mellis and
  12.                   Tom Igoe
  13.                 - Ethernet library documentation:
  14.                   http://arduino.cc/en/Reference/Ethernet
  15.                 - SD Card library documentation:
  16.                   http://arduino.cc/en/Reference/SD
  17.  
  18. Pin layout:
  19. 0  : Hardware serial RX.
  20. 1  : Hardware serial TX.
  21. 2  :
  22. 3 ~:
  23. 4  : SD CS.
  24. 5 ~:
  25. 6 ~:
  26. 7  :
  27. 8  :
  28. 9 ~:
  29. 10~: Ethernet shield CS.
  30. 11~: Ethernet shield MOSI.
  31. 12 : Ethernet shield MISO.
  32. 13 : Ethernet shield CLK.
  33.  
  34. Revisions:
  35. 1.2: Added code to handle if sensor is unplugged on the web page, 02/18/14.
  36. 1.2: Added support for temps down to -40F. 02/20/14.
  37. --------------------------------------------------------------*/
  38.  
  39. #include <SPI.h>
  40. #include <Ethernet.h>
  41. #include <SD.h>
  42.  
  43. #define REQ_BUF_SZ 60 // size of buffer used to capture HTTP requests.
  44.  
  45. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  46. IPAddress ip(192, 168, 1, 179); // IP address, may need to change depending on network.
  47. EthernetServer server(80); // create a server at port 80.
  48. File webFile;
  49. char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string.
  50. char req_index = 0; // index into HTTP_req buffer.
  51.  
  52. //variables to serve:
  53. uint8_t tempHold = 0;
  54. int8_t tempAvg = 0;
  55. uint8_t hour = 0;
  56. uint8_t eveningHour = 0;
  57. uint8_t morningHour = 0;
  58. uint8_t tempReduction = 0;
  59. uint8_t door = 0;
  60. uint8_t heater = 0;
  61. int8_t temp1 = 0;
  62. int8_t temp2 = 0;
  63. int8_t temp3 = 0;
  64. int8_t tempOut = 0;
  65.  
  66. unsigned long timeNow = 0, lastUpdate = 0;
  67. String readString;
  68.  
  69. void setup() {
  70.   pinMode(10, OUTPUT);
  71.   digitalWrite(10, HIGH); // disable Ethernet chip.  
  72.   Serial.begin(19200);
  73.      
  74.   if (!SD.begin(4)) { // initialize SD card.
  75.     return;    // init failed.
  76.   } //end if.
  77.  
  78.   if (!SD.exists("index.htm")) { // check for index.htm file.
  79.     return;  // can't find index file.
  80.   } //end if.
  81.  
  82.   Ethernet.begin(mac, ip);
  83.   server.begin();
  84. } //end setup().
  85.  
  86. void loop() {
  87.   timeNow = millis();
  88.   EthernetClient client = server.available();  // try to get client.
  89.  
  90.   if (timeNow - lastUpdate > 10000) { //keeps data fresh when no client connected.
  91.     Serial.println(F("*"));
  92.     lastUpdate = millis();
  93.   } //end if.
  94.    
  95.   if (client) {  // got client?
  96.     boolean currentLineIsBlank = true;
  97.     while (client.connected()) {
  98.       if (client.available()) {
  99.         char c = client.read(); // read 1 byte (character) from client.
  100.         // limit the size of the stored received HTTP request.
  101.         // buffer first part of HTTP request in HTTP_req array (string),
  102.         // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1).
  103.         if (req_index < (REQ_BUF_SZ - 1)) {
  104.           HTTP_req[req_index] = c; // save HTTP request character.
  105.           req_index++;
  106.         } //end if.
  107.        
  108.         // last line of client request is blank and ends with \n
  109.         // respond to client only after last line received:
  110.         if (c == '\n' && currentLineIsBlank) { // send a standard http response header.
  111.           client.println(F("HTTP/1.1 200 OK"));
  112.           // remainder of header follows below, depending on if
  113.           // web page or XML page is requested.
  114.           // Ajax request - send XML file:
  115.           if (StrContains(HTTP_req, "ajax_inputs")) { //send rest of HTTP header.
  116.             Serial.println(F("*")); //request all values from thermostat.
  117.             client.println(F("Content-Type: text/xml"));
  118.             client.println(F("Connection: keep-alive"));
  119.             client.println();
  120.             sendCommands();
  121.             XML_response(client); //send XML file containing input states.
  122.           } //end if.
  123.           else { // web page request.
  124.             // send rest of HTTP header:
  125.             client.println(F("Content-Type: text/html"));
  126.             client.println(F("Connection: keep-alive"));
  127.             client.println();
  128.            
  129.             // send web page:
  130.             webFile = SD.open("index.htm");
  131.             if (webFile) {
  132.               while(webFile.available()) {
  133.                 client.write(webFile.read()); //send web page to client.
  134.               } //end while.
  135.               webFile.close();
  136.             } //end if.
  137.           } //end else.
  138.          
  139.           //Serial.print(HTTP_req); // display received HTTP request on serial port.
  140.          
  141.           // reset buffer index and all buffer elements to 0:
  142.           req_index = 0;
  143.           StrClear(HTTP_req, REQ_BUF_SZ);
  144.           break;
  145.         } //end if.
  146.        
  147.         // every line of text received from the client ends with \r\n.
  148.         if (c == '\n') {
  149.         // last character on line of received text.
  150.         // starting new line with next character read.
  151.           currentLineIsBlank = true;
  152.         }  //end if.
  153.         else if (c != '\r') { // a text character was received from client.
  154.           currentLineIsBlank = false;
  155.         } //end if.
  156.       } // end if client.available().
  157.     } // end while client.connected().
  158.     delay(1);      // give the web browser time to receive the data.
  159.     client.stop(); // close the connection.
  160.   } // end if (client).
  161. } //end loop().
  162.  
  163. // checks if received HTTP request contains certain strings then issues serial commands accordingly.
  164. void sendCommands(void) {
  165.   if (StrContains(HTTP_req, "tempUp")) {
  166.     Serial.println(F("h"));  // increase hold temp.
  167.   } //end if.
  168.   else if (StrContains(HTTP_req, "tempDn")) {
  169.     Serial.println(F("n"));  // decrease hold temp.
  170.   } //end else if
  171.   else if (StrContains(HTTP_req, "nightUp")) {
  172.     Serial.println(F("e"));  // night hour increase.
  173.   } //end else if
  174.   else if (StrContains(HTTP_req, "nightDn")) {
  175.     Serial.println(F("d")); // night hour decrease.
  176.   } //end else if
  177.   else if (StrContains(HTTP_req, "dayUp")) {
  178.     Serial.println(F("m")); // day hour increase.
  179.   } //end else if
  180.   else if (StrContains(HTTP_req, "dayDn")) {
  181.     Serial.println(F("j")); //day hour decrease.
  182.   } //end else if
  183.   else if (StrContains(HTTP_req, "tempRUp")) {
  184.     Serial.println(F("t")); // increase temp reduction.
  185.   } //end else if
  186.   else if (StrContains(HTTP_req, "tempRDn")) {
  187.     Serial.println(F("g")); //decrease temp reduction.
  188.   } //end else if
  189. } //end sendCommands().
  190.  
  191. // send the XML file with current variable values
  192. void XML_response(EthernetClient cl) {
  193.   cl.print(F("<?xml version = \"1.0\" ?>"));
  194.   cl.print(F("<inputs>"));
  195.   cl.print(F("<tempAvg>"));
  196.   cl.print(tempAvg);
  197.   cl.print(F("</tempAvg>"));
  198.   cl.print(F("<tempHold>"));
  199.   cl.print(tempHold);
  200.   cl.print(F("</tempHold>"));
  201.   cl.print(F("<hour>"));
  202.   cl.print(hour);
  203.   cl.print(F("</hour>"));
  204.   cl.print(F("<eveningHour>"));
  205.   cl.print(eveningHour - 12);
  206.   cl.print(F("</eveningHour>"));
  207.   cl.print(F("<morningHour>"));
  208.   cl.print(morningHour);
  209.   cl.print(F("</morningHour>"));
  210.   cl.print(F("<tempReduction>"));
  211.   cl.print(tempReduction);
  212.   cl.print(F("</tempReduction>"));
  213.   cl.print(F("<doorState>"));
  214.   cl.print(door);
  215.   cl.print(F("</doorState>"));
  216.   cl.print(F("<heaterState>"));
  217.   cl.print(heater);
  218.   cl.print(F("</heaterState>"));
  219.   cl.print(F("<sensors>"));
  220.   if (temp1 >= -40) {
  221.     cl.print(temp1);
  222.   } //end if.
  223.   else {
  224.     cl.print(F("--"));
  225.   } //end else.
  226.   cl.print(F("</sensors>"));
  227.   cl.print(F("<sensors>"));
  228.   if (temp2 >= -40) {
  229.     cl.print(temp2);
  230.   } //end if.
  231.   else {
  232.     cl.print(F("--"));
  233.   } //end else.
  234.   cl.print(F("</sensors>"));
  235.   cl.print(F("<sensors>"));
  236.   if (temp3 >= -40) {
  237.     cl.print(temp3);
  238.   } //end if.
  239.   else {
  240.     cl.print(F("--"));
  241.   } //end else.
  242.   cl.print(F("</sensors>"));
  243.   cl.print(F("<sensors>"));
  244.   if (tempOut >= -40) {
  245.     cl.print(tempOut);
  246.   } //end if.
  247.   else {
  248.     cl.print(F("--"));
  249.   } //end else.
  250.   cl.print(F("</sensors>"));
  251.   cl.print(F("</inputs>"));
  252. } //end XML_response().
  253.  
  254. // sets every element of str to 0 (clears array)
  255. void StrClear(char *str, char length) {
  256.   for (uint8_t i = 0; i < length; i++) {
  257.     str[i] = 0;
  258.   } //end for.
  259. } //end StrClear().
  260.  
  261. // searches for the string sfind in the string str
  262. // returns 1 if string found
  263. // returns 0 if string not found
  264. char StrContains(char *str, char *sfind) {
  265.   char found = 0;
  266.   char index = 0;
  267.   char len;
  268.  
  269.   len = strlen(str);
  270.    
  271.   if (strlen(sfind) > len) {
  272.     return 0;
  273.   } //end if.
  274.   while (index < len) {
  275.     if (str[index] == sfind[found]) {
  276.       found++;
  277.       if (strlen(sfind) == found) {
  278.         return 1;
  279.       } //end if.
  280.     } //end if.
  281.     else {
  282.       found = 0;
  283.     } //end else.
  284.     index++;
  285.   } //end while.
  286.   return 0;
  287. } //end StrContains().
  288.  
  289. void serialEvent() { //recieves all values from thermostat and saves to global values.
  290.   while (Serial.available()) {
  291.     char c = Serial.read();
  292.     readString += c;
  293.  
  294.     if (c == '*') { //end of packet.
  295.       uint8_t holdEnd = readString.indexOf('h');
  296.       uint8_t avgEnd = readString.indexOf('a');  
  297.       uint8_t hourEnd = readString.indexOf('j');
  298.       uint8_t eveningEnd = readString.indexOf('e');
  299.       uint8_t morningEnd = readString.indexOf('m');
  300.       uint8_t reductionEnd = readString.indexOf('t');
  301.       uint8_t doorEnd = readString.indexOf('d');
  302.       uint8_t heaterEnd = readString.indexOf('f');
  303.       uint8_t temp1End = readString.indexOf('x');
  304.       uint8_t temp2End = readString.indexOf('y');
  305.       uint8_t temp3End = readString.indexOf('z');
  306.       uint8_t tempOutEnd = readString.indexOf('w');
  307.    
  308.       String hold = readString.substring(0, holdEnd);
  309.       tempHold = hold.toInt();
  310.       String avg = readString.substring(holdEnd + 1, avgEnd);
  311.       tempAvg = avg.toInt();
  312.       String hour1 = readString.substring(avgEnd + 1, hourEnd);
  313.       hour = hour1.toInt();
  314.       String evening = readString.substring(hourEnd + 1, eveningEnd);
  315.       eveningHour = evening.toInt();
  316.       String morning = readString.substring(eveningEnd + 1, morningEnd);
  317.       morningHour = morning.toInt();
  318.       String reduction = readString.substring(morningEnd + 1, reductionEnd);
  319.       tempReduction = reduction.toInt();
  320.       String doorCheck = readString.substring(reductionEnd + 1, doorEnd);
  321.       door = doorCheck.toInt();
  322.       String heaterCheck = readString.substring(doorEnd + 1, heaterEnd);
  323.       heater = heaterCheck.toInt();
  324.       String temp1Check = readString.substring(heaterEnd + 1, temp1End);
  325.       if (temp1Check == "--") {
  326.         temp1 = -41;
  327.       } //end if.
  328.       else {
  329.         temp1 = temp1Check.toInt();
  330.       } //end else.
  331.       String temp2Check = readString.substring(temp1End + 1, temp2End);
  332.       if (temp2Check == "--") {
  333.         temp2 = -41;
  334.       } //end if.
  335.       else {
  336.         temp2 = temp2Check.toInt();
  337.       } //end else.
  338.       String temp3Check = readString.substring(temp2End + 1, temp3End);
  339.       if (temp3Check == "--") {
  340.         temp3 = -41;
  341.       } //end if.
  342.       else {
  343.         temp3 = temp3Check.toInt();
  344.       } //end else.
  345.       String tempOutCheck = readString.substring(temp3End + 1, tempOutEnd);
  346.       if (tempOutCheck == "--") {
  347.         tempOut = -41;
  348.       } //end if.
  349.       else {
  350.         tempOut = tempOutCheck.toInt();
  351.       } //end else.
  352.      
  353.       readString = "";
  354.     } //end if.
  355.   } //end while.
  356. } //end serialEvent().
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement