vulture2600

Thermostat RTC I2C V5.1

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