Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This sketch written for the Arduino Uno/Duemelinova
- // Licensed Creative Commons
- // Written by Brian Gosney (UnaClocker) May 2011
- // This code runs my dishwasher via some relays. It monitors the NTC thermistor water temp sensor
- // More details will be at http://www.neonsquirt.com/dishwasher.html
- // This is code revision 3.4 - Now compiles on Arduino 1.0, most strings moved to F("Flash, rather than SRAM")
- #include <math.h> // Needed for the logarithmic NTC thermistor temp sensor
- #include <LiquidCrystal.h> // For the 4x20 LCD status screen
- #include <Wire.h> // Used for the I2C RTC chip
- #include "Chronodot.h" // Used to fetch and decode the RTC data
- Chronodot RTC; // Create the RTC object
- LiquidCrystal lcd(8,9,10,11,12,13); // These are the pins used for the parallel LCD
- char* dayOfWeek[]={
- "Sunday ", "Monday", "Tuesday", "Wednesday", "Thursday ", "Friday ", "Saturday"};
- // using pointers to point at an array of arrays of characters.
- char* currentMonth[]={
- "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
- boolean pm=false; // AM or PM, for the clock
- unsigned long cycleStart; // Used for keeping track of how long it's been washing.
- double tempArray[25]; // Array of temperatures, to average readings and reduce jitter
- byte arrayIndex=0; // Used to count temperature samples
- #define ventPin 7
- #define soapDispensor 6
- #define waterInlet 5
- #define drainPin 4
- #define washMotor 3
- #define heaterPin 2
- #define goButton A1
- #define tempSensor A2
- #define goLight 0
- #define stopLight 1
- #define stopButton A3
- #define tiltSensor A0
- //void dLay(integer howLong) {
- //}
- double waterTemp() { // This subroutine came from the Arduino Playground
- if (arrayIndex> 23) {
- arrayIndex=0; // 25 samples, 0 to 24, when it hits 24, reset to 0
- }
- else {
- arrayIndex++; // Increment array index counter
- }
- double Temp; // The Thermistor2 "Simple Code"
- int RawADC = analogRead(tempSensor);
- Temp = log(((10240000/RawADC) - 10000)); // I believe the - 10000 is because it's a 10k thermistor?
- Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
- Temp = Temp - 273.15; // Convert Kelvin to Celcius
- Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
- tempArray[arrayIndex]=Temp; // replace the reading at this index with the current reading
- Temp=0; // reset the temporary variable to 0
- for (int i=0; i<24; i++) {
- Temp += tempArray[i]; // add all of the elements in the array together
- }
- return (Temp / 25); // return the average temp from the array
- }
- void setup () {
- for (int i=0; i<25; i++) tempArray[i]=70; // Fill the temperature array with sane numbers.
- Wire.begin(); // Used for the RTC
- RTC.begin(); // Likewise
- lcd.begin(20,4); // 4x20 LCD Panel
- pinMode(tempSensor, INPUT);
- pinMode(ventPin, OUTPUT);
- pinMode(soapDispensor, OUTPUT);
- pinMode(waterInlet, OUTPUT);
- pinMode(drainPin, OUTPUT);
- pinMode(washMotor, OUTPUT);
- pinMode(heaterPin, OUTPUT);
- pinMode(goButton, INPUT);
- digitalWrite(goButton, HIGH); // activate internal pull-up resistor for this input pin
- pinMode(stopButton, INPUT);
- pinMode(tiltSensor, INPUT);
- digitalWrite(stopButton, HIGH);
- digitalWrite(tiltSensor, HIGH);
- pinMode(0, OUTPUT);
- pinMode(1, OUTPUT);
- }
- void updateRuntimeDisplay(byte currentMode) { // I'm not happy with this routine. Needs work.
- unsigned long elapsedSeconds = ((millis() - cycleStart) / 1000); // Come up with the number of seconds elapsed
- unsigned long elapsedMinutes = (elapsedSeconds / 60);
- unsigned long elapsedHours = (elapsedMinutes / 60);
- lcd.setCursor(0,0);
- lcd.print(F("Cycle Time: "));
- if (elapsedHours > 0) { // Don't display the hours elapsed if less than an hour has elapsed.
- lcd.print(elapsedHours);
- lcd.print(':');
- if (elapsedHours == 1) elapsedMinutes -= 60;
- if (elapsedHours == 2) elapsedMinutes -= 120;
- }
- if (elapsedMinutes < 10) { // Only displays a single digit, so needs an extra zero.
- lcd.print('0');
- }
- lcd.print(elapsedMinutes);
- lcd.setCursor(0,1);
- lcd.print(F("Water Temp: "));
- lcd.print(int(waterTemp()));
- lcd.print('F');
- lcd.setCursor(0,3);
- switch (currentMode) {
- case 1:
- lcd.print(F("Filling "));
- break;
- case 2:
- lcd.print(F("Draining "));
- break;
- case 3:
- lcd.print(F("Washing the dishes "));
- break;
- case 4:
- lcd.print(F("10 minute Pre-Rinse "));
- break;
- case 5:
- lcd.print(F("Final Rinse "));
- break;
- case 6:
- lcd.print(F("Drying Clean Dishes "));
- break;
- }
- }
- void fillItUp() {
- unsigned long fillTime = millis();
- digitalWrite(waterInlet, HIGH);
- while ((millis() - fillTime) < 105000) { // 1 minute, 45 seconds to fill the dishwasher
- delay(100);
- updateRuntimeDisplay(1);
- }
- digitalWrite(waterInlet, LOW);
- delay(100);
- lcd.begin(20,4);
- lcd.clear();
- }
- void drainItOut() {
- unsigned long drainTime = millis();
- digitalWrite(drainPin, HIGH);
- delay(500);
- lcd.begin(20,4);
- lcd.clear();
- while ((millis() - drainTime) < 105000) { // Usually empty in 1:30, but give it a little extra time.
- delay(100);
- updateRuntimeDisplay(2);
- }
- digitalWrite(drainPin, LOW);
- delay(100);
- lcd.begin(20,4);
- lcd.clear();
- }
- void tiltRoutine() {
- long doorOpened = millis();
- while (digitalRead(tiltSensor)) {
- if ((millis()-doorOpened) > 120000) {
- lcd.setCursor(0,3);
- lcd.print(" ");
- }
- }
- }
- void ventDry() {
- digitalWrite(ventPin, HIGH);
- while (waterTemp() > 115) {
- delay(1000);
- updateRuntimeDisplay(6);
- }
- digitalWrite(ventPin, LOW);
- }
- void preRinse() {
- unsigned long rinseTime = millis();
- digitalWrite(washMotor, HIGH);
- delay(500);
- lcd.begin(20,4);
- lcd.clear();
- while ((millis() - rinseTime) < 600000) { // 60000 is 1 minute, 600000 should be 10.
- updateRuntimeDisplay(4);
- delay(1000);
- }
- digitalWrite(washMotor, LOW);
- delay(100);
- lcd.begin(20,4);
- lcd.clear();
- }
- void finalRinse() {
- unsigned long rinseTime = millis();
- digitalWrite(heaterPin, HIGH);
- digitalWrite(washMotor, HIGH);
- digitalWrite(soapDispensor, HIGH); // It's not soap on the rinse cycle, it's that "JetDry" stuff coming out.
- delay(500);
- lcd.begin(20,4);
- lcd.clear();
- while ((millis() - rinseTime) < 30000) { // run dispensor motor for 30 seconds
- updateRuntimeDisplay(5);
- delay(500);
- }
- digitalWrite(soapDispensor, LOW);
- while (waterTemp() < 140) {
- delay(1000);
- updateRuntimeDisplay(5);
- }
- digitalWrite(heaterPin, LOW);
- delay(5000);
- digitalWrite(washMotor, LOW);
- delay(100);
- lcd.begin(20,4);
- lcd.clear();
- }
- void washTheDishes() {
- digitalWrite(heaterPin, HIGH);
- digitalWrite(washMotor, HIGH);
- delay(1500);
- lcd.begin(20,4); // The display seems to wig out when the motor kicks in
- lcd.clear(); // so I added an extra delay and reinitialize it here. Untested.
- while (waterTemp() < 120) { // Soap doesn't work well below 120f
- updateRuntimeDisplay(3);
- delay(1000);
- }
- unsigned long soapTime = millis();
- digitalWrite(soapDispensor, HIGH);
- while ((millis() - soapTime) < 30000) {
- delay(500);
- updateRuntimeDisplay(3);
- }
- digitalWrite(soapDispensor, LOW);
- while (waterTemp() < 156) {
- delay(1000);
- updateRuntimeDisplay(3);
- }
- digitalWrite(heaterPin, LOW);
- delay(5000);
- digitalWrite(washMotor, LOW);
- delay(100);
- lcd.begin(20,4);
- lcd.clear();
- }
- void loop() {
- // drainItOut();
- lcd.setCursor(0,0);
- lcd.print(F("Today is: "));
- digitalWrite(0, HIGH);
- digitalWrite(1, HIGH);
- while ((digitalRead(goButton))) { // Display Date/Time until button is pressed
- if (!digitalRead(stopButton)) drainItOut();
- if (digitalRead(tiltSensor)) {
- tiltRoutine();
- }
- DateTime now = RTC.now();
- lcd.setCursor(10, 0);
- lcd.print(dayOfWeek[now.dayOfWeek()]);
- lcd.setCursor(0,1);
- lcd.print(currentMonth[(now.month() - 1)]);
- lcd.print(' ');
- lcd.print(now.day(), DEC);
- lcd.print(", ");
- lcd.print(now.year(), DEC);
- lcd.setCursor(0,2);
- if (now.hour() > 12) {
- pm = true;
- }
- else {
- pm = false;
- }
- if (pm) {
- lcd.print((now.hour()-12), DEC);
- }
- else {
- lcd.print(now.hour(), DEC);
- }
- lcd.print(':');
- if (now.minute() < 10) {
- lcd.print('0');
- }
- lcd.print(now.minute(), DEC);
- lcd.print(':');
- if (now.second() < 10) {
- lcd.print('0');
- }
- lcd.print(now.second(), DEC);
- if (pm) {
- lcd.print(F(" PM "));
- }
- else {
- lcd.print(F(" AM "));
- }
- }
- // Go button was pressed, run through the cycles
- digitalWrite(goLight, HIGH);
- digitalWrite(stopLight, HIGH);
- lcd.clear();
- cycleStart = millis();
- fillItUp();
- delay(1000);
- washTheDishes();
- delay(1000);
- drainItOut();
- delay(1000);
- fillItUp();
- delay(1000);
- preRinse();
- delay(1000);
- drainItOut();
- delay(1000);
- fillItUp();
- delay(1000);
- finalRinse();
- delay(1000);
- drainItOut();
- delay(1000);
- ventDry();
- lcd.clear();
- lcd.setCursor(0,3);
- lcd.print(F("The dishes are CLEAN!"));
- digitalWrite(goLight, LOW);
- digitalWrite(stopLight, HIGH);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement