Advertisement
UnaClocker

Dishwasher

May 22nd, 2011
17,159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.37 KB | None | 0 0
  1. // This sketch written for the Arduino Uno/Duemelinova
  2. // Licensed Creative Commons
  3. // Written by Brian Gosney (UnaClocker) May 2011
  4. // This code runs my dishwasher via some relays. It monitors the NTC thermistor water temp sensor
  5. // More details will be at http://www.neonsquirt.com/dishwasher.html
  6. // This is code revision 3.4 - Now compiles on Arduino 1.0, most strings moved to F("Flash, rather than SRAM")
  7.  
  8.  
  9. #include <math.h>  // Needed for the logarithmic NTC thermistor temp sensor
  10. #include <LiquidCrystal.h>  // For the 4x20 LCD status screen
  11. #include <Wire.h>  // Used for the I2C RTC chip
  12. #include "Chronodot.h"  // Used to fetch and decode the RTC data
  13.  
  14. Chronodot RTC; // Create the RTC object
  15. LiquidCrystal lcd(8,9,10,11,12,13);  // These are the pins used for the parallel LCD
  16. char* dayOfWeek[]={
  17.   "Sunday  ", "Monday", "Tuesday", "Wednesday", "Thursday ", "Friday  ", "Saturday"};
  18. // using pointers to point at an array of arrays of characters.
  19. char* currentMonth[]={
  20.   "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
  21. boolean pm=false;  // AM or PM, for the clock
  22. unsigned long cycleStart;  // Used for keeping track of how long it's been washing.
  23. double tempArray[25];  // Array of temperatures, to average readings and reduce jitter
  24. byte arrayIndex=0;  // Used to count temperature samples
  25.  
  26. #define ventPin 7
  27. #define soapDispensor 6
  28. #define waterInlet 5
  29. #define drainPin 4
  30. #define washMotor 3
  31. #define heaterPin 2
  32. #define goButton A1
  33. #define tempSensor A2
  34. #define goLight 0
  35. #define stopLight 1
  36. #define stopButton A3
  37. #define tiltSensor A0
  38.  
  39. //void dLay(integer howLong) {
  40. //}
  41.  
  42. double waterTemp() {  // This subroutine came from the Arduino Playground
  43.   if (arrayIndex> 23) {
  44.     arrayIndex=0; // 25 samples, 0 to 24, when it hits 24, reset to 0
  45.   }
  46.   else {
  47.     arrayIndex++;  // Increment array index counter
  48.   }
  49.   double Temp;        // The Thermistor2 "Simple Code"
  50.   int RawADC = analogRead(tempSensor);
  51.   Temp = log(((10240000/RawADC) - 10000));  // I believe the - 10000 is because it's a 10k thermistor?
  52.   Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
  53.   Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  54.   Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
  55.   tempArray[arrayIndex]=Temp; // replace the reading at this index with the current reading
  56.   Temp=0;  // reset the temporary variable to 0
  57.   for (int i=0; i<24; i++) {
  58.     Temp += tempArray[i]; // add all of the elements in the array together
  59.   }
  60.   return (Temp / 25);  // return the average temp from the array
  61. }
  62.  
  63. void setup () {
  64.   for (int i=0; i<25; i++) tempArray[i]=70;  // Fill the temperature array with sane numbers.
  65.   Wire.begin();   // Used for the RTC
  66.   RTC.begin();    // Likewise
  67.   lcd.begin(20,4);  // 4x20 LCD Panel
  68.   pinMode(tempSensor, INPUT);
  69.   pinMode(ventPin, OUTPUT);
  70.   pinMode(soapDispensor, OUTPUT);
  71.   pinMode(waterInlet, OUTPUT);
  72.   pinMode(drainPin, OUTPUT);
  73.   pinMode(washMotor, OUTPUT);
  74.   pinMode(heaterPin, OUTPUT);
  75.   pinMode(goButton, INPUT);
  76.   digitalWrite(goButton, HIGH);  // activate internal pull-up resistor for this input pin  
  77.   pinMode(stopButton, INPUT);
  78.   pinMode(tiltSensor, INPUT);
  79.   digitalWrite(stopButton, HIGH);
  80.   digitalWrite(tiltSensor, HIGH);
  81.   pinMode(0, OUTPUT);
  82.   pinMode(1, OUTPUT);
  83. }
  84.  
  85. void updateRuntimeDisplay(byte currentMode) {  // I'm not happy with this routine. Needs work.
  86.   unsigned long elapsedSeconds = ((millis() - cycleStart) / 1000); // Come up with the number of seconds elapsed
  87.   unsigned long elapsedMinutes = (elapsedSeconds / 60);
  88.   unsigned long elapsedHours = (elapsedMinutes / 60);
  89.   lcd.setCursor(0,0);
  90.   lcd.print(F("Cycle Time: "));
  91.   if (elapsedHours > 0) { // Don't display the hours elapsed if less than an hour has elapsed.
  92.     lcd.print(elapsedHours);
  93.     lcd.print(':');
  94.     if (elapsedHours == 1) elapsedMinutes -= 60;
  95.     if (elapsedHours == 2) elapsedMinutes -= 120;
  96.   }
  97.   if (elapsedMinutes < 10) { // Only displays a single digit, so needs an extra zero.
  98.     lcd.print('0');
  99.   }
  100.   lcd.print(elapsedMinutes);
  101.   lcd.setCursor(0,1);
  102.   lcd.print(F("Water Temp: "));  
  103.   lcd.print(int(waterTemp()));
  104.   lcd.print('F');
  105.   lcd.setCursor(0,3);
  106.   switch (currentMode) {
  107.   case 1:
  108.     lcd.print(F("Filling             "));
  109.     break;
  110.   case 2:
  111.     lcd.print(F("Draining            "));
  112.     break;
  113.   case 3:
  114.     lcd.print(F("Washing the dishes  "));
  115.     break;
  116.   case 4:
  117.     lcd.print(F("10 minute Pre-Rinse "));
  118.     break;
  119.   case 5:
  120.     lcd.print(F("Final Rinse         "));
  121.     break;
  122.   case 6:
  123.     lcd.print(F("Drying Clean Dishes "));
  124.     break;
  125.   }  
  126. }
  127.  
  128. void fillItUp() {
  129.   unsigned long fillTime = millis();
  130.   digitalWrite(waterInlet, HIGH);
  131.   while ((millis() - fillTime) < 105000) { // 1 minute, 45 seconds to fill the dishwasher
  132.     delay(100);
  133.     updateRuntimeDisplay(1);
  134.   }
  135.   digitalWrite(waterInlet, LOW);
  136.   delay(100);
  137.   lcd.begin(20,4);
  138.   lcd.clear();
  139. }
  140.  
  141. void drainItOut() {
  142.   unsigned long drainTime = millis();
  143.   digitalWrite(drainPin, HIGH);
  144.   delay(500);
  145.   lcd.begin(20,4);
  146.   lcd.clear();
  147.   while ((millis() - drainTime) < 105000) {  // Usually empty in 1:30, but give it a little extra time.
  148.     delay(100);
  149.     updateRuntimeDisplay(2);
  150.   }
  151.   digitalWrite(drainPin, LOW);
  152.   delay(100);
  153.   lcd.begin(20,4);
  154.   lcd.clear();
  155. }
  156.  
  157. void tiltRoutine() {
  158.   long doorOpened = millis();
  159.   while (digitalRead(tiltSensor)) {
  160.     if ((millis()-doorOpened) > 120000) {
  161.       lcd.setCursor(0,3);
  162.       lcd.print("                    ");
  163.     }
  164.   }
  165. }
  166.  
  167. void ventDry() {
  168.   digitalWrite(ventPin, HIGH);  
  169.   while (waterTemp() > 115) {
  170.     delay(1000);
  171.     updateRuntimeDisplay(6);
  172.   }
  173.   digitalWrite(ventPin, LOW);
  174. }
  175.  
  176. void preRinse() {
  177.   unsigned long rinseTime = millis();
  178.   digitalWrite(washMotor, HIGH);
  179.   delay(500);
  180.   lcd.begin(20,4);
  181.   lcd.clear();
  182.   while ((millis() - rinseTime) < 600000) { // 60000 is 1 minute, 600000 should be 10.
  183.     updateRuntimeDisplay(4);
  184.     delay(1000);    
  185.   }
  186.   digitalWrite(washMotor, LOW);
  187.   delay(100);
  188.   lcd.begin(20,4);
  189.   lcd.clear();
  190. }
  191.  
  192. void finalRinse() {
  193.   unsigned long rinseTime = millis();
  194.   digitalWrite(heaterPin, HIGH);
  195.   digitalWrite(washMotor, HIGH);
  196.   digitalWrite(soapDispensor, HIGH); // It's not soap on the rinse cycle, it's that "JetDry" stuff coming out.
  197.   delay(500);
  198.   lcd.begin(20,4);
  199.   lcd.clear();
  200.   while ((millis() - rinseTime) < 30000) { // run dispensor motor for 30 seconds
  201.     updateRuntimeDisplay(5);
  202.     delay(500);
  203.   }
  204.   digitalWrite(soapDispensor, LOW);
  205.   while (waterTemp() < 140) {
  206.     delay(1000);
  207.     updateRuntimeDisplay(5);
  208.   }
  209.   digitalWrite(heaterPin, LOW);
  210.   delay(5000);
  211.   digitalWrite(washMotor, LOW);
  212.   delay(100);
  213.   lcd.begin(20,4);
  214.   lcd.clear();
  215. }
  216.  
  217. void washTheDishes() {
  218.   digitalWrite(heaterPin, HIGH);
  219.   digitalWrite(washMotor, HIGH);
  220.   delay(1500);
  221.   lcd.begin(20,4);  // The display seems to wig out when the motor kicks in
  222.   lcd.clear();      // so I added an extra delay and reinitialize it here. Untested.
  223.   while (waterTemp() < 120) {  // Soap doesn't work well below 120f
  224.     updateRuntimeDisplay(3);
  225.     delay(1000);
  226.   }
  227.   unsigned long soapTime = millis();
  228.   digitalWrite(soapDispensor, HIGH);
  229.   while ((millis() - soapTime) < 30000) {
  230.     delay(500);
  231.     updateRuntimeDisplay(3);
  232.   }
  233.   digitalWrite(soapDispensor, LOW);
  234.   while (waterTemp() < 156) {
  235.     delay(1000);
  236.     updateRuntimeDisplay(3);
  237.   }
  238.   digitalWrite(heaterPin, LOW);
  239.   delay(5000);
  240.   digitalWrite(washMotor, LOW);
  241.   delay(100);
  242.   lcd.begin(20,4);
  243.   lcd.clear();
  244. }
  245.  
  246.  
  247. void loop() {
  248.   //  drainItOut();
  249.   lcd.setCursor(0,0);  
  250.   lcd.print(F("Today is: "));
  251.   digitalWrite(0, HIGH);
  252.   digitalWrite(1, HIGH);
  253.   while ((digitalRead(goButton))) { // Display Date/Time until button is pressed
  254.     if (!digitalRead(stopButton)) drainItOut();
  255.     if (digitalRead(tiltSensor)) {
  256.       tiltRoutine();
  257.     }
  258.  
  259.     DateTime now = RTC.now();
  260.     lcd.setCursor(10, 0);
  261.     lcd.print(dayOfWeek[now.dayOfWeek()]);
  262.     lcd.setCursor(0,1);
  263.     lcd.print(currentMonth[(now.month() - 1)]);
  264.     lcd.print(' ');
  265.     lcd.print(now.day(), DEC);
  266.     lcd.print(", ");
  267.     lcd.print(now.year(), DEC);
  268.     lcd.setCursor(0,2);
  269.     if (now.hour() > 12) {
  270.       pm = true;
  271.     }
  272.     else {
  273.       pm = false;
  274.     }
  275.     if (pm) {
  276.       lcd.print((now.hour()-12), DEC);
  277.     }
  278.     else {
  279.       lcd.print(now.hour(), DEC);
  280.     }
  281.     lcd.print(':');
  282.     if (now.minute() < 10) {
  283.       lcd.print('0');
  284.     }
  285.     lcd.print(now.minute(), DEC);
  286.     lcd.print(':');
  287.     if (now.second() < 10) {
  288.       lcd.print('0');
  289.     }
  290.     lcd.print(now.second(), DEC);
  291.     if (pm) {
  292.       lcd.print(F(" PM   "));
  293.     }
  294.     else {
  295.       lcd.print(F(" AM   "));
  296.     }
  297.   }
  298.   // Go button was pressed, run through the cycles
  299.   digitalWrite(goLight, HIGH);
  300.   digitalWrite(stopLight, HIGH);
  301.   lcd.clear();
  302.   cycleStart = millis();
  303.   fillItUp();
  304.   delay(1000);
  305.   washTheDishes();
  306.   delay(1000);
  307.   drainItOut();
  308.   delay(1000);
  309.   fillItUp();
  310.   delay(1000);
  311.   preRinse();
  312.   delay(1000);
  313.   drainItOut();
  314.   delay(1000);
  315.   fillItUp();
  316.   delay(1000);
  317.   finalRinse();
  318.   delay(1000);
  319.   drainItOut();
  320.   delay(1000);
  321.   ventDry();
  322.   lcd.clear();
  323.   lcd.setCursor(0,3);
  324.   lcd.print(F("The dishes are CLEAN!"));
  325.   digitalWrite(goLight, LOW);
  326.   digitalWrite(stopLight, HIGH);
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement