Tuesday, July 30, 2013

Lychee Shishi Version 1 - Code



As promised here is the code for my ShiShi project(working title).  I know that it's not the best.  I learned so much while creating this.  One day I'll sit down and rewrite this whole thing.  Code after the break..



/*
 *Lychee Shishi.pde
 * This if code is intended to control the growing area for an indoor growing area
 *
 *Working Lights
 *RTC Time retreival
 *Shenzhen Sun Rise/Set Calculations
 *Temp sensor reading
 *
 * A Processing example sketch to automatically send the messages is inclided in the download
 *
 */
#include
#include  #include
#include #include
#include  // a basic DS1307 library that returns time as a time_t#include "Timer.h"
#include "DHT.h"
#include
#include
#include

Timer t;

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)
// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()



#define DHTPIN 6     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Location constants  - Shenzhen, China
const float LATITUDE = 22.608103,
    LONGITUDE = 113.939965;
const int TIMEZONE = 8;

//SD Card stuff - for maker shield
const int chipSelect = 10;
File logfile;
void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  while(1);
}
// Time variables
TimeLord LightTimeLord;
byte   lightOnHr, lightOnMin, lightOffHr, lightOffMin;

//Pins that are used to switch on components
int WATER_PUMP_PIN = 2;
int LIGHT_RELAY_PIN = 3;
int HUM_PIN = 4;
int led4 = 5;
//LED Indocator Pins
//int waterLED = 6;
//int lightLED = 7;
//int humLED = 8;
//int led8 = 9;
#define I2C_ADDR    0x3F  // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


