LED and Water level control for Aquarium

First time Arduino user: First time posting.

I am still discovering mechanical/ wiring improvements in my setup but the Controller is not doing what I am asking it to do...

Correction: The Controller is doing Exactly what I am telling it to do.

The goal is to use the Arduino platform to dim my LEDs on,keep them full on, and then fade them off, turn a fan on/off, and use water level inputs to turn an Automatic Top Off (ATO) pump on and off.

The problem is that the ATO, the lights or the fan has yet to operate acording to plan and so far (three days in a row I have yet to see a repeat in the same problem twice)

I cut and pasted two different projects into one and then modified them to my needs...

If you can see any improvements help would be appreciated.


Aaron

1st half Code:

/*
Set RTC. Display on LCD. LED fade Up and Down.  Fan On and Off.  

originally written by Christian, cptbjorn@gmail.com

*/

/*
Water topoff code. Looking for value at inPin every 60 seconds and turn
on/off base on inPin value.
code have 90 seconds timeout to shutoff pump

originally written by Xenia2, Reef Central 

*/

#include "Wire.h" 
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include  // initialize the library with the numbers of the interface pins


/*||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| A U T O   T O P   O F F   |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

unsigned long relay_on_time;
unsigned long loopTime;
unsigned long shutDownTime=0; // 

int atoPin= 2;               // ATO relay connected to digital pin 2
int opticalPin = A3;         // sensor input source connected to digital pin A3
int val = 0;                 // variable to store the read value


/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L E D   D I M M I N G   P A R T  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  F A D E S   I N   A N D   O U T  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



int whiteramptime = 240 ;    // time for white LEDs to dim on and off in minutes
int whitemin = 0 ;           // minimum dimming value of white LEDs, range of 0-255
int whitemax = 255 ;         // maximum dimming value of white LEDs, range of 0-255
int photoperiod = 240 ;      // amount of time array is on at full power in minutes
int ontime = 9 ;             // time of day (hour, 24h clock) to begin photoperiod fade in
int white = 11;              // white LEDs connected to digital pin 11 (pwm)
int fan = 4;                 // defines pin 4 as fan

int whitepercent[11] = { 0, 26, 52, 78, 103, 128, 154, 180, 205, 230, 255 };   // these are the values in 10% increments

// int pwm_one = 5;        // extra pwm pin for future use
// int pwm_one = 6;        // extra pwm pin for future use
// int pwm_one = 3;        // extra pwm pin for future use


LiquidCrystal lcd(7, 8, 9, 10, 13, 12);   // typically 8, 9, 4, 5, 6, 7
                                          // have to change to free up more pwm pins



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  R T C   C L O C K   D S 1 3 0 7  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



byte decToBcd(byte val)    // Convert normal decimal numbers to binary coded decimal
{
  return ( (val/10*16) + (val%10) );
}


byte bcdToDec(byte val)    // Convert binary coded decimal to normal decimal numbers
{
  return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));   // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second = bcdToDec(Wire.receive() & 0x7f);
  *minute = bcdToDec(Wire.receive());
  *hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
  *dayOfWeek = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month = bcdToDec(Wire.receive());
  *year = bcdToDec(Wire.receive());
}



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  O N E S E C O N D |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



void onesecond() //function that runs once per second while program is running
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  lcd.setCursor(0, 0);
  if(hour>0)
  {
    if(hour<=12)
    {
      lcd.print(hour, DEC);
    }
    else
    {
      lcd.print(hour-12, DEC);
    }
  }
  else
  {
    lcd.print("12");
  }
  lcd.print(":");
  if (minute < 10) {
    lcd.print("0");
  }
  lcd.print(minute, DEC);
  lcd.print(":");
  if (second < 10) {
    lcd.print("0");
  }
  lcd.print(second, DEC);
  if(hour<12)
  {
    lcd.print("am");
  }
  else
  {
    lcd.print("pm");
  }
  lcd.print(" ");
  delay(1000);
}



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  F A N   O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

void FanOn()
{
  digitalWrite(fan, HIGH);
  //analogWrite(fan, 255);
    
}

/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  F A N   O F F |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

void FanOff()
{
  digitalWrite(fan, LOW);
  //analogWrite(fan, 0);
    
}

/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  S E T U P  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/


void setup()
{
  relay_on_time = millis();
  loopTime = relay_on_time; 
  pinMode(atoPin, OUTPUT);    // sets the digtial pin 2 as output
  pinMode(opticalPin, INPUT); // sets the digital pin A3 as input
  
  pinMode(fan, OUTPUT);       // set digital pin 4 as a output
  

  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  S E T U P - D I S P L A Y |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  second = 15;
  minute = 19;
  hour = 16;
  dayOfWeek = 0;  // Sunday is 0
  dayOfMonth = 12;
  month = 2;
  year = 12;
  //setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

  analogWrite(white, whitemin);
  lcd.begin(16, 2); // set up the LCD's number of rows and columns: 
  //  lcd.print("12:00 80.6"); // Print a message to the LCD.
  //  lcd.print(char(223));
  
  lcd.setCursor(11, 0);
  lcd.print("ATO:");
  
  lcd.setCursor(8, 1);
  lcd.print("LED:");
  lcd.print(33*whitemin/85);  
}



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/


void loop()
{
  onesecond();
  relay_on_time = millis();
  if (relay_on_time >= (loopTime + 60000)) // check status of input every 60 seconds
  { 
  val = digitalRead(opticalPin);
  if (val == HIGH)
    {
    lcd.setCursor(15, 0);
    lcd.print("+");                       //amber LED on
                                          // <<< changed to LCD "+"
    digitalWrite(atoPin, HIGH);
    if ( 0 == shutDownTime)               
    shutDownTime = relay_on_time + 90000;
    }
  if (val == LOW)
    {
    lcd.setCursor(15, 0);
    lcd.print("-");                       // green LED on
                                          // <<< changed to LCD "-"
    digitalWrite (atoPin, LOW);
    shutDownTime = 0;
    }
  if ( shutDownTime && shutDownTime <= relay_on_time )
    {                                     
    digitalWrite(atoPin, LOW);            
    while(1)                              
      {                                     
                                        // wait for reset
       lcd.print("X");                  // red LED on
                                        // <<< changed to LCD "X" whole screen,
                                        // lights turn off/ fan off, wait for reset
      }                                       
    }                                     
  loopTime = relay_on_time;
  }
  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P - D I M   F U N C T I O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  int daybyminute = ((hour * 60) + minute); //converts time of day to a single value in minutes
      

  int whiterampup;
    if (daybyminute >= (ontime*60)) 
       whiterampup = (((ontime*60) + whiteramptime) - daybyminute);
     else
       whiterampup = whiteramptime;

  int whiterampdown;
    if (((ontime * 60) + photoperiod + whiteramptime) <= daybyminute)
      whiterampdown = (((ontime*60) + photoperiod + 2*whiteramptime) - daybyminute);
    else
      whiterampdown = whiteramptime;



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P - F A D E  I N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/


 if (daybyminute >= (ontime*60))
  { 
    if (daybyminute <= ((ontime*60) + (whiteramptime/10*9))) //if time is in range of fade in, start fading in + (whiteramptime/10*9)      

      // fade white LEDs in from min to max.
      for (int i = 1; i <= 10; i++) // setting i value for 10% increment. Start with 0%
    {
      FanOn();                   //turns fan on
      { 
        analogWrite(white, whitepercent[i]); 
        lcd.setCursor(14, 1);
        lcd.print(i);
        lcd.print(" "); 

        int countdown = ((whiterampup*60)/10); // calculates seconds to next step
        while (countdown>0)
      {
        onesecond(); // updates clock once per second
        countdown--;
      }
      } 
    } 
  }
  

  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P - M A X  V A L U E |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



 if (daybyminute >= ((ontime * 60) + whiteramptime)) 
  { 
    if ( daybyminute < ((ontime * 60) + whiteramptime + photoperiod)) // if time is in range of photoperiod, turn lights on to maximum fade value
    {
      FanOn();                     //turns fan on
      {
      analogWrite(white, 255); 
        lcd.setCursor(14, 1);
        lcd.print(10);
        lcd.print(" ");
      }
    } 
  }



  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P - F A D E  O U T |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



  if (((ontime * 60) + photoperiod + whiteramptime) <= daybyminute)
  { 
    if (((ontime * 60) + photoperiod + whiteramptime) >= daybyminute)
    {
      // fade white LEDs out from max to min in increments of 1 point:
      for (int i = 10; i >= 0; i--) // setting i value for 10% increment. Start with 10%
     {
      FanOn();                       //turns fan on
      { 
        analogWrite(white, whitepercent[i]); 
        lcd.setCursor(14, 1);
        lcd.print(i);
        lcd.print(" ");  

        int countdown = ((whiterampdown*60)/10); // calculates seconds to next step
        while (countdown>0)
        {
          onesecond(); // updates clock once per second
          countdown--;
        }
       } 
      }
    }
  }
  //*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  Night Time |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

if (((ontime * 60) + photoperiod + (2 * whiteramptime)) < daybyminute)
  {         
      
    FanOff();
  }
// if (daybyminute < (ontime*60))
//{
//
//    FansOff();
//  
//}


}  // END LOOP

I looked at your code. (You can attach a file with the code if is too long to include in the message). Clearly you have hacked a lot at it to try and find the errors - lots of functions that do not get called from setup() or loop().

Anyhow, what you are doing now in your loop is

relay_on_time = millis();
if ( some test on difference between relay_on_time and looptime ) ...
:
loopTime = relay_on_time;

The difference is never going to be bigger than 1 ms and most probably 0ms most of the time, so you are never entering the if block.

I do not like the if ( shutDownTime && shutDownTime <= relay_on_time ) - too cryptic, using the true/false idiom of C, and whilst you (correctly?) rely on precedence of operators you reduntantly use brackets elsewhere. Write it more clearly, you can afford the 0.0008ms you may loose by two needless instructions (or thereabouts, if the compiler does not optimize it away) if ( shutDownTime==0 && shutDownTime <= relay_on_time )