vulture2600

Thermostat RTC I2C V5.1

Mar 9th, 2015
337
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.45 KB | None | 0 0
  1. /*Thermostat with Real Time Clock Module and web support using second Arduino with ethernet shield.
  2. This sketch takes temp readings from three temp sensors and a door sensor and decides when to turn the heat on or off.
  3.  
  4. Revisions:
  5. V2.2: Web support using second arduino with ethernet shield. Master sends single char commands over serial and thermostat responds accordingly.
  6. V2.3: Added door and heater state to web page.
  7. V2.4: Added EEPROM functionality to save settings to resume on startup.
  8. V2.5: Added code to handle if one of the sensors is unplugged on the web page, 02/18/14.
  9. V2.6: Rewrote button polling, bottom line display and ReadTimeDate() with switch/cases; consolidated door logic, rewrote average functions. 02/19/14.
  10. V2.7: Added functionality to display negative temps down to -40. 02/20/14.
  11. V2.8: Removed averageC(), removed unneccesary lcd.setCursor()'s, fixed average() to correctly return negative temps, changed tempAvgC calculation,
  12.   sensorInterval variable added, C/F mode saved to EEPROM, tempHold limited to 12F minimum, getTemp() analog reading to tempC now uses floating point math and rounding. 03/02/14.
  13.   Changed average() to use floating point math as well. 03/03/14.
  14. V2.9: Changed how often ReadTimeDate() is called. 03/05/14.
  15. V3.0: Added daylight savings time option menu and functionality. 02/23/15.
  16. V3.1: Added doorState variable and only reads door once per loop instead of several times. 02/25/15.
  17. V3.2: Changed ReadTimeDate() to only initialize one string instead of three. Added heaterDelay variable. 02/27/15.
  18.  
  19. V4.0: Added One-Wire Temp sensor support for outdoor temps and getOneWireTemp(). Changed temp variables to temp1, temp2, temp3 from tempNear/Far/Out.
  20. Fixed closing parenthesis typo in getTemp(). Changed const uint8_t's to #define in pin declarations. Limited data[] to two slots in getOneWireTemp(). 03/02/14.
  21. Version 4.0 which uses analog TMP36 temp sensors can be found here: http://pastebin.com/YxKFUr2y
  22.  
  23. V5.0: Rewrote entire sketch to use I2C temp sensors and I2C clock module. 03/04/14.
  24. V5.1: TempHold is now changeable on M8 (temp Out) screen. Added RTC_Interval and changed sensorInterval. Added lastClockCheck2 variable. 03/09/14.
  25.  
  26. Pin layout as follows:
  27. 0  : Hardware serial RX.
  28. 1  : Hardware serial TX.
  29. 2  :
  30. 3 ~: Green LED.
  31. 4  :
  32. 5 ~: Yellow LED.
  33. 6 ~: Red LED.
  34. 7  : Door sensor.
  35. 8  : Heater relay.
  36. 9 ~:
  37. 10~: OneWire bus.
  38. 11~:
  39. 12 :
  40. 13 :
  41. A0 :
  42. A1 :
  43. A2 :
  44. A3 :
  45. A4 : I2C SDA.
  46. A5 : I2C CLK.
  47.  
  48. Sketch outline:
  49. Libraries.
  50. Pin Declarations.
  51. Global Variables.
  52. setup().
  53. loop() {
  54.   Static variables.
  55.   Poll door.
  56.   Poll buttons.
  57.   Poll sensors.
  58.   Print avg/hold to first line.
  59.   Print menu to second line.
  60.   Door closed: switch/case for second line.
  61.   Door open: door open.
  62.   Heater on/off logic.
  63. }
  64. cToF().
  65. getOneWireTemp().
  66. heaterOn().
  67. heaterOff().
  68. clearLine().
  69. average().
  70. serialEvent().  
  71. */
  72.  
  73. #include <Wire.h>
  74. #include "RTClib.h"
  75. #include <RTC_DS1307.h>
  76. #include "Adafruit_MCP9808.h"
  77. #include <Adafruit_MCP23017.h>
  78. #include <Adafruit_RGBLCDShield.h>
  79. #include <EEPROM.h>
  80. #include <OneWire.h>
  81. #include <SPI.h>
  82.  
  83. #define RTC_Interval 150 //delay between RTC updates.
  84. #define sensorInterval 1000 //delay between sensor readings.
  85. #define heaterDelay 120000 //heater on/off delay.
  86.  
  87. //pin declarations:
  88. #define greenLed 3
  89. #define yellowLed 5
  90. #define redLed 6
  91. #define door 7
  92. #define relay 8
  93. #define oneWireBus 10
  94.  
  95. OneWire oneWire(oneWireBus);
  96. byte addr[8]; //array to store OneWire device's address.
  97.  
  98. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
  99. RTC_DS1307 rtc;
  100. Adafruit_MCP9808 tempSensor1 = Adafruit_MCP9808();
  101. Adafruit_MCP9808 tempSensor2 = Adafruit_MCP9808();
  102. Adafruit_MCP9808 tempSensor3 = Adafruit_MCP9808();
  103.  
  104. //global variables:
  105. boolean celsius = EEPROM.read(5);
  106. boolean doorLineCleared = false;
  107. boolean daylightSavings = EEPROM.read(6);
  108.  
  109. uint8_t tempHold = EEPROM.read(0); // read saved tempHold value from EEPROM.
  110. int8_t tempReduction = EEPROM.read(1);
  111. uint8_t menu = EEPROM.read(4);
  112. int8_t temp1, temp2, temp3, tempOneWire, tempAvg; // variables to store temps.
  113. unsigned long heaterOnTime = 0, heaterOffTime = 0, currentTime = 0, lastReadingTime = 0, lastClockCheck = 0, lastClockCheck2 = 0;
  114. uint8_t heaterState = 0, doorState = 0;
  115.  
  116. DateTime now;
  117. uint8_t hour;
  118. uint8_t eveningHour = EEPROM.read(3);
  119. uint8_t morningHour = EEPROM.read(2);
  120.  
  121. void setup() {
  122.   pinMode(redLed, OUTPUT);
  123.   pinMode(greenLed, OUTPUT);
  124.   pinMode(yellowLed, OUTPUT);
  125.   pinMode(door, INPUT_PULLUP); //door pin is pulled to ground while door is closed.
  126.   pinMode(relay, OUTPUT);
  127.   Serial.begin(19200);
  128.   Wire.begin();
  129.   lcd.begin(16, 2);
  130.   lcd.setCursor(0, 0);
  131.   lcd.print(F("RTC Thermostat"));
  132.   lcd.setCursor(0, 1);
  133.   lcd.print(F("V 5.1"));
  134.   delay(1000);
  135.   tempSensor1.begin(0x18); //I2C address.
  136.   tempSensor2.begin(0x19);
  137.   tempSensor3.begin(0x1A);
  138.   oneWire.search(addr); //get connected OneWire device address.
  139.   rtc.begin();
  140.   //rtc.adjust(DateTime(__DATE__, __TIME__)); //set RTC to time of compile, will revert to that time every time arduino is reset. run once and then comment out and reload.
  141.   lcd.clear();
  142. } //end setup().
  143.  
  144. void loop() {
  145.    uint8_t buttons = lcd.readButtons(); //MUST be in main loop. will not work if global.
  146.  
  147.   if (digitalRead(door) == HIGH) { //only read once per loop.
  148.     doorState = 1;
  149.   } //end if.
  150.   else {
  151.     doorState = 0;
  152.   } //end else.
  153.  
  154.   currentTime = millis();
  155.  
  156.   int8_t tempAvgC, temp1C, temp2C, temp3C, tempOneWireC;
  157.   float convF = (5.0 * (tempHold - 32)) / 9.0;
  158.   int8_t tempHoldC = round(convF);
  159.   int8_t tempReductionC = tempReduction / 4;
  160.  
  161.   if (buttons) { //poll the buttons.
  162.     if (buttons & BUTTON_SELECT) {
  163.       celsius = !celsius;
  164.       EEPROM.write(5, celsius); //only write to EEPROM when something is changed to reduce write cycles.
  165.     } //end if.
  166.        
  167.     else if (buttons & BUTTON_UP) {
  168.       switch (menu) { //update variables depending on which menu is selected.      
  169.         case 1:
  170.           tempHold += 2;
  171.           if (tempHold > 80) {
  172.             tempHold = 80;
  173.           } //end if.
  174.           EEPROM.write(0, tempHold);
  175.         break; //end case 1.
  176.        
  177.         case 2:
  178.           tempReduction += 2;
  179.           if (tempReduction > 12) {
  180.             tempReduction = 12;
  181.           } //end if.
  182.           EEPROM.write(1, tempReduction);
  183.         break; //end case 2.
  184.        
  185.         case 3:
  186.           eveningHour ++;
  187.           if (eveningHour > 24) {
  188.             eveningHour = 24;
  189.           } //end if.
  190.           EEPROM.write(3, eveningHour);
  191.         break; //end case 3.
  192.        
  193.         case 4:
  194.           morningHour ++;
  195.           if (morningHour > 11) {
  196.             morningHour = 11;
  197.           } //end if.
  198.           EEPROM.write(2, morningHour);
  199.         break; //end case 4.
  200.        
  201.         case 5:
  202.         break; //end case 5.
  203.        
  204.         case 6:
  205.         break; //end case 6.
  206.        
  207.         case 7:
  208.           daylightSavings = !daylightSavings;
  209.           EEPROM.write(6, daylightSavings);
  210.         break; //end case 7.
  211.        
  212.         case 8:
  213.           tempHold += 2;
  214.           if (tempHold > 80) {
  215.             tempHold = 80;
  216.           } //end if.
  217.           EEPROM.write(0, tempHold);
  218.         break; //end case 8.
  219.        
  220.         default:
  221.         break;
  222.       } //end switch.
  223.     } //end if button_up.
  224.    
  225.     else if (buttons & BUTTON_DOWN) {
  226.       switch (menu) {
  227.         case 1:
  228.           tempHold -= 2;
  229.           if (tempHold < 12) {
  230.             tempHold = 12;
  231.           } //end if.
  232.           EEPROM.write(0, tempHold);
  233.         break; //end case 1.
  234.          
  235.         case 2:
  236.           tempReduction -= 2;
  237.           if (tempReduction <= 0) {
  238.             tempReduction = 0;
  239.           } //end if.
  240.           EEPROM.write(1, tempReduction);
  241.         break; //end case 2.
  242.          
  243.         case 3:
  244.           eveningHour --;
  245.           if (eveningHour < 16) {
  246.             eveningHour = 16;
  247.           } //end if.
  248.           EEPROM.write(3, eveningHour);
  249.         break; //end case 3.
  250.          
  251.         case 4:
  252.           morningHour --;
  253.           if (morningHour < 3) {
  254.             morningHour = 3;
  255.           } //end if.
  256.           EEPROM.write(2, morningHour);
  257.         break; //end case 4.
  258.        
  259.         case 5:
  260.         break; //end case 5.
  261.        
  262.         case 6:
  263.         break; //end case 6.
  264.        
  265.         case 7:
  266.           daylightSavings = !daylightSavings;
  267.           EEPROM.write(6, daylightSavings);
  268.         break; //end case 7.
  269.        
  270.         case 8:
  271.           tempHold -= 2;
  272.           if (tempHold < 12) {
  273.             tempHold = 12;
  274.           } //end if.
  275.           EEPROM.write(0, tempHold);
  276.         break;
  277.          
  278.         default:
  279.         break;
  280.       } //end switch
  281.     } //end if button_down.
  282.          
  283.     else if (buttons & BUTTON_RIGHT) {
  284.       menu ++;
  285.       clearLine(); //clears 2nd line only when menu number is changed.
  286.       if (menu > 8) {
  287.         menu = 1;
  288.       } //end if.
  289.       EEPROM.write(4, menu);
  290.     } //end if.
  291.    
  292.     else if (buttons & BUTTON_LEFT) {
  293.       menu --;
  294.       clearLine();
  295.       if (menu < 1) {
  296.         menu = 8;
  297.       } //end if.
  298.       EEPROM.write(4, menu);
  299.     } //end if.
  300.   } // end if buttons.
  301.  
  302.   if (currentTime - lastClockCheck2 > RTC_Interval) { //get hour of day from RTC.
  303.     now = rtc.now();
  304.     hour = now.hour();
  305.     if (daylightSavings) {
  306.       hour += 1;
  307.     } //end if.
  308.     lastClockCheck2 = currentTime;
  309.   } //end if.
  310.  
  311.   if (currentTime - lastReadingTime > sensorInterval) { //only poll sensors every interval
  312.     if (!celsius) {
  313.       temp1 = cToF(tempSensor1.readTempC()); //poll the sensors.
  314.       temp2 = cToF(tempSensor2.readTempC());
  315.       temp3 = cToF(tempSensor3.readTempC());
  316.       tempAvg = average(temp1, temp2, temp3);
  317.       tempOneWire = getOneWireTemp();      
  318.     } //end if.
  319.     else {
  320.       temp1C = tempSensor1.readTempC();
  321.       temp2C = tempSensor2.readTempC();
  322.       temp3C = tempSensor3.readTempC();
  323.       tempAvgC = average(temp1C, temp2C, temp3C);
  324.       tempOneWireC = getOneWireTemp();
  325.     } //end else.  
  326.    
  327.     lastReadingTime = currentTime;
  328.   } //end if.  
  329.  
  330.    //print avg to screen:
  331.   lcd.setCursor(0, 0);
  332.   lcd.print(F("Avg:"));
  333.   if (!celsius) {
  334.     if (tempAvg >= -40 && tempAvg < 0) { //displays negative temps.
  335.       lcd.print(tempAvg);
  336.       lcd.print(F("F"));
  337.     } //end if.
  338.     else if (tempAvg >= 0) { //displays positive temps and clears last digit.
  339.       lcd.print(tempAvg);
  340.       lcd.print(F("F "));
  341.     } //end else if.
  342.     else {
  343.       lcd.print(F("--F ")); //displays "--" if all 3 sensors are unplugged.
  344.     } //end else.
  345.   } //end if !celsius.
  346.  
  347.   else {
  348.     if (tempAvgC >= -40 && tempAvgC < 0) {
  349.       lcd.print(tempAvgC);
  350.       lcd.print(F("C"));
  351.     } //end if.
  352.     else if (tempAvgC >= 0) {
  353.       lcd.print(tempAvgC);
  354.       lcd.print(F("C "));
  355.     } //end else if.
  356.     else {
  357.       lcd.print(F("--C "));
  358.     } //end else.
  359.   } //end else.
  360.  
  361.   //print hold temp to screen:
  362.   lcd.setCursor(8, 0);
  363.   lcd.print(F("Hold:"));
  364.   lcd.setCursor(13, 0);
  365.   if (hour < morningHour || hour >= eveningHour) { //displays night temp hold at night.
  366.     if (!celsius) {
  367.       lcd.print(tempHold - tempReduction);
  368.       lcd.print(F("*")); //star indicates night time temp reduction.
  369.     } //end if.
  370.     else {
  371.       lcd.print(tempHoldC - tempReductionC);
  372.       lcd.print(F("*"));
  373.     } //end else.
  374.   } //end if.
  375.  
  376.   else if (hour >= morningHour && hour < eveningHour) { //displays regular temp hold during day.
  377.     if (!celsius) {
  378.       lcd.print(tempHold);
  379.       lcd.print(F("F"));
  380.     } //end if.
  381.     else {
  382.       lcd.print(tempHoldC);
  383.       lcd.print(F("C"));
  384.     } //end else.
  385.   } //end else if.
  386.  
  387.   lcd.setCursor(0, 1);
  388.   lcd.print(F("M")); //displays menu number.
  389.   lcd.print(menu);
  390.  
  391.   //bottom line display:
  392.   if (doorState == 0) {
  393.     analogWrite(redLed, 0);
  394.     digitalWrite(greenLed, HIGH); //green led indicates system normal.
  395.     if (!doorLineCleared) { //only clears line once when door is shut.
  396.       clearLine();
  397.       doorLineCleared = true;
  398.     } //end if.
  399.    
  400.     switch (menu) {
  401.       case 1: //displays sensors to screen and allows changing of temp hold.
  402.         lcd.setCursor(2, 1);
  403.         if (!celsius) { //sensor one:
  404.           if (temp1 < -40) { //displays "--" if tempNear returns null and clears leading minus sign.
  405.             lcd.print(F(" --"));
  406.           } //end if.
  407.           else if (temp1 >= -40 && temp1 < 0) { //negative temps.
  408.             lcd.print(temp1);
  409.           } //end else if.
  410.           else {
  411.             lcd.print(F(" ")); //positive temps and clears minus sign.
  412.             lcd.print(temp1);
  413.           } //end else.
  414.           lcd.print(F("F "));
  415.         } //end if.
  416.         else {
  417.           if (temp1C < -40) {
  418.             lcd.print(F(" --"));
  419.           } //end if.
  420.           else if (temp1C >= 40 && temp1C < 0) {
  421.             lcd.print(temp1C);
  422.           } //end else if.
  423.           else {
  424.             lcd.print(F(" "));
  425.             lcd.print(temp1C);
  426.           } // end else.
  427.           lcd.print(F("C "));
  428.         } //end else.
  429.  
  430.         lcd.setCursor(7, 1);
  431.         if (!celsius) { //sensor 2:
  432.           if (temp2 < -40) {
  433.             lcd.print(F(" --"));
  434.           } //end if.
  435.           else if (temp2 >= -40 && temp2 < 0) {
  436.             lcd.print(temp2);
  437.           } //end else if.
  438.           else {
  439.             lcd.print(F(" "));
  440.             lcd.print(temp2);
  441.           } //end else.
  442.           lcd.print(F("F "));
  443.         } //end if.
  444.         else {
  445.           if (temp2C < -40) {
  446.             lcd.print(F(" --"));
  447.           } //end if.
  448.           else if (temp2C >= 40 && temp2C < 0) {
  449.             lcd.print(temp2C);
  450.           } //end else if.
  451.           else {
  452.             lcd.print(F(" "));
  453.             lcd.print(temp2C);
  454.           } // end else.
  455.           lcd.print(F("C "));
  456.         } //end else.
  457.        
  458.         lcd.setCursor(12, 1);
  459.         if (!celsius) { //sensor 3:
  460.           if (temp3 < -40) {
  461.             lcd.print(F(" --"));
  462.           } //end if.
  463.           else if (temp3 >= -40 && temp3 < 0) {
  464.             lcd.print(temp3);
  465.           } //end else if.
  466.           else {
  467.             lcd.print(F(" "));
  468.             lcd.print(temp3);
  469.           } //end else.
  470.           lcd.print(F("F "));
  471.         } //end if.
  472.         else {
  473.           if (temp3C < -40) {
  474.             lcd.print(F(" --"));
  475.           } //end if.
  476.           else if (temp3C >= 40 && temp3C < 0) {
  477.             lcd.print(temp3C);
  478.           } //end else if.
  479.           else {
  480.             lcd.print(F(" "));
  481.             lcd.print(temp3C);
  482.           } // end else.
  483.           lcd.print(F("C "));
  484.         } //end else.
  485.       break; //end menu 1.
  486.  
  487.       case 2: //displays temp drop amount.
  488.         lcd.setCursor(3, 1);
  489.         lcd.print(F("Drop Temp:"));
  490.         if (!celsius) {
  491.           if (tempReduction < 10) {
  492.             lcd.print(F(" "));
  493.           } //end if.
  494.           lcd.print(tempReduction);
  495.           lcd.print(F("F"));
  496.         } //end if.
  497.         else {
  498.           if (tempReductionC < 10) {
  499.             lcd.print(F(" "));
  500.           } //end if.
  501.           lcd.print(tempReductionC);
  502.           lcd.print(F("C"));
  503.         } //end else.
  504.       break; //end menu 2.
  505.  
  506.       case 3: //displays PM time to drop temp:
  507.         lcd.setCursor(3, 1);
  508.         lcd.print(F("Heat Dn: "));
  509.         if (eveningHour < 22) {
  510.           lcd.print(F(" "));
  511.         } //end if.
  512.         lcd.print(eveningHour - 12);
  513.         lcd.print(F("pm"));
  514.       break; //end menu 3.
  515.  
  516.       case 4: //displays AM time to raise temp:
  517.         lcd.setCursor(3, 1);
  518.         lcd.print(F("Heat Up: "));
  519.         if (morningHour < 10) {
  520.           lcd.print(F(" "));
  521.         } //end if.
  522.         lcd.print(morningHour);
  523.         lcd.print(F("am"));
  524.       break; //end menu 4.
  525.  
  526.       case 5: //display time to 2nd row:  
  527.         lcd.setCursor(4, 1);
  528.         lcd.print(F("Tm: "));
  529.         if (currentTime - lastClockCheck > RTC_Interval) {
  530.           now = rtc.now();
  531.           if (hour < 10) {
  532.             lcd.print(F(" "));
  533.           } //end if.
  534.           lcd.print(now.hour());
  535.           lcd.print(F(":"));
  536.           if (now.minute() < 10) {
  537.             lcd.print(F("0"));
  538.           } //end if.
  539.           lcd.print(now.minute());
  540.           lcd.print(F(":"));
  541.           if (now.second() < 10) {
  542.             lcd.print(F("0"));
  543.           } //end if.
  544.           lcd.print(now.second());
  545.           lastClockCheck = currentTime;
  546.         } //end if.
  547.       break; //end menu 5.
  548.  
  549.       case 6: //display date to 2nd row:
  550.         lcd.setCursor(4, 1);
  551.         lcd.print(F("Dt: "));
  552.         if (currentTime - lastClockCheck > RTC_Interval) {
  553.           now = rtc.now();
  554.           if (now.month() < 10) {
  555.             lcd.print(F(" "));
  556.           } //end if.
  557.           lcd.print(now.month());
  558.           lcd.print(F("/"));
  559.           if (now.day() < 10) {
  560.             lcd.print(F("0"));
  561.           } //end if.
  562.           lcd.print(now.day());
  563.           lcd.print(F("/"));
  564.           lcd.print(now.year() - 2000);
  565.           lastClockCheck = currentTime;
  566.         } //end if.
  567.       break; //end menu 6.
  568.      
  569.       case 7: //daylight savings time enable/disable:
  570.         lcd.setCursor(4, 1);
  571.         lcd.print(F("DST:"));
  572.         if (daylightSavings) {
  573.           lcd.print(F("Active  "));
  574.         } //end if.
  575.        
  576.         else {
  577.           lcd.print(F("Inactive"));
  578.         } //end else.
  579.       break;  //end menu 7.
  580.      
  581.       case 8: //prints outside temp to screen.
  582.         lcd.setCursor(4, 1);
  583.         lcd.print(F("Out: "));
  584.         if (!celsius) {
  585.           if (tempOneWire > -51) {
  586.             lcd.print(tempOneWire);
  587.          } //end if.
  588.           else {
  589.             lcd.print("--");
  590.           } //end else.
  591.           lcd.print(F("F   "));
  592.         } //end if celsius.
  593.         else {
  594.           if (tempOneWireC > -51) {
  595.             lcd.print(tempOneWireC);
  596.           } //end if.
  597.           else {
  598.             lcd.print("--");
  599.           } //end else.
  600.           lcd.print(F("C   "));
  601.         } // else.
  602.       break; //end case 8.  
  603.     } //end switch menu.
  604.   } //end if door closed.
  605.  
  606.   else {
  607.     doorLineCleared = false;
  608.     lcd.setCursor(2, 1);
  609.     lcd.print(F(" Door open!   "));
  610.     digitalWrite(greenLed, LOW);
  611.     digitalWrite(yellowLed, LOW);
  612.     digitalWrite(relay, LOW);
  613.     heaterState = 0;
  614.     analogWrite(redLed, 180);
  615.     heaterOffTime = currentTime;
  616.   } //end else if.
  617.  
  618.   //decide when to turn heater on or off:
  619.   if (hour >= morningHour && hour < eveningHour) { //day time
  620.     if (((!celsius && tempAvg > -41 && tempAvg < tempHold) ||
  621.     (celsius && tempAvgC > -41 && tempAvgC < tempHoldC)) && doorState == 0) {
  622.       heaterOn();
  623.     } //end if.
  624.     else {
  625.       heaterOff();
  626.     } //end else.
  627.   } //end if day time.
  628.        
  629.   else if (hour < morningHour || hour >= eveningHour) { //night time
  630.     if (((!celsius && tempAvg > -41 && tempAvg < (tempHold - tempReduction)) ||
  631.     (celsius && tempAvgC > -41 && tempAvgC < (tempHoldC - tempReductionC))) && doorState == 0) {
  632.       heaterOn();
  633.     } //end if.
  634.     else {
  635.       heaterOff();
  636.     } //end else.
  637.   } //end if night time.
  638.  
  639. } //end loop().
  640.  
  641. int8_t cToF(float c) { //convert float C to int F.
  642.   return round((1.8 * c) + 32.0);
  643. } //end cToF().
  644.  
  645. int8_t getOneWireTemp() { //get OneWire temp.
  646.   byte data[2]; //array to store data retrieved from sensor.
  647.   oneWire.reset();
  648.   oneWire.select(addr);
  649.   oneWire.write(0x44, 1); //start conversion.
  650.   oneWire.reset();
  651.   oneWire.select(addr);
  652.   oneWire.write(0xBE); //read scratchpad.
  653.  
  654.   for (byte i = 0; i < 2; i ++) {
  655.     data[i] = oneWire.read(); //collect data.
  656.   } //end for.
  657.  
  658.   int16_t raw = (data[1] << 8) | data[0]; //convert raw data to C.
  659.  
  660.   if (celsius) {
  661.     return round((float)raw / 16.0);
  662.   } //end if.
  663.   else {
  664.     return round(((float)raw / 16.0) * 1.8 + 32.0);
  665.   } //end else.
  666. } //end getOneWireTemp().
  667.  
  668. void heaterOn() {
  669.   if (currentTime - heaterOffTime > heaterDelay) { //check to see if heater has been off for at least 2 min.
  670.     digitalWrite(relay, HIGH);
  671.     analogWrite(yellowLed, 180);
  672.     heaterOnTime = currentTime;
  673.     heaterState = 1;
  674.   } //end if.
  675. } //end heaterOn().
  676.  
  677. void heaterOff() {
  678.   if (currentTime - heaterOnTime > heaterDelay) { //check to see if heater has been on for at least 2 min.
  679.     digitalWrite(relay, LOW);
  680.     digitalWrite(yellowLed, LOW);
  681.     heaterOffTime = currentTime;
  682.     heaterState = 0;
  683.   } //end if.
  684. } //end heaterOff().
  685.  
  686. void clearLine() { //clears 2nd line past M#.
  687.   lcd.setCursor(2, 1);
  688.   lcd.print(F("              "));
  689. } //end clearLine().
  690.  
  691. int8_t average(int8_t temp_1, int8_t temp_2, int8_t temp_3) { //averages 3 temps and knows how depending on which sensors are plugged in.
  692.   uint8_t count = 0;
  693.   float avg = 0.0;
  694.   if (temp_1 > -41) { //sensor connected.
  695.    count ++;
  696.    avg += temp_1;
  697.   } //end if.
  698.   if (temp_2 > -41) {
  699.     count ++;
  700.     avg += temp_2;
  701.   } //end if.
  702.   if (temp_3 > -41) {
  703.     count ++;
  704.     avg += temp_3;
  705.   } //end if.
  706.   if (count != 0) {
  707.     return round(avg / count);
  708.   } //end if.
  709.   else {
  710.     return -41; //all three sensors unplugged.
  711.   } //end else.
  712. } //end average().
  713.  
  714. void serialEvent() { //called any time serial data is available.
  715.   char c = Serial.read();
  716.   switch (c) {
  717.     case '*': //all values requested. sends string of data to be served by other arduino. IE " 64h63a17j9e7m8t0d1f61x62y65z58w* "
  718.       Serial.print(tempHold);
  719.       Serial.print(F("h")); //indicates end of tempHold.
  720.      
  721.       if (tempAvg > -41) {
  722.         Serial.print(tempAvg);
  723.       } //end if.
  724.       else {
  725.         Serial.print(F("--"));
  726.       } //end else.
  727.      
  728.       Serial.print(F("a"));
  729.       Serial.print(hour);
  730.       Serial.print(F("j"));
  731.       Serial.print(eveningHour);
  732.       Serial.print(F("e"));
  733.       Serial.print(morningHour);
  734.       Serial.print(F("m"));
  735.       Serial.print(tempReduction);
  736.       Serial.print(F("t"));
  737.       Serial.print(doorState);
  738.       Serial.print(F("d"));
  739.       Serial.print(heaterState);
  740.       Serial.print(F("f"));
  741.      
  742.       if (temp1 > -41) {
  743.         Serial.print(temp1);
  744.       } //end if.
  745.       else {
  746.         Serial.print(F("--"));
  747.       } //end else.
  748.       Serial.print(F("x"));
  749.    
  750.       if (temp2 > -41) {
  751.         Serial.print(temp2);
  752.       } //end if.
  753.       else {
  754.         Serial.print(F("--"));
  755.       } //end else.
  756.       Serial.print(F("y"));
  757.      
  758.       if (temp3 > -41) {
  759.         Serial.print(temp3);
  760.       } //end if.
  761.       else {
  762.         Serial.print(F("--"));
  763.       } //end else.
  764.       Serial.print(F("z"));
  765.      
  766.       if (tempOneWire > -51) {
  767.         Serial.print(tempOneWire);
  768.       }
  769.       else {
  770.         Serial.print(F("--"));
  771.       }
  772.       Serial.print(F("w"));
  773.      
  774.       Serial.println(F("*")); //end of data character.
  775.     break; //end case '*'.
  776.    
  777.     case 'h': //increase hold temp.
  778.       tempHold += 2;
  779.       if (tempHold > 80) {
  780.         tempHold = 80;
  781.       } //end if.
  782.       EEPROM.write(0, tempHold);
  783.     break; //end case 'h'.
  784.    
  785.     case 'n': //decrease hold temp.
  786.       tempHold -= 2;
  787.       if (tempHold < 12) {
  788.         tempHold = 12;
  789.       } //end if.
  790.       EEPROM.write(0, tempHold);
  791.     break; //end case 'n'.
  792.    
  793.     case 'e': //heat off later.
  794.       eveningHour ++;
  795.       if (eveningHour > 24) {
  796.         eveningHour = 24;
  797.       } //end if.
  798.       EEPROM.write(3, eveningHour);
  799.     break; //end case 'e'.
  800.    
  801.     case 'd': //heat off earlier.
  802.       eveningHour --;
  803.       if (eveningHour < 16) {
  804.         eveningHour = 16;
  805.       } //end if.
  806.       EEPROM.write(3, eveningHour);
  807.     break; //end case 'd'.
  808.    
  809.     case 'm': //heat on later.
  810.       morningHour ++;
  811.       if (morningHour > 11) {
  812.         morningHour = 11;
  813.       } //end if.
  814.       EEPROM.write(2, morningHour);
  815.     break; //end case 'm'.
  816.    
  817.     case 'j': //heat on earlier.
  818.       morningHour --;
  819.       if (morningHour < 3) {
  820.         morningHour = 3;
  821.       } //end if.
  822.       EEPROM.write(2, morningHour);
  823.     break; //end case 'j'.
  824.    
  825.     case 't': //reduce temp more.
  826.       tempReduction += 2;
  827.       if (tempReduction > 12) {
  828.         tempReduction = 12;
  829.       } //end if.
  830.       EEPROM.write(1, tempReduction);
  831.     break; //end case 't'.
  832.    
  833.     case 'g': //reduce temp less.
  834.       tempReduction -= 2;
  835.       if (tempReduction < 0) {
  836.         tempReduction = 0;
  837.       } //end if.
  838.       EEPROM.write(1, tempReduction);
  839.     break; //end case 'g'.
  840.   } //end switch.
  841. } //end serialEvent().
Add Comment
Please, Sign In to add comment