void setup()  {
  Serial.begin(9600);

  lcd.begin (16,2);

// Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                   // go home


// initialize the digital pins as an output.
  pinMode(WATER_PUMP_PIN, OUTPUT);
  pinMode(LIGHT_RELAY_PIN, OUTPUT);
  pinMode(HUM_PIN, OUTPUT);
  pinMode(led4, OUTPUT);



  // initialize the digital pins as an output.
//  pinMode(waterLED, OUTPUT);
//  pinMode(lightLED, OUTPUT);
//  pinMode(humLED, OUTPUT);
//  pinMode(led8, OUTPUT);

 //Turns off the all Non-Light Pins on start up
digitalWrite(HUM_PIN, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(WATER_PUMP_PIN, HIGH);

// Gets the time from the RTC
  setSyncProvider(RTC.get);
  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC");
    else
     Serial.println("RTC has set the system time");  
 
// TimeLord Stuff  - Do not Touch
  LightTimeLord.TimeZone(TIMEZONE * 60);
  LightTimeLord.Position(LATITUDE, LONGITUDE);

//This is the call that sets the sunrise and sunset times
  calculateAlarmTimes();


//water Pump stuff
Alarm.timerRepeat(10800, pumpOn); //Cycle the water pump once every 3 hours
//Alarms for sunrise & set  w/examples
Alarm.alarmRepeat(lightOnHr,lightOnMin,0,lightOn);  // Sunrise
Alarm.alarmRepeat(lightOffHr,lightOffMin,0,lightOff); // Sunset
Alarm.timerRepeat(12,0,0,calculateAlarmTimes); // Get new rise and set after midnight
//Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds
//Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds


dht.begin();
/*
 // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  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;  // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);
  // connect to RTC
  Wire.begin();
 if(timeStatus()!= timeSet){
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }

  logfile.println("millis,stamp,datetime,light,temp,vcc");
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,light,temp,vcc");
#endif //ECHO_TO_SERIAL
*/


}

void loop(){
  Alarm.delay(1000);

float Wcd = 180000 - millis()/1000;
int LWcd = Wcd/1000.;
lcd.setCursor ( 6, 1 );
lcd.print(LWcd);

  t.update();
 
//displays clock through serial monitor // when not debugging
  digitalClockDisplay();

 /*
//Alarms for sunrise & set  w/examples
Alarm.alarmRepeat(lightOnHr,lightOnMin,0,lightOn);  // Sunrise
Alarm.alarmRepeat(lightOffHr,lightOffMin,0,lightOff); // Sunset
Alarm.timerRepeat(12,0,0,calculateAlarmTimes); // Get new rise and set after midnight
//Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds
//Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds
*/
}

/**
 * Calculates alarm times used for scheduling and init state.
 */
void calculateAlarmTimes(){
  int nowHour = hour(),
   nowMinute = minute(),
   nowDay = day(),
   nowMonth = month(),
   nowYear = year();

  byte timeLordSunRise[]  = {0, 0, 0, nowDay, nowMonth, nowYear};
  byte timeLordSunSet[]  = {0, 0, 0, nowDay, nowMonth, nowYear};
  LightTimeLord.SunRise(timeLordSunRise);
  LightTimeLord.SunSet(timeLordSunSet);


    Serial.print("sunrise: ");
    Serial.print(timeLordSunRise[2]);
    Serial.print(":");
    Serial.println(timeLordSunRise[1]);
    Serial.print("sunset: ");
    Serial.print(timeLordSunSet[2]);
    Serial.print(":");
    Serial.println(timeLordSunSet[1]);


  lightOnHr = timeLordSunRise[2];
  lightOnMin = timeLordSunRise[1];
  lightOffHr = timeLordSunSet[2];
  lightOffMin = timeLordSunSet[1];

   // If the light is supposed to be on turn it on
  if(hour() < lightOffHr && hour() >=lightOnHr)
  {
  Serial.println("RECOVER");
  lightOn();
  }
  else
  {
  lightOff();
  Serial.println("Light Checked");
  }
  }

// light methods
void lightOn(){
  digitalWrite(LIGHT_RELAY_PIN, LOW);
 // digitalWrite(lightLED, HIGH);
  Serial.println("Light should be on");
  lcd.setCursor ( 0, 1 );
  lcd.print("L+");
}
void lightOff(){
  digitalWrite(LIGHT_RELAY_PIN, HIGH);
//  digitalWrite(lightLED, LOW);
  Serial.println("Light should be off");
  lcd.setCursor ( 0, 1 );
  lcd.print("L-");
}
// end light methods

//void Repeats(){
//  Serial.println("15 second timer");
//  digitalWrite(WATER_PUMP_PIN, LOW);
//  digitalWrite(LIGHT_RELAY_PIN, LOW);
//  digitalWrite(HUM_PIN, LOW);
// digitalWrite(led4, LOW);
//}
//Water Pump Loop stuff
void pumpOn(){
  Serial.println("Pump On");
  digitalWrite(WATER_PUMP_PIN, LOW);
 // lcd.setCursor ( 6, 1 );
 // lcd.print("W+");
  t.after(600000, pumpOff);
}
void pumpOff(){
  Serial.println("Pump Off");
  //lcd.setCursor ( 6, 1 );
 // lcd.print("W-");
  digitalWrite(WATER_PUMP_PIN, HIGH);
}
void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();

  // digital clock display of the time on LCD
  lcd.setCursor ( 0, 0 );
  lcd.print(hour() );
  lcd.print(":");
  lcd.print(minute());
  lcd.print(" ");
    }
void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
    if(digits < 10)
    Serial.print('0');
      Serial.print(digits);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float tf = ((t*9)/5) + 32;
  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
     Serial.println("       ");
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
 
    lcd.setCursor ( 10, 1 );
    lcd.print(h);
    lcd.print("%");
    lcd.setCursor ( 10, 0 );
    lcd.print(tf);
    lcd.print("F");
    }


   if (h < 70)    //If humidity is below 70%
    {
      digitalWrite(HUM_PIN, LOW);   //Run the fan
    //  digitalWrite(humLED, HIGH);
      Serial.println("Humidifing");
      lcd.setCursor ( 3, 1 );
      lcd.print("H+");
    }
    else if (h > 71) // add a little hysteresis to prevent rapid cycling due to noise
    {
       digitalWrite(HUM_PIN, HIGH);  //Stop fan when humidity 71% or higher
   //    digitalWrite(humLED, LOW);
       Serial.println("Humififier Off");
       lcd.setCursor ( 3, 1 );
      lcd.print("H-");
    }


}







No comments: