/* CHANGELOG 1.4 - Updated temperature equatino to reflect new sensor, LM34. - Increased tempRA array size - Changed some pins numbers 1.5 - Added SD card functionality with serial echo. - Fixed issue with pump loops where pressing the down button wouldn't turn it off (I think it's fixed). - ACKNOWLEDGEMENTS Big thanks to Adafruit for their SD code! TO DO - Decrease scope of some variables to decrease memory usage - Update LCD to have some sort of pump readout. */ #include #include "RTClib.h" #include #include #include #include "SD.h" #include Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); RTC_DS1307 rtc; RunningAverage tempRA(50); RunningAverage lightRA(10); const int tempPin = A0; const int lightPin = A2; const int growPin = 3; const int pumpPin = 9; const int highPump = 210; const int lowPump = 190; const int chipSelect = 10; const boolean ECHO = 1; File logfile; int lightValue; int tempValue; int buttons; int lightState = 0; int x; float tempVolt; float temperature; char lightStatus[3][5]= {"Off ", "On ", "Auto"}; void error(char *str){ Serial.print("Error: "); Serial.println(str); } void setup() { Serial.begin(9600); pinMode(growPin, OUTPUT); pinMode(pumpPin, OUTPUT); Serial.println("Initializing SD card..."); pinMode(chipSelect, OUTPUT); if(!SD.begin(chipSelect)){ Serial.println("SD card not present."); } else{ Serial.println("SD card initialized."); } // Increments file name each time char filename[] = "Logger00.CSV"; for(uint8_t i = 0; i < 100; i++){ filename[6] = i/10 + '0'; filename[7] = i%10 + '0'; if(!SD.exists(filename)){ // only open a new file if it doesn't exist logfile = SD.open(filename, FILE_WRITE); break; } } if(! logfile){ error("Couldn't create file."); } Serial.print("Logging to: "); Serial.println(filename); Wire.begin(); if(!rtc.begin()){ Serial.println("RTC failed."); } logfile.println("Millis, Time, Light, Temp, LEDs, Pump"); if(ECHO){ Serial.println("Millis, Time, Light, Temp, LEDs, Pump"); } digitalWrite(growPin, LOW); digitalWrite(pumpPin, LOW); lcd.begin(16,2); lcd.print("GrOwn v1.5"); delay(3000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Lights:"); lcd.print(lightStatus[lightState]); } void loop() { DateTime now = rtc.now(); lightValue = analogRead(lightPin); lightRA.addValue(lightValue); // Read, 10 ms delay, then read again is necessary because the // Arduino need to switch to tempPin after lightPin, but requires // a few ms to stabilize and take accurate reading. First read // indicates switch to tempPin, then second read is accurate value. tempValue = analogRead(tempPin); delay(10); tempValue = analogRead(tempPin); delay(10); tempVolt = (tempValue/1024.0)*5.0; temperature = (tempVolt*100); tempRA.addValue(temperature); buttons = lcd.readButtons(); if(buttons){ if(buttons & BUTTON_RIGHT){ lcd.setCursor(0,0); lcd.print("Lights:"); lightState += 1; lcd.print(lightStatus[lightState]); } if(buttons & BUTTON_LEFT){ lcd.setCursor(0,0); lcd.print("Lights:"); lightState -= 1; lcd.print(lightStatus[lightState]); } // Perform an oscillating water spray to cover all the area if(buttons & BUTTON_UP){ for(x=lowPump; xlowPump; x--){ buttons = lcd.readButtons(); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); break; } analogWrite(pumpPin, x); Serial.println("In loop 2."); delay(200); } // a delay to allow the pump to stay a certain speed // while still being able to check for BUTTON_DOWN for(int i=0; i<10; i++){ buttons = lcd.readButtons(); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); break; } delay(500); } for(x=lowPump; x<(highPump-18); x++){ buttons = lcd.readButtons(); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); break; } analogWrite(pumpPin, x); Serial.println("In loop 3."); delay(200); } for(int i=0; i<10; i++){ buttons = lcd.readButtons(); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); break; } delay(500); } for(x=(highPump-18); x>lowPump; x--){ buttons = lcd.readButtons(); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); break; } analogWrite(pumpPin, x); Serial.println("In loop 4."); delay(200); } } digitalWrite(pumpPin, LOW); if(buttons & BUTTON_DOWN){ digitalWrite(pumpPin, LOW); Serial.println("Pump turned off."); } } // if the lights are in "Auto" mode leave it up to // the light sensor to turn on the lights boolean lightsOnOff; if(lightState == 0){ digitalWrite(growPin, LOW); lightsOnOff = 0; } if(lightState == 1){ digitalWrite(growPin, HIGH); lightsOnOff = 1; } if(lightState == 2){ // only turn lights on between 8:00 am and 6:00 pm if(now.hour() > 8 && now.hour() < 18){ if(lightRA.getAverage() >= 750){ digitalWrite(growPin, LOW); //Serial.println("Lights off."); lightsOnOff = 0; } else if(lightRA.getAverage() > 350 && lightRA.getAverage() < 750){ digitalWrite(growPin, LOW); lightsOnOff = 0; } else if(lightRA.getAverage() <= 350){ digitalWrite(growPin, HIGH); Serial.println("Lights on."); lightsOnOff = 1; } } else{ digitalWrite(growPin, LOW); lightsOnOff = 0; } } lcd.setCursor(0,1); lcd.print("Temp :"); lcd.print(tempRA.getAverage(), 1); // log data to SD card // millis since starting uint32_t m = millis(); logfile.print(m); logfile.print(", "); if(ECHO){ Serial.print(m); Serial.print(", "); } //logfile.print(now.get()); //logfile.print(", "); logfile.print(now.year(), DEC); logfile.print("/"); logfile.print(now.month(), DEC); logfile.print("/"); logfile.print(now.day(), DEC); logfile.print(" "); logfile.print(now.hour(), DEC); logfile.print(":"); logfile.print(now.minute(), DEC); logfile.print(":"); logfile.print(now.second(), DEC); logfile.print(", "); logfile.print(lightValue); logfile.print(", "); logfile.print(temperature); logfile.print(", "); logfile.print(lightsOnOff); logfile.println(", "); if(ECHO){ //Serial.print(now.get()); //Serial.print(", "); Serial.print(now.year(), DEC); Serial.print("/"); Serial.print(now.month(), DEC); Serial.print("/"); Serial.print(now.day(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(":"); Serial.print(now.minute(), DEC); Serial.print(":"); Serial.print(now.second(), DEC); Serial.print(", "); Serial.print(lightValue); Serial.print(", "); Serial.print(temperature); Serial.print(", "); Serial.print(lightsOnOff); Serial.println(", "); } logfile.flush(); //Serial.print("Temperature: "); Serial.println(temperature); //Serial.print("Light value: "); Serial.println(lightRA.getAverage()); delay(1000); }