vulture2600

Thermostat RTC v4.0

Feb 13th, 2014
1,985
0
Never
9
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.11 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. This circuit uses a 2.04v analog reference by connecting the 3.3v pin to AREF through a 20k resistor. The internal 32k resistor creates a voltage divider.
  5. The TMP36 temp sensor puts out 1750mV @ 125 degrees Celsius and 100mV @ -40. Since our voltage tops out at 1.75V, using a lower analog reference voltage
  6. provides more resolution at the ADC.
  7.  
  8. To convert an anlog reading to C, we have to do some math:
  9. 0-2.04V over 1024 steps equals 1.992mV per step. At -40C, we should see 100mv, so we divide 100mV by 1.992 to get 50. This means at -40C, we
  10. should see 50 as an analog reading. At 125C the sensor puts out 1750mV, so 1750mV / 1.992 = 878. We then map an analog range of 50 to 878 to a
  11. Celsius range of -40 to 125: map(analogReading, 50, 878, -40, 125). See revision 2.8 for updated floating point math.
  12.  
  13. Revisions:
  14. V2.2: Web support using second arduino with ethernet shield. Master sends single char commands over serial and thermostat responds accordingly.
  15. V2.3: Added door and heater state to web page.
  16. V2.4: Added EEPROM functionality to save settings to resume on startup.
  17. V2.5: Added code to handle if one of the sensors is unplugged on the web page, 02/18/14.
  18. V2.6: Rewrote button polling, bottom line display and ReadTimeDate() with switch/cases; consolidated door logic, rewrote average functions. 02/19/14.
  19. V2.7: Added functionality to display negative temps down to -40. 02/20/14.
  20. V2.8: Removed averageC(), removed unneccesary lcd.setCursor()'s, fixed average() to correctly return negative temps, changed tempAvgC calculation,
  21.   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.
  22.   Changed average() to use floating point math as well. 03/03/14.
  23. V2.9: Changed how often ReadTimeDate() is called. 03/05/14.
  24. V3.0: Added daylight savings time option menu and functionality. 02/23/15.
  25. V3.1: Added doorState variable and only reads door once per loop instead of several times. 02/25/15.
  26. V3.2: Changed ReadTimeDate() to only initialize one string instead of three. Added heaterDelay variable. 02/27/15.
  27.  
  28. V4.0: Added One-Wire Temp sensor support for outdoor temps and getOneWireTemp(). Changed temp variables to temp1, temp2, temp3 from tempNear/Far/Out.
  29. 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.
  30.  
  31. Pin layout as follows:
  32. 0  : Hardware serial RX.
  33. 1  : Hardware serial TX.
  34. 2  : OneWire bus.
  35. 3 ~: Green LED.
  36. 4  :
  37. 5 ~: Yellow LED.
  38. 6 ~: Red LED.
  39. 7  : Door sensor.
  40. 8  : RTC CS.
  41. 9 ~: Heater relay.
  42. 10~:
  43. 11~: RTC MOSI.
  44. 12 : RTC MISO.
  45. 13 : RTC CLK
  46. A0 : Sensor 1.
  47. A1 : Sensor 2.
  48. A2 : Sensor 3.
  49. A3 :
  50. A4 : LCD shield.
  51. A5 : LCD shield.
  52.  
  53. Sketch outline:
  54. Libraries.
  55. Pin Declarations.
  56. Global Variables.
  57. setup().
  58. loop() {
  59.   Static variables.
  60.   Poll buttons.
  61.   Poll sensors.
  62.   Print avg/hold to first line.
  63.   Print menu to second line.
  64.   Door closed: switch/case for second line.
  65.   Door open: door open.
  66.   Heater on/off logic.
  67. }
  68. getTemp().
  69. getOneWireTemp().
  70. heaterOn().
  71. heaterOff().
  72. clearLine().
  73. average().
  74. RTC_init().
  75. ReadTimeDate().
  76. serialEvent().  
  77. */
  78.  
  79. #include <Wire.h>
  80. #include <Adafruit_MCP23017.h>
  81. #include <Adafruit_RGBLCDShield.h>
  82. #include <SPI.h>
  83. #include <EEPROM.h>
  84. #include <OneWire.h>
  85.  
  86. #define sensorInterval 150 //interval between temp sensor readings.
  87. #define heaterDelay 120000 //heater on or off for at least 2 min
  88.  
  89. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
  90.  
  91.  
  92. //pin declarations:
  93. #define oneWireBus 2 //OneWire bus.
  94. #define greenLed 3
  95. #define yellowLed 5
  96. #define redLed 6
  97. #define door 7
  98. #define cs 8
  99. #define relay 9
  100.  
  101. #define tempPin1 0
  102. #define tempPin2 1
  103. #define tempPin3 2
  104.  
  105. OneWire oneWire(oneWireBus);
  106. byte addr[8]; //OneWire temp sensor address.
  107.  
  108. //global variables:
  109. boolean celsius = EEPROM.read(5);
  110. boolean doorLineCleared = false;
  111. boolean daylightSavings = EEPROM.read(6);
  112. uint8_t tempHold = EEPROM.read(0); // read saved tempHold value from EEPROM.
  113. uint8_t tempReduction = EEPROM.read(1);
  114. uint8_t menu = EEPROM.read(4);
  115. int8_t temp1, temp2, temp3, tempOneWire, tempAvg; // variables to store temps.
  116. unsigned long heaterOnTime = 0, heaterOffTime = 0, currentTime = 0, lastReadingTime = 0, lastClockCheck = 0;
  117. uint8_t heaterState = 0;
  118. uint8_t doorState = 0;
  119. uint8_t reading = 0; //columns in matrix.
  120.  
  121. uint16_t val[3][10] = { //array to store analog reading values.
  122.   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  123.   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  124.   {0, 0, 0, 0, 0 ,0, 0, 0, 0, 0}
  125. }; //end val.
  126.  
  127. uint8_t hour;
  128. uint8_t eveningHour = EEPROM.read(3);
  129. uint8_t morningHour = EEPROM.read(2);
  130.  
  131. void setup() {
  132.   analogReference(EXTERNAL); //AREF = 2.04v.
  133.   pinMode(redLed, OUTPUT);
  134.   pinMode(greenLed, OUTPUT);
  135.   pinMode(yellowLed, OUTPUT);
  136.   pinMode(door, INPUT_PULLUP); //door pin is pulled to ground while door is closed.
  137.   pinMode(relay, OUTPUT);
  138.   pinMode(cs, OUTPUT);
  139.   Serial.begin(19200);
  140.   lcd.begin(16, 2);
  141.   lcd.setCursor(0, 0);
  142.   lcd.print(F("RTC Thermostat"));
  143.   lcd.setCursor(0, 1);
  144.   lcd.print(F("V. 4.0"));
  145.   RTC_init();
  146.   delay(1000);
  147.   lcd.clear();  
  148.   oneWire.search(addr); //get connected device's address.
  149. } //end setup().
  150.  
  151. void loop() {
  152.   uint8_t buttons = lcd.readButtons(); //MUST be in main loop. will not work if global.
  153.  
  154.   if (digitalRead(door) == HIGH) { //only read once per loop.
  155.     doorState = 1;
  156.   }
  157.   else {
  158.     doorState = 0;
  159.   }
  160.  
  161.   currentTime = millis();
  162.   String timeString;
  163.  
  164.   int8_t tempAvgC, temp1C, temp2C, temp3C, tempOneWireC;
  165.   float convF = (5.0 * (tempHold - 32)) / 9.0;
  166.   int8_t tempHoldC = round(convF);
  167.   int8_t tempReductionC = tempReduction / 4;
  168.  
  169.   if (buttons) { //poll the buttons.
  170.     if (buttons & BUTTON_SELECT) {
  171.       celsius = !celsius;
  172.       EEPROM.write(5, celsius); //only write to EEPROM when something is changed to reduce write cycles.
  173.     } //end if.
  174.        
  175.     else if (buttons & BUTTON_UP) {
  176.       switch (menu) { //update variables depending on which menu is selected.      
  177.         case 1:
  178.           tempHold += 2;
  179.           if (tempHold > 80) {
  180.             tempHold = 80;
  181.           } //end if.
  182.           EEPROM.write(0, tempHold);
  183.         break; //end case 1.
  184.        
  185.         case 2:
  186.           tempReduction += 2;
  187.           if (tempReduction > 12) {
  188.             tempReduction = 12;
  189.           } //end if.
  190.           EEPROM.write(1, tempReduction);
  191.         break; //end case 2.
  192.        
  193.         case 3:
  194.           eveningHour ++;
  195.           if (eveningHour > 24) {
  196.             eveningHour = 24;
  197.           } //end if.
  198.           EEPROM.write(3, eveningHour);
  199.         break; //end case 3.
  200.        
  201.         case 4:
  202.           morningHour ++;
  203.           if (morningHour > 11) {
  204.             morningHour = 11;
  205.           } //end if.
  206.           EEPROM.write(2, morningHour);
  207.         break; //end case 4.
  208.        
  209.         case 5:
  210.         break; //end case 5.
  211.        
  212.         case 6:
  213.         break; //end case 6.
  214.        
  215.         case 7:
  216.           daylightSavings = !daylightSavings;
  217.           EEPROM.write(6, daylightSavings);
  218.         break; //end case 7.
  219.        
  220.         case 8:
  221.         break; //end case 8.
  222.        
  223.         default:
  224.         break;
  225.       } //end switch.
  226.     } //end if button_up.
  227.    
  228.     else if (buttons & BUTTON_DOWN) {
  229.       switch (menu) {
  230.         case 1:
  231.           tempHold -= 2;
  232.           if (tempHold < 12) {
  233.             tempHold = 12;
  234.           } //end if.
  235.           EEPROM.write(0, tempHold);
  236.         break; //end case 1.
  237.          
  238.         case 2:
  239.           tempReduction -= 2;
  240.           if (tempReduction < 0) {
  241.             tempReduction = 0;
  242.           } //end if.
  243.           EEPROM.write(1, tempReduction);
  244.         break; //end case 2.
  245.          
  246.         case 3:
  247.           eveningHour --;
  248.           if (eveningHour < 16) {
  249.             eveningHour = 16;
  250.           } //end if.
  251.           EEPROM.write(3, eveningHour);
  252.         break; //end case 3.
  253.          
  254.         case 4:
  255.           morningHour --;
  256.           if (morningHour < 3) {
  257.             morningHour = 3;
  258.           } //end if.
  259.           EEPROM.write(2, morningHour);
  260.         break; //end case 4.
  261.        
  262.         case 5:
  263.         break; //end case 5.
  264.        
  265.         case 6:
  266.         break; //end case 6.
  267.        
  268.         case 7:
  269.           daylightSavings = !daylightSavings;
  270.           EEPROM.write(6, daylightSavings);
  271.         break; //end case 7.
  272.        
  273.         case 8:
  274.         break;
  275.          
  276.         default:
  277.         break;
  278.       } //end switch
  279.     } //end if button_down.
  280.          
  281.     else if (buttons & BUTTON_RIGHT) {
  282.       menu ++;
  283.       clearLine(); //clears 2nd line only when menu number is changed.
  284.       if (menu > 8) {
  285.         menu = 1;
  286.       } //end if.
  287.       EEPROM.write(4, menu);
  288.     } //end if.
  289.    
  290.     else if (buttons & BUTTON_LEFT) {
  291.       menu --;
  292.       clearLine();
  293.       if (menu < 1) {
  294.         menu = 8;
  295.       } //end if.
  296.       EEPROM.write(4, menu);
  297.     } //end if.
  298.   } // end if buttons.
  299.  
  300.   if (currentTime - lastReadingTime > sensorInterval) { //only poll sensors every 150ms.
  301.     timeString = ReadTimeDate(2);
  302.     hour = timeString.toInt(); //gets hour of day.
  303.    
  304.     if (!celsius) {
  305.       temp1 = getTemp(tempPin1); //poll the sensors.
  306.       temp2 = getTemp(tempPin2);
  307.       temp3 = getTemp(tempPin3);
  308.       tempAvg = average(temp1, temp2, temp3);
  309.       tempOneWire = getOneWireTemp();      
  310.     } //end if.
  311.     else {
  312.       temp1C = getTemp(tempPin1);
  313.       temp2C = getTemp(tempPin2);
  314.       temp3C = getTemp(tempPin3);
  315.       tempAvgC = average(temp1C, temp2C, temp3C);
  316.       tempOneWireC = getOneWireTemp();
  317.     } //end else.
  318.    
  319.     lastReadingTime = currentTime;
  320.     reading ++; //next column number in the matrix.
  321.     if (reading > 9) { //reset reading counter every 10 readings.
  322.       reading = 0;
  323.     } //end if.
  324.   } //end if.
  325.  
  326.   //print avg to screen:
  327.   lcd.setCursor(0, 0);
  328.   lcd.print(F("Avg:"));
  329.   if (!celsius) {
  330.     if (tempAvg >= -40 && tempAvg < 0) { //displays negative temps.
  331.       lcd.print(tempAvg);
  332.       lcd.print(F("F"));
  333.     } //end if.
  334.     else if (tempAvg >= 0) { //displays positive temps and clears last digit.
  335.       lcd.print(tempAvg);
  336.       lcd.print(F("F "));
  337.     } //end else if.
  338.     else {
  339.       lcd.print(F("--F ")); //displays "--" if all 3 sensors are unplugged.
  340.     } //end else.
  341.   } //end if !celsius.
  342.  
  343.   else {
  344.     if (tempAvgC >= -40 && tempAvgC < 0) {
  345.       lcd.print(tempAvgC);
  346.       lcd.print(F("C"));
  347.     } //end if.
  348.     else if (tempAvgC >= 0) {
  349.       lcd.print(tempAvgC);
  350.       lcd.print(F("C "));
  351.     } //end else if.
  352.     else {
  353.       lcd.print(F("--C "));
  354.     } //end else.
  355.   } //end else.
  356.  
  357.   //print hold temp to screen:
  358.   lcd.setCursor(8, 0);
  359.   lcd.print(F("Hold:"));
  360.   lcd.setCursor(13, 0);
  361.   if (hour < morningHour || hour >= eveningHour) { //displays night temp hold at night.
  362.     if (!celsius) {
  363.       lcd.print(tempHold - tempReduction);
  364.       lcd.print(F("*")); //star indicates night time temp reduction.
  365.     } //end if.
  366.     else {
  367.       lcd.print(tempHoldC - tempReductionC);
  368.       lcd.print(F("*"));
  369.     } //end else.
  370.   } //end if.
  371.  
  372.   else if (hour >= morningHour && hour < eveningHour) { //displays regular temp hold during day.
  373.     if (!celsius) {
  374.       lcd.print(tempHold);
  375.       lcd.print(F("F"));
  376.     } //end if.
  377.     else {
  378.       lcd.print(tempHoldC);
  379.       lcd.print(F("C"));
  380.     } //end else.
  381.   } //end else if.
  382.  
  383.   lcd.setCursor(0, 1);
  384.   lcd.print(F("M")); //displays menu number.
  385.   lcd.print(menu);
  386.  
  387.   //bottom line display:
  388.   if (doorState == 0) {
  389.     analogWrite(redLed, 0);
  390.     digitalWrite(greenLed, HIGH); //green led indicates system normal.
  391.     if (!doorLineCleared) { //only clears line once when door is shut.
  392.       clearLine();
  393.       doorLineCleared = true;
  394.     } //end if.
  395.    
  396.     switch (menu) {
  397.       case 1: //displays sensors to screen and allows changing of temp hold.
  398.         lcd.setCursor(2, 1);
  399.         if (!celsius) { //sensor one:
  400.           if (temp1 < -40) { //displays "--" if tempNear returns null and clears leading minus sign.
  401.             lcd.print(F(" --"));
  402.           } //end if.
  403.           else if (temp1 >= -40 && temp1 < 0) { //negative temps.
  404.             lcd.print(temp1);
  405.           } //end else if.
  406.           else {
  407.             lcd.print(F(" ")); //positive temps and clears minus sign.
  408.             lcd.print(temp1);
  409.           } //end else.
  410.           lcd.print(F("F "));
  411.         } //end if.
  412.         else {
  413.           if (temp1C < -40) {
  414.             lcd.print(F(" --"));
  415.           } //end if.
  416.           else if (temp1C >= 40 && temp1C < 0) {
  417.             lcd.print(temp1C);
  418.           } //end else if.
  419.           else {
  420.             lcd.print(F(" "));
  421.             lcd.print(temp1C);
  422.           } // end else.
  423.           lcd.print(F("C "));
  424.         } //end else.
  425.  
  426.         lcd.setCursor(7, 1);
  427.         if (!celsius) { //sensor 2:
  428.           if (temp2 < -40) {
  429.             lcd.print(F(" --"));
  430.           } //end if.
  431.           else if (temp2 >= -40 && temp2 < 0) {
  432.             lcd.print(temp2);
  433.           } //end else if.
  434.           else {
  435.             lcd.print(F(" "));
  436.             lcd.print(temp2);
  437.           } //end else.
  438.           lcd.print(F("F "));
  439.         } //end if.
  440.         else {
  441.           if (temp2C < -40) {
  442.             lcd.print(F(" --"));
  443.           } //end if.
  444.           else if (temp2C >= 40 && temp2C < 0) {
  445.             lcd.print(temp2C);
  446.           } //end else if.
  447.           else {
  448.             lcd.print(F(" "));
  449.             lcd.print(temp2C);
  450.           } // end else.
  451.           lcd.print(F("C "));
  452.         } //end else.
  453.        
  454.         lcd.setCursor(12, 1);
  455.         if (!celsius) { //sensor 3:
  456.           if (temp3 < -40) {
  457.             lcd.print(F(" --"));
  458.           } //end if.
  459.           else if (temp3 >= -40 && temp3 < 0) {
  460.             lcd.print(temp3);
  461.           } //end else if.
  462.           else {
  463.             lcd.print(F(" "));
  464.             lcd.print(temp3);
  465.           } //end else.
  466.           lcd.print(F("F "));
  467.         } //end if.
  468.         else {
  469.           if (temp3C < -40) {
  470.             lcd.print(F(" --"));
  471.           } //end if.
  472.           else if (temp3C >= 40 && temp3C < 0) {
  473.             lcd.print(temp3C);
  474.           } //end else if.
  475.           else {
  476.             lcd.print(F(" "));
  477.             lcd.print(temp3C);
  478.           } // end else.
  479.           lcd.print(F("C "));
  480.         } //end else.
  481.       break; //end menu 1.
  482.  
  483.       case 2: //displays temp drop amount.
  484.         lcd.setCursor(3, 1);
  485.         lcd.print(F("Drop Temp:"));
  486.         if (!celsius) {
  487.           if (tempReduction < 10) {
  488.             lcd.print(F(" "));
  489.           } //end if.
  490.           lcd.print(tempReduction);
  491.           lcd.print(F("F"));
  492.         } //end if.
  493.         else {
  494.           if (tempReductionC < 10) {
  495.             lcd.print(F(" "));
  496.           } //end if.
  497.           lcd.print(tempReductionC);
  498.           lcd.print(F("C"));
  499.         } //end else.
  500.       break; //end menu 2.
  501.  
  502.       case 3: //displays PM time to drop temp:
  503.         lcd.setCursor(3, 1);
  504.         lcd.print(F("Heat Dn: "));
  505.         if (eveningHour < 22) {
  506.           lcd.print(F(" "));
  507.         } //end if.
  508.         lcd.print(eveningHour - 12);
  509.         lcd.print(F("pm"));
  510.       break; //end menu 3.
  511.  
  512.       case 4: //displays AM time to raise temp:
  513.         lcd.setCursor(3, 1);
  514.         lcd.print(F("Heat Up: "));
  515.         if (morningHour < 10) {
  516.           lcd.print(F(" "));
  517.         } //end if.
  518.         lcd.print(morningHour);
  519.         lcd.print(F("am"));
  520.       break; //end menu 4.
  521.  
  522.       case 5: //display time to 2nd row:  
  523.         lcd.setCursor(4, 1);
  524.         lcd.print(F("Tm: "));
  525.         if (currentTime - lastClockCheck > sensorInterval) {
  526.           lcd.print(ReadTimeDate(1)); //gets time only.
  527.           lastClockCheck = currentTime;
  528.         } //end if.
  529.       break; //end menu 5.
  530.  
  531.       case 6: //display date to 2nd row:
  532.         lcd.setCursor(4, 1);
  533.         lcd.print(F("Dt: "));
  534.         if (currentTime - lastClockCheck > sensorInterval) {
  535.           lcd.print(ReadTimeDate(0)); //gets date only.
  536.           lastClockCheck = currentTime;
  537.         } //end if.
  538.       break; //end menu 6.
  539.      
  540.       case 7: //daylight savings time enable/disable:
  541.         lcd.setCursor(4, 1);
  542.         lcd.print(F("DST:"));
  543.         if (daylightSavings) {
  544.           lcd.print(F("Active  "));
  545.         } //end if.
  546.        
  547.         else {
  548.           lcd.print(F("Inactive"));
  549.         } //end else.
  550.       break;  //end menu 7.
  551.      
  552.       case 8: //prints outside temp to screen.
  553.         lcd.setCursor(4, 1);
  554.         lcd.print(F("Out: "));
  555.         if (!celsius) {
  556.           if (tempOneWire > -51) {
  557.             lcd.print(tempOneWire);
  558.          } //end if.
  559.           else {
  560.             lcd.print("--");
  561.           } //end else.
  562.           lcd.print(F("F   "));
  563.         } //end if celsius.
  564.         else {
  565.           if (tempOneWireC > -51) {
  566.             lcd.print(tempOneWireC);
  567.           } //end if.
  568.           else {
  569.             lcd.print("--");
  570.           } //end else.
  571.           lcd.print(F("C   "));
  572.         } // else.
  573.       break; //end case 8.  
  574.     } //end switch menu.
  575.   } //end if door closed.
  576.  
  577.   else {
  578.     doorLineCleared = false;
  579.     lcd.setCursor(2, 1);
  580.     lcd.print(F(" Door open!   "));
  581.     digitalWrite(greenLed, LOW);
  582.     digitalWrite(yellowLed, LOW);
  583.     digitalWrite(relay, LOW);
  584.     heaterState = 0;
  585.     analogWrite(redLed, 180);
  586.     heaterOffTime = currentTime;
  587.   } //end else if.
  588.  
  589.   //decide when to turn heater on or off:
  590.   if (hour >= morningHour && hour < eveningHour) { //day time
  591.     if (((!celsius && tempAvg > -41 && tempAvg < tempHold) ||
  592.     (celsius && tempAvgC > -41 && tempAvgC < tempHoldC)) && doorState == 0) {
  593.       heaterOn();
  594.     } //end if.
  595.     else {
  596.       heaterOff();
  597.     } //end else.
  598.   } //end if day time.
  599.        
  600.   else if (hour < morningHour || hour >= eveningHour) { //night time
  601.     if (((!celsius && tempAvg > -41 && tempAvg < (tempHold - tempReduction)) ||
  602.     (celsius && tempAvgC > -41 && tempAvgC < (tempHoldC - tempReductionC))) && doorState == 0) {
  603.       heaterOn();
  604.     } //end if.
  605.     else {
  606.       heaterOff();
  607.     } //end else.
  608.   } //end if night time.
  609. } //end loop().  
  610.  
  611. /* getTemp(): each time the function is called, a new reading is taken and stored to the 3x10 matrix. each row is then averaged and
  612. returned as temp for each sensor. AREF = 2.04V.
  613. */
  614. int8_t getTemp(uint8_t pin) {
  615.   val[pin][reading] = analogRead(pin);
  616.   delay(2); //delay between each analog pin is needed to reduce cross interferance between readings.
  617.   if (val[pin][reading] < 50) { //sensor unplugged.
  618.     return -41;
  619.   } //end if.
  620.   uint16_t sum = 0;
  621.   for (uint8_t i = 0; i <= 9; i ++) { //adds up all the values in the row.
  622.     sum += val[pin][i];
  623.   } //end for.
  624.   sum /= 10;
  625.   float tempC = ((sum - 50.0) * (165.0) / (828.0)) - 40.0; //convert analog reading to celsius using floating point math instead of map(sum, 50, 878, -40, 125).
  626.   if (celsius) {
  627.     return round(tempC);
  628.   } //end if.
  629.   else {
  630.     return round((1.8 * tempC) + 32.0);
  631.   } // end else.
  632. } //end getTemp().
  633.  
  634. int8_t getOneWireTemp() {
  635.   byte data[2]; //array to store data retrieved from sensor.
  636.   oneWire.reset();
  637.   oneWire.select(addr);
  638.   oneWire.write(0x44, 1); //start conversion.
  639.   oneWire.reset();
  640.   oneWire.select(addr);
  641.   oneWire.write(0xBE); //read scratchpad.
  642.  
  643.   for (byte i = 0; i < 3; i ++) {
  644.     data[i] = oneWire.read(); //collect data.
  645.   } //end for.
  646.  
  647.   int16_t raw = (data[1] << 8) | data[0]; //convert raw data to C.
  648.  
  649.   if (celsius) {
  650.     return round((float)raw / 16.0);
  651.   } //end if.
  652.   else {
  653.     return round(((float)raw / 16.0) * 1.8 + 32.0);
  654.   } //end else.
  655. } //end getOneWireTemp().
  656.  
  657. void heaterOn() {
  658.   if (currentTime - heaterOffTime > heaterDelay) { //check to see if heater has been off for at least 2 min.
  659.     digitalWrite(relay, HIGH);
  660.     analogWrite(yellowLed, 180);
  661.     heaterOnTime = currentTime;
  662.     heaterState = 1;
  663.   } //end if.
  664. } //end heaterOn().
  665.  
  666. void heaterOff() {
  667.   if (currentTime - heaterOnTime > heaterDelay) { //check to see if heater has been on for at least 2 min.
  668.     digitalWrite(relay, LOW);
  669.     digitalWrite(yellowLed, LOW);
  670.     heaterOffTime = currentTime;
  671.     heaterState = 0;
  672.   } //end if.
  673. } //end heaterOff().
  674.  
  675. void clearLine() { //clears 2nd line past M#.
  676.   lcd.setCursor(2, 1);
  677.   lcd.print(F("              "));
  678. } //end clearLine().
  679.  
  680. 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.
  681.   uint8_t count = 0;
  682.   float avg = 0.0;
  683.   if (temp_1 > -41) { //sensor connected.
  684.    count ++;
  685.    avg += temp_1;
  686.   } //end if.
  687.   if (temp_2 > -41) {
  688.     count ++;
  689.     avg += temp_2;
  690.   } //end if.
  691.   if (temp_3 > -41) {
  692.     count ++;
  693.     avg += temp_3;
  694.   } //end if.
  695.   if (count != 0) {
  696.     return round(avg / count);
  697.   } //end if.
  698.   else {
  699.     return -41; //all three sensors unplugged.
  700.   } //end else.
  701. } //end average().
  702.  
  703. void RTC_init() { //start the RTC chip.
  704.   SPI.begin();
  705.   SPI.setBitOrder(MSBFIRST);
  706.   SPI.setDataMode(SPI_MODE1); // both mode 1 & 3 should work.  
  707.   digitalWrite(cs, LOW); //set control register.  
  708.   SPI.transfer(0x8E);
  709.   SPI.transfer(0x60); //60= disable Osciallator and Battery SQ wave @1hz, temp compensation, Alarms disabled.
  710.   digitalWrite(cs, HIGH);
  711.   delay(10);
  712. } //end RTC_init().
  713.  
  714. String ReadTimeDate(uint8_t mode) { //gets time and date.
  715.   String dateTime;
  716.   uint8_t TimeDate [7]; //second,minute,hour,null,day,month,year       
  717.   for (uint8_t i = 0; i <= 6; i ++) {
  718.     if (i == 3) {
  719.       i ++;
  720.     } //end if.
  721.     digitalWrite(cs, LOW);
  722.     SPI.transfer(i + 0x00);
  723.     unsigned int n = SPI.transfer(0x00);        
  724.     digitalWrite(cs, HIGH);
  725.     int a = n & B00001111;    
  726.     if (i == 2) {  
  727.       int b = (n & B00110000) >> 4; //24 hour mode
  728.       if (b == B00000010) {
  729.         b = 20;
  730.       } //end if.        
  731.       else if (b == B00000001) {
  732.         b = 10;
  733.       } //end else.
  734.       TimeDate[i] = a + b;
  735.     } //end if.
  736.     else if (i == 4) {
  737.       int b = (n & B00110000) >> 4;
  738.       TimeDate[i] = a + b * 10;
  739.     } //end else.
  740.     else if (i == 5) {
  741.       int b = (n & B00010000) >> 4;
  742.       TimeDate[i] = a + b * 10;
  743.     } //end else.
  744.     else if (i == 6) {
  745.       int b = (n & B11110000) >> 4;
  746.       TimeDate[i] = a + b * 10;
  747.     } //end else.
  748.     else { 
  749.       int b = (n & B01110000) >> 4;
  750.       TimeDate[i] = a + b * 10;
  751.     } //end else.
  752.   } //end for.
  753.  
  754.   if (daylightSavings) { //reduce hour slot by 1.
  755.         TimeDate[2] -= 1;
  756.   } //end if.
  757.  
  758.   switch (mode) {
  759.     case 0: //returns date only.
  760.       if (TimeDate[5] < 10) {
  761.         dateTime.concat("0"); //leading zero.
  762.       } //end if.
  763.       dateTime.concat(TimeDate[5]);
  764.       dateTime.concat("/");
  765.       if (TimeDate[4] < 10) {
  766.         dateTime.concat("0");
  767.       } //end if.
  768.       dateTime.concat(TimeDate[4]);
  769.       dateTime.concat("/");
  770.       dateTime.concat(TimeDate[6]);
  771.       return dateTime;
  772.     break; //end mode 0.
  773.  
  774.     case 1: //returns time only.
  775.       if (TimeDate[2] < 10) {
  776.         dateTime.concat("0"); //leading zero
  777.       } //end if.
  778.       dateTime.concat(TimeDate[2]);
  779.       dateTime.concat(":");
  780.       if (TimeDate[1] < 10) {
  781.         dateTime.concat("0");
  782.       } //end if.
  783.       dateTime.concat(TimeDate[1]);
  784.       dateTime.concat(":");
  785.       if (TimeDate[0] < 10) {
  786.         dateTime.concat("0");
  787.       } //end if.
  788.       dateTime.concat(TimeDate[0]);
  789.       return dateTime;
  790.     break; //end mode 1.
  791.  
  792.     case 2: //returns hour of day only.
  793.       dateTime.concat(TimeDate[2]);
  794.       return dateTime;
  795.     break; //end mode 2.
  796.   } //end switch.
  797. } //end ReadTimeDate().
  798.  
  799. void serialEvent() { //called any time serial data is available.
  800.   char c = Serial.read();
  801.   switch (c) {
  802.     case '*': //all values requested. sends string of data to be served by other arduino. IE " 64h63a17j9e7m8t0d1f61x62y65z58w* "
  803.       Serial.print(tempHold);
  804.       Serial.print(F("h")); //indicates end of tempHold.
  805.      
  806.       if (tempAvg > -41) {
  807.         Serial.print(tempAvg);
  808.       } //end if.
  809.       else {
  810.         Serial.print(F("--"));
  811.       } //end else.
  812.      
  813.       Serial.print(F("a"));
  814.       Serial.print(hour);
  815.       Serial.print(F("j"));
  816.       Serial.print(eveningHour);
  817.       Serial.print(F("e"));
  818.       Serial.print(morningHour);
  819.       Serial.print(F("m"));
  820.       Serial.print(tempReduction);
  821.       Serial.print(F("t"));
  822.       Serial.print(doorState);
  823.       Serial.print(F("d"));
  824.       Serial.print(heaterState);
  825.       Serial.print(F("f"));
  826.      
  827.       if (temp1 > -41) {
  828.         Serial.print(temp1);
  829.       } //end if.
  830.       else {
  831.         Serial.print(F("--"));
  832.       } //end else.
  833.       Serial.print(F("x"));
  834.    
  835.       if (temp2 > -41) {
  836.         Serial.print(temp2);
  837.       } //end if.
  838.       else {
  839.         Serial.print(F("--"));
  840.       } //end else.
  841.       Serial.print(F("y"));
  842.      
  843.       if (temp3 > -41) {
  844.         Serial.print(temp3);
  845.       } //end if.
  846.       else {
  847.         Serial.print(F("--"));
  848.       } //end else.
  849.       Serial.print(F("z"));
  850.      
  851.       if (tempOneWire > -51) {
  852.         Serial.print(tempOneWire);
  853.       }
  854.       else {
  855.         Serial.print(F("--"));
  856.       }
  857.       Serial.print(F("w"));
  858.      
  859.       Serial.println(F("*")); //end of data character.
  860.     break; //end case '*'.
  861.    
  862.     case 'h': //increase hold temp.
  863.       tempHold += 2;
  864.       if (tempHold > 80) {
  865.         tempHold = 80;
  866.       } //end if.
  867.       EEPROM.write(0, tempHold);
  868.     break; //end case 'h'.
  869.    
  870.     case 'n': //decrease hold temp.
  871.       tempHold -= 2;
  872.       if (tempHold < 12) {
  873.         tempHold = 12;
  874.       } //end if.
  875.       EEPROM.write(0, tempHold);
  876.     break; //end case 'n'.
  877.    
  878.     case 'e': //heat off later.
  879.       eveningHour ++;
  880.       if (eveningHour > 24) {
  881.         eveningHour = 24;
  882.       } //end if.
  883.       EEPROM.write(3, eveningHour);
  884.     break; //end case 'e'.
  885.    
  886.     case 'd': //heat off earlier.
  887.       eveningHour --;
  888.       if (eveningHour < 16) {
  889.         eveningHour = 16;
  890.       } //end if.
  891.       EEPROM.write(3, eveningHour);
  892.     break; //end case 'd'.
  893.    
  894.     case 'm': //heat on later.
  895.       morningHour ++;
  896.       if (morningHour > 11) {
  897.         morningHour = 11;
  898.       } //end if.
  899.       EEPROM.write(2, morningHour);
  900.     break; //end case 'm'.
  901.    
  902.     case 'j': //heat on earlier.
  903.       morningHour --;
  904.       if (morningHour < 3) {
  905.         morningHour = 3;
  906.       } //end if.
  907.       EEPROM.write(2, morningHour);
  908.     break; //end case 'j'.
  909.    
  910.     case 't': //reduce temp more.
  911.       tempReduction += 2;
  912.       if (tempReduction > 12) {
  913.         tempReduction = 12;
  914.       } //end if.
  915.       EEPROM.write(1, tempReduction);
  916.     break; //end case 't'.
  917.    
  918.     case 'g': //reduce temp less.
  919.       tempReduction -= 2;
  920.       if (tempReduction < 0) {
  921.         tempReduction = 0;
  922.       } //end if.
  923.       EEPROM.write(1, tempReduction);
  924.     break; //end case 'g'.
  925.   } //end switch.
  926. } //end serialEvent().
  927.  
  928. /*
  929. void printResults() { //for debugging.
  930.   Serial.println(ReadTimeDate(0));
  931.   Serial.println(ReadTimeDate(1));
  932.   Serial.print(F("Menu #: "));
  933.   Serial.println(menu);
  934.   Serial.println();
  935.   Serial.print(F("Hold temp: "));
  936.   Serial.println(tempHold);
  937.   Serial.println();
  938.   Serial.print(F("Average temp: "));
  939.   Serial.println(tempAvg);
  940.   Serial.println();
  941.   Serial.println(F("Sensor one: "));
  942.   for (uint8_t i = 0; i <= 9; i ++) {
  943.     Serial.print(val[0][i]);
  944.     Serial.print(F(" "));
  945.   } //end for.
  946.   Serial.println();
  947.   Serial.println(F("Sensor two: "));
  948.   for (uint8_t i = 0; i <= 9; i ++) {  
  949.     Serial.print(val[1][i]);
  950.     Serial.print(F(" "));
  951.   } //end for.
  952.   Serial.println();
  953.   Serial.println(F("Sensor three: "));
  954.   for (uint8_t i = 0; i <= 9; i ++) {
  955.     Serial.print(val[2][i]);
  956.     Serial.print(F(" "));
  957.   } //end for.
  958.   Serial.println();
  959. } //end printResults().*/
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment