Code Version 1.0

From Reef Projects

Jump to: navigation, search

Code is fairly well commented.

Current Features:

  • Controls lights/timer function
  • Kills lights in the event of over heating
  • If lights are killed because of restart (power fail) or overheating, there is a delay before turning on
  • Controls heater/fan
  • Feed mode button
  • ATO
  • Alarm, although not used yet
  • Prints to LCD


#include <OneWire.h>
#include <LCDI2C.h>
//#include <stdio.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

/*
Arduino Reef Controller

Analog Pin 1 = **PH Probe?
Analog Pin 2 = **ORP Probe?
Analog Pin 3 =
Analog Pin 4 = SDA for I2C
Analog Pin 5 = SCL for I2C


Digital Pin 0 = RX
Digital Pin 1 = TX
Digital Pin 2 = Temp Sensor
Digital Pin 3 = ATO Input
Digital Pin 4 = Feed Mode Button
Digital Pin 5 = Relay 1 Heater
Digital Pin 6 = Relay 2 Day Light
Digital Pin 7 = Relay 3 Moon Light
Digital Pin 8 = Relay 4 Fan
Digital Pin 9 = Relay 5 Automatic Top-off
Digital Pin 10 = Relay 6 Power Head #1
Digital Pin 11 = Relay 7 Power Head #2
Digital Pin 12 = Relay 8 Skimmer
Digital Pin 13 = Alarm


*/


LCDI2C lcd = LCDI2C(4,0x4C);  //[# of lines on LCD],[address of serial LCD controller on I2C]

OneWire ds(2);  // Temp Sensor on pin 2
int ato_input = 3;  //ATO input on pin 3
int feed = 4;  //Feed Mode Button

int heater = 5;
int day_light = 6;
int moon_light = 7;
int fan = 8;
int ato = 9;
int ph_1 = 10;
int ph_2 = 11;
int skimmer = 12;
int alarm = 13;

int heater_on_temp = 7950;  //Turn on the heater at this temp         ex 78 degrees = 7800, 78.5 degrees = 7850
int heater_off_temp = 8000; //Turn off heater at this temp

int fan_on_temp = 8150;  //Turn on fan at this temp
int fan_off_temp = 8050; //turn fan off once below this temp

int lights_off_temp = 8300;  //Turn off the lights if the temp rises above this temp

int lights_on_time = 1300;  //Turn day lights on at this time (military time)
int lights_off_time = 2100; //Turn day lights off at this time
int on_minute;  //sets the turn on time.
int wait_time = 30; //how long to wait before turning on lights if they are turned off due to power loss or overheating
int lights_out = -100;  //placeholder  --don't change

int moonl_on_time = 2100;  //Turn on moon lights at this time
int moonl_off_time = 700;  //Turn off moon lights at this time

int feed_time = 5;  //Turn off power heads for this amount of time when feed mode button is pressed.
int pumps_off = -10; //placeholder  --don't change


int c2f(int cel){ //Function to convert celcius to Fahrenheit
      return (cel * 9/5) + 3200;
      }

void setup(void) {
/*  Un-comment to set the time
    RTC.stop();
  RTC.set(DS1307_SEC,01);        //set the seconds
  RTC.set(DS1307_MIN,22);     //set the minutes
  RTC.set(DS1307_HR,13);       //set the hours (military)
  RTC.set(DS1307_DOW,2);       //set the day of the week
  RTC.set(DS1307_DATE,17);       //set the date
  RTC.set(DS1307_MTH,3);        //set the month
  RTC.set(DS1307_YR,9);         //set the year
  RTC.start();
*/
  
  lcd.init(); //initialize LCD
  
  //****** initialize inputs/outputs ************************************/
  pinMode(heater, OUTPUT);  // digital pin for heater as output
  pinMode(day_light, OUTPUT);  // digital pin for day light as output
  pinMode(moon_light, OUTPUT);  // digital pin for moon light as output
  pinMode(fan, OUTPUT);  // digital pin for fan as output
  pinMode(ato, OUTPUT);  // digital pin for auto top off as output
  pinMode(ph_1, OUTPUT);  // digital pin for power head 1 as output
  pinMode(ph_2, OUTPUT);  // digital pin for power head 2 as output
  pinMode(skimmer, OUTPUT);  // digital pin for skimmer as output
  pinMode(ato_input, INPUT);  //digital pin for ATO float switch as input
  pinMode(feed, INPUT);  //digital pin for feed mode button as input
  pinMode(alarm, OUTPUT);  // digital pin for alarm as output
  on_minute = 1;
  delay(2000);
  
  digitalWrite(day_light, LOW);
  
}

int High = 0;
int Low = 10000;

void loop(void){
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract, minute, hour, second, date, month, year, mil_time;
  char buf[12];  //used to convert int to string for displaying on LCD
  
  //Get time from DS1307**********************************************************************************************
  
  hour = RTC.get(DS1307_HR,true);  //This is in military time
  minute = RTC.get(DS1307_MIN,false);
  second = RTC.get(DS1307_SEC,false);
  date = RTC.get(DS1307_DATE,false);
  month = RTC.get(DS1307_MTH,false);
  year = RTC.get(DS1307_YR,false);
  mil_time = (hour * 100) + minute;  //create military time output
  
  //Get temp data from DS18B20 ***************************************************************************************
    if ( !ds.search(addr)) {
      ds.reset_search();
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Tc_100 = c2f(Tc_100);
  
  //Display current temperature*****************************************************************************

  lcd.position(0,0);
  
  Whole = (Tc_100 / 100);  // separate off the whole and fractional portions
  Fract = (Tc_100 % 100);

    lcd.println(itoa(Whole, buf, 10));
    lcd.println(".");
    if (Fract < 10)
  {
     lcd.println("0");
  }
    lcd.println(itoa(Fract, buf, 10));
    lcd.print(0xDF);
    lcd.println("F");
    
    //Display Time******************************************************************************************
    lcd.position(0,10);
    if(hour == 0){
      hour = 12;
    }
    if( hour > 12){
      if(hour - 12 < 10){
        lcd.println(" ");
      }
    lcd.println(itoa(hour - 12, buf, 10));
    }
    else{
      if(hour < 10){
        lcd.println(" ");
      }
      lcd.println(itoa(hour, buf, 10));
    }
    lcd.println(":");
    if(minute < 10){
      lcd.println("0");
    }
    lcd.println(itoa(minute, buf, 10));
    lcd.println(":");
    if(second < 10){
      lcd.println("0");
    }
    lcd.println(itoa(second, buf, 10));
    if(hour > 11){
      lcd.println("PM");
    }
    else{
      lcd.println("AM");
    }
    
    //Display High Temp***********************************************************************************
 if(on_minute == 0){  //used so if bad data is sent for the first reading, it is not saved
  lcd.position(1,0);
  if(Tc_100 > High){
    High = Tc_100;
  }
    Whole = (High / 100);  // separate off the whole and fractional portions
    Fract = (High % 100);
    lcd.println("H= ");
    lcd.println(itoa(Whole, buf, 10));
    lcd.println(".");
    if (Fract < 10)
  {
     lcd.println("0");
  }
  
    lcd.println(itoa(Fract, buf, 10));
    lcd.print(0xDF);
    lcd.println(" ");
 }
    //Display Low Temp***************************************************************************************
 if(on_minute == 0){   //used so if bad data is sent for the first reading, it is not saved
      if(Tc_100 < Low){
    Low = Tc_100;
  }
    Whole = (Low / 100);  // separate off the whole and fractional portions
    Fract = (Low % 100);
    lcd.println("L= ");
    lcd.println(itoa(Whole, buf, 10));
    lcd.println(".");
    if (Fract < 10)
  {
     lcd.println("0");
  }
    lcd.println(itoa(Fract, buf, 10));
    lcd.print(0xDF);
 }
    

  //Relay Controls ***************************************************************************************
  
  //****************Heater  
  if(Tc_100 < heater_on_temp){     // turn heater on if temp is below heater_on_temp
    digitalWrite(heater, HIGH);
  }  
  if(Tc_100 > heater_off_temp){    //turn heater off if temp is above heater_off_temp
   digitalWrite(heater, LOW);
  }
  
  //****************Day Lights
  
   if((lights_off_temp < Tc_100 && digitalRead(day_light) == HIGH) || (digitalRead(day_light) == LOW && on_minute == 1)){
     lights_out = (minute + wait_time) % 60;
   }

   if((lights_out == minute || lights_out == -100) && (lights_off_temp > Tc_100 && lights_on_time <= mil_time  && lights_off_time > mil_time)){
     digitalWrite(day_light, HIGH);
     lights_out = -100;
   }
   else{
     digitalWrite(day_light, LOW);     
   }
  
  //****************Moon Lights
  if(moonl_on_time <= mil_time  || moonl_off_time > mil_time){
    digitalWrite(moon_light, HIGH);
  }
  else{
    digitalWrite(moon_light, LOW);
  }
  
  //****************Fan
   if(Tc_100 > fan_on_temp){     // turn fan on if temp is above fan_on_temp
    digitalWrite(fan, HIGH);
  }  
  if(Tc_100 < fan_off_temp){    //turn fan off if temp is below fan_off_temp
   digitalWrite(fan, LOW);
  }
  
  //****************Auto top off
  
  if(digitalRead(ato_input) == LOW){
    digitalWrite(ato, HIGH);
    delay(3000);               //Turn on ATO pump for 3 seconds
    digitalWrite(ato, LOW);    //Turn off ATO Pump
  }
 
 //****************Power heads and skimmer feed mode

  if(digitalRead(feed) == LOW){
    pumps_off = (minute + feed_time) % 60;
  }
  
  if(pumps_off  == minute || pumps_off == -10){
  digitalWrite(ph_1, HIGH);
  digitalWrite(ph_2, HIGH);
  digitalWrite(skimmer, HIGH);
  pumps_off = -10;
  }
  else{
  digitalWrite(ph_1, LOW);
  digitalWrite(ph_2, LOW);
  digitalWrite(skimmer, LOW);
  }
  
  //Display what relays are on********************************************************
  lcd.position(2,0);
  if(digitalRead(heater) == HIGH){lcd.println("H1 ");}
    else{lcd.println("H0 ");}
  if(digitalRead(day_light) == HIGH){lcd.println("D1 ");}
    else{lcd.println("D0 ");}  
  if(digitalRead(moon_light) == HIGH){lcd.println("M1 ");}
    else{lcd.println("M0 ");}  
  if(digitalRead(fan) == HIGH){lcd.println("F1 ");}
    else{lcd.println("F0 ");}  
  lcd.position(3,0);
  if(digitalRead(ato) == HIGH){lcd.println("A1 ");}
    else{lcd.println("A0 ");}  
  if(digitalRead(ph_1) == HIGH){lcd.println("P1 ");}
    else{lcd.println("P0 ");} 
  if(digitalRead(ph_2) == HIGH){lcd.println("P1 ");}
    else{lcd.println("HP ");}
  if(digitalRead(skimmer) == HIGH){lcd.println("S1");}
    else{lcd.println("S0");}  
    
  
  
  
  
  
  on_minute = 0;  //signals that the program has been run once
} //end loop

Personal tools