• ******* To read about the changes to the marketplace click here

DIY Arduino Controller

johntan

Non-member
I don't know if anyone is interested, but I am wrapping up a DIY controller this week - I used a lot of the open source code from reefcentral, and the arduino forums to pull this off.

It took me awhile to gather all of this together, and reefcentral only addresses dimming LEDs - which I plan to do when mine arrive.

Parts/pricing

Arduino Uno ~$30
LCD 20x4 ~$12
DS18B20 temp sensor ~Free from Maxim as a sample set
2 x Solid State Relays (5v~24v DC input to 120v~240V output) ~$20 each
Breadboard ~$5
set of 75 breadboard wires ~$5
4.7k ohm resistors ~$1.50

This is pretty much it for a controller for tank temperature, and a nice display.
The LCD is wired straight from the tutorial found here: http://www.ladyada.net/learn/lcd/charlcd.html

Attached here is the wiring diagram for just sensing temperature, and responding with either fans or a heater - the resistor shown on the breadboard is a 4.7k
View attachment arduinolayout.pdf

To make this submersible, I took an ethernet cord and chopped off the ends. Soldered three of the wires to the DS18B20, and covered that end in aquarium silicon. The other end goes right into the project box and is soldered to three jumper wires. Same layout shown, just extennnnnded.

Now the software! Again this is not originally mine, lifted this from the RC project (http://www.reefcentral.com/forums/showthread.php?t=1987110) however they did not address temperature :( So I re-wrote the 'fan' and 'fuge' parts, I am keeping the dimming feature as my rapidLED shipment is coming tomorrow :D


PHP:
/*

REEFCONTROLLER


*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h" 
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins
#define ONE_WIRE_BUS 6 //Define the pin of the DS18B20


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

/* NOTE USE 'BLUE' Setting until two drivers ordered*/


const int ledPin1 =  A2;          // pin number for relay 1 was digital pin 2
const int ledPin2 =  A3;          // pin number for relay 2 was digital pin 8



int ledState1 = LOW;             
int ledState2 = LOW; 
long previousMillis1 = 0;        
long previousMillis2 = 0;
long interval1 = 30000;          // interval at which to blink (milliseconds) for RELAY1
long interval2 = 50000;		 // interval at which to blink (milliseconds) for RELAY2


/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 blueramptime = 60 ;    // time for blue LEDs to dim on and off in minutes
int whiteramptime = 120 ;  // time for white LEDs to dim on and off in minutes
int bluemin = 0 ;          // minimmum dimming value of blue LEDs, range of 0-255
int bluemax = 255 ;        // maximum dimming value of blue LEDs, range of 0-255
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 = 360 ;    // amount of time array is on at full power in minutes
int ontime = 10 ;          // time of day (hour, 24h clock) to begin photoperiod fade in
int blue = 10;              // blue LEDs connected to digital pin 3 (pwm)
int white = 11;            // white LEDs connected to digital pin 11 (pwm)
int fan = A0;            // Fan power relay connected to analog pin 0
int fuge = A1;            // fuge light power relay connected to analog pin 1
//int moon = 3;            // moon light connected to digital pin 3

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

int fuge_on = 80;  //Turn on fan at this temp
int fuge_off = 81; //turn fan off once below this temp



//int bluepercent[11] = { 0, 1, 2, 5, 8 ,12, 18, 27, 44, 80, 255 };   // this line is needed if you are using meanwell ELN60-48D
//int whitepercent[11] = { 0, 1, 2, 5, 8 ,12, 18, 27, 44, 80, 255 };   // these are the values in 10% increments

int bluepercent[11] = { 0, 26, 52, 78, 103, 128, 154, 180, 205, 230, 255 };   // this line is needed if you are using meanwell ELN60-48P
int whitepercent[11] = { 0, 26, 52, 78, 103, 128, 154, 180, 205, 230, 255 };   // these are the values in 10% increments

//int pwm_one = 9;        // extra pwm pin for future use

LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //My diy circuit layout use this if you copy my board
//LiquidCrystal lcd(11, 12, 13, 14, 15, 16); //Teensy++ 2.0 alternate to Arduino boards
//LiquidCrystal lcd(12, 13, 4, 5, 6, 7);   // typically 8, 9, 4, 5, 6, 7
                                         // have to change to free up more pwm pins
//  Set up the custom fish icon


// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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, 1);
  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 S   O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
void FansOn()
{
  digitalWrite(fan, HIGH);  
  lcd.setCursor(17, 3);
  lcd.print("On ");
  //analogWrite(fan, 255);
    
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  F A N S   O F F |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
void FansOff()
{
  digitalWrite(fan, LOW);
  lcd.setCursor(17, 3);
  lcd.print("Off");
    //analogWrite(fan, 0);
    
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  F U G E  L I G H T  O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
void FugeOn()
{
  digitalWrite(fuge, HIGH);  
  lcd.setCursor(7, 3);
  lcd.print("On ");
  
    
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  F U G E  L I G H T   O F F |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/
void FugeOff()
{
  digitalWrite(fuge, LOW);
  lcd.setCursor(7, 3);
  lcd.print("Off");
    
    
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  M O O N  L I G H T  O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void MoonOn()
{
  digitalWrite(moon, HIGH);  
  lcd.setCursor(8, 1);
  lcd.write(4);
  lcd.write(5);

code too long, will post rest below
 
Last edited:
PHP:
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  M O O N  L I G H T   O F F |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void MoonOff()
{
  digitalWrite(moon, LOW);
  lcd.setCursor(8, 1);
  lcd.write(6);
  lcd.write(7);
   
    
}

/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  R E L A Y 1 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/




void relay1()  //FUNCTION TO TURN ON AND OFF RELAY 1.
{ 
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis1 > interval1) 
  { 
    previousMillis1 = currentMillis;   
    if (ledState1 == LOW)
      ledState1 = HIGH;
    else
      ledState1 = LOW;
    digitalWrite(ledPin1, ledState1);
  }
}

/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  R E L A Y 2 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/




void relay2()
{
  unsigned long currentMillis2 = millis();

  if(currentMillis2 - previousMillis2 > interval2) 
  {
    previousMillis2 = currentMillis2;   
    if (ledState2 == LOW)
      ledState2 = HIGH;
    else
      ledState2 = LOW;
    digitalWrite(ledPin2, ledState2);
  }
}




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


void setup() {
  pinMode(ledPin1, OUTPUT);    // set the digital pin as output:
  pinMode(ledPin2, OUTPUT);    // set the digital pin as output:
  pinMode(fan, OUTPUT);      // Set analog pin 0 as a output
  pinMode(fuge, OUTPUT);      // Set analog pin 1 as a output
  //pinMode(moon, OUTPUT);      // Set analog pin 3 as a output
  sensors.begin();             // Start up the DS18B20 Temp library

  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 = 00;
  minute = 15;
  hour = 23;
  dayOfWeek = 25;  // Sunday is 0
  dayOfMonth = 4;
  month = 4;
  year = 11;
  
  //Use the next line for setting the clock
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

  analogWrite(blue, bluemin);
  analogWrite(white, whitemin);
//  lcd.createChar(0, newChar);
  //lcd.createChar(1, newChar1);
  //lcd.createChar(2, newChar2);
  //lcd.createChar(3, newChar3);
  //lcd.createChar(4, newChar4);
  //lcd.createChar(5, newChar5);
  //lcd.createChar(6, newChar6);
  //lcd.createChar(7, newChar7);
  lcd.begin(20, 4); // set up the LCD's number of rows and columns: 
  lcd.setCursor(0, 0);
  //lcd.write(0);
  //lcd.write(1);
  lcd.setCursor(3, 0);// set the cursor to column 0, line 0
  lcd.print("Test Controller");
  lcd.setCursor(18, 0);
  //lcd.write(3);
  //lcd.write(2);
  //lcd.setCursor(7, 1);
  //lcd.print("M:");
  lcd.setCursor(11, 1);
  lcd.print("B:");
  lcd.print(33*bluemin/85);
  lcd.setCursor(16, 1);
  lcd.print("W:");
  lcd.print(33*whitemin/85);
  lcd.setCursor(0, 3);
  lcd.print("Heater: ");
  lcd.setCursor(11, 3);
  lcd.print("Fans: ");
 
}




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




void loop()
{
  onesecond();
  relay2();
  relay1();





  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 bluerampup;
     if (daybyminute >= (ontime*60)) 
       bluerampup = (((ontime*60) + blueramptime) - daybyminute);
     else
       bluerampup = blueramptime;
       
  int whiterampup;
    if (daybyminute >= (ontime*60 + blueramptime)) 
       whiterampup = (((ontime*60) + blueramptime + whiteramptime) - daybyminute);
     else
       whiterampup = whiteramptime;

  int whiterampdown;
    if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
      whiterampdown = (((ontime*60) + photoperiod + blueramptime + 2*whiteramptime) - daybyminute);
    else
      whiterampdown = whiteramptime;
      
  int bluerampdown;
    if (((ontime * 60) + photoperiod + blueramptime + 2*whiteramptime) <= daybyminute)
      bluerampdown = (((ontime*60) + photoperiod + 2*blueramptime + 2*whiteramptime) - daybyminute);
    else
      bluerampdown = blueramptime;
 
PHP:
  /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  L O O P - F A D E  I N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/


 if (daybyminute >= (ontime*60))
  { 
    if (daybyminute <= ((ontime*60) + blueramptime + (whiteramptime/10*9))) //if time is in range of fade in, start fading in + (whiteramptime/10*9)
    {
      // Turn the fans on.
      FansOn();
      // Turn the fuge off.
      //FugeOff();
      // Turn the moon lights off.
     // MoonOff();
      // fade blue LEDs in from min to max.
      
      for (int i = 1; i <= 10; i++) // setting ib value for 10% increment. Start with 0% 
      { 
        analogWrite(blue, bluepercent[i]); 
        lcd.setCursor(13, 1);
        lcd.print(i);
        lcd.print(" "); 
      
        int countdown = ((bluerampup*60)/10); // calculates seconds to next step
        while (countdown>0)
          {
          onesecond(); // updates clock once per second
          countdown--;
          relay2();
          relay1();
        }
      }      

      // fade white LEDs in from min to max.
      for (int i = 1; i <= 10; i++) // setting i value for 10% increment. Start with 0%
      { 
        analogWrite(white, whitepercent[i]); 
        lcd.setCursor(18, 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--;
          relay2();
          relay1();
        }
      } 
    }
  }


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



 if (daybyminute >= ((ontime * 60) + blueramptime + whiteramptime)) 
  { 
    if ( daybyminute < ((ontime * 60) + blueramptime + whiteramptime + photoperiod)) // if time is in range of photoperiod, turn lights on to maximum fade value
    {
      // Turn the fans on.
      FansOn();
      // Turn the fuge off.
     // FugeOff();
      // Turn the moon lights off.
     // MoonOff();
      
      analogWrite(blue, 255);
        lcd.setCursor(13, 1);
        lcd.print(10);
        lcd.print(" ");
      analogWrite(white, 255); 
        lcd.setCursor(18, 1);
        lcd.print(10);
        lcd.print(" "); 
      
    } 
  }



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



  if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
  { 
    if (((ontime * 60) + photoperiod + whiteramptime + 2*blueramptime + (blueramptime/10*9)) >= daybyminute)
    {
      // Turn the fans on.
      FansOn();
      // Turn the fuge off.
      //FugeOff();
      // Turn the moon lights off.
      //MoonOff();
      
      // 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%
      { 
        analogWrite(blue, 255);
        lcd.setCursor(13, 1);
        lcd.print(10);
        lcd.print(" "); 
        
        analogWrite(white, whitepercent[i]); 
        lcd.setCursor(18, 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--;
          relay2();
          relay1();
        }

      } 

      // fade blue 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%
      { 
        analogWrite(blue, bluepercent[i]);
        lcd.setCursor(13, 1);
        lcd.print(i);
        lcd.print(" "); 

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

// DS18B20 display
sensors.requestTemperatures(); // Send the command to get temperatures
    // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(13, 2);

  //lcd.print("Led Temp:");
  lcd.print(sensors.getTempFByIndex(1)); 
  lcd.print((char)223);
  lcd.print("F");
  
  if (sensors.getTempFByIndex(1) > fan_on_temp) return FansOn(), FugeOff();
    if (sensors.getTempFByIndex(1) < fan_off_temp) return FansOff(), FugeOn();
    


 
  //lcd.setCursor(2, 2);
  ////lcd.print("Tank Temp: ");
  //lcd.print(sensors.getTempFByIndex(0)); 
  //lcd.print((char)223);
  //lcd.print("F");
  

   
//  lcd.print(sensors.getTempCByIndex(0));
//  lcd.print((char)223); 
//  lcd.print("C");
  
  //delay(500);
  //*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  Night Time |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/

if (((ontime * 60) + photoperiod + (2 * blueramptime) + (2 * whiteramptime)) < daybyminute)
  {         
      
    //FansOff();
   // FugeOn();
    //MoonOn();
  }
  
  
  
  
  
  
// if (daybyminute < (ontime*60))
//{
//
  
//  
//}
  
}  // END LOOP

I have commented out with // or /* things I didn't need like the settings for model "D" meanwell drivers, moon lighting...

My question to anyone who may be in the know, I have pH probes... how do I get the arduino to play nice with them? haha!
 
Some sweet sweet proof:

Screen shot 2011-07-14 at 9.20.38 AM.png
 
Forgot to mention you need to download the OneWire library, and DallasTemperature library for this project.
 
Thanks for this I will have to try it.
 
update

An update to this project of mine. I redid the entire program based off the time.alarm libraries. The option for weather is commented out, currently it will get stuck on the weather pattern all day and I am trying to get it down to a few hours.


PHP:
//INCLUDES#####################################################################################
#include <OneWire.h>
#include "Wire.h"
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <LiquidCrystal.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 6 //Define the pin of the DS18B20
//VARIABLE#####################################################################################
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
//circulation control
//powerhead 1 is for waves, should be used with a solid state relay
//powerhead 2 is for tidal surge 2x per day
int powerhead1 = -100;
int powerhead2 = -100;
int powerhead1state = LOW;

long previousMillis1 = 0;        
long interval1 = 3000; // wave interval for powerhead1

void wavemaker()  //relay is based off interval1
{ 
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis1 > interval1) 
  { 
    previousMillis1 = currentMillis;   
    if (powerhead1state == LOW)
      powerhead1state = HIGH;
    else
      powerhead1state = LOW;
    digitalWrite(powerhead1, powerhead1state);
  }
}

///////////////////////////////
//temperature control
//mechanical relays are fine here
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

int fan = A0;
int heat = 4;
//temperature tolerances
int toohot = 82;
int toocold = 80;

void fanon()
{digitalWrite(fan,HIGH);}

void fanoff()
{digitalWrite(fan,LOW);}

void heaton()
{digitalWrite(heat,HIGH);}

void heatoff()
{digitalWrite(heat,LOW);}

////////////////////////////////
//secondary lighting
int ledmatrix = A1;
int refugium = 2;
///////////////////////////////
//primary Lighting
int mainlights = 3;    // LED connected to digital pin 3
int fadetime = (/*minutes to fade here-> */((60)/*<-minutes to fade*/*60000)/255);


////////////////////////////////
//weather patterns
long randNumber;



//#############################################################################################
void temperature()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  delay(1000);
  float temp2=0;
  lcd.setCursor(14, 0);
  temp2= sensors.getTempFByIndex(0);
  lcd.print(sensors.getTempFByIndex(0)); 
  lcd.print((char)223);

  if(temp2>toohot) return fanon(),heatoff(),lcd.setCursor(16,3), lcd.print("Cool");
  if(temp2<toocold) return heaton(),fanoff(),lcd.setCursor(16,3), lcd.print("Heat");
}
//#############################################################################################
void digitalClockDisplay()
{ 
  lcd.setCursor(0,0);
  lcd.print(hour());
  lcd.print(":");
  if (minute()<10) lcd.print("0");
  lcd.print(minute());
  delay(1000);
}
//#############################################################################################

void sunrise()
{
  lcd.setCursor(7,1);
  lcd.print("Morning");
  delay(500);
  
  digitalWrite(refugium,LOW);
  
    // fade in from min to max in increments of 1 points:
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=1) { 
    // sets the value (range from 0 to 255):
    analogWrite(mainlights, fadeValue);         
    delay(fadetime);
  }
}
  
//#############################################################################################
void noon()
{
  lcd.setCursor(7,1);
  lcd.print("Sunny  ");
 // randNumber = random(1,10);
  digitalWrite(refugium,LOW);
  digitalWrite(ledmatrix,HIGH);
  
  //weather patterns would go here
  //if (randNumber = 1) //10% chance of cloud pattern...
  
  /*
    for(int fadeValue = 30 ; fadeValue <= 255; fadeValue +=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40);}
    delay(10000);
    for(int fadeValue = 255 ; fadeValue >= 30; fadeValue -=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40); }
    delay(120000);
    for(int fadeValue = 30 ; fadeValue <= 255; fadeValue +=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40);}
    delay(20000);
    for(int fadeValue = 255 ; fadeValue >= 30; fadeValue -=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40); }
    delay(300000);
    for(int fadeValue = 30 ; fadeValue <= 255; fadeValue +=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40);}
    delay(5000);
    for(int fadeValue = 255 ; fadeValue >= 30; fadeValue -=1) { 
    analogWrite(mainlights, fadeValue);         
    delay(40); }
    delay(600000);
  */  
  
}  
  
//#############################################################################################  

void sunset()
{
    lcd.setCursor(7,1);
  lcd.print("Night  ");
  
  digitalWrite(refugium,HIGH);
  digitalWrite(ledmatrix,LOW);
  
    // fade out from max to min in increments of 1 points:
    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1) { 
    // sets the value (range from 0 to 255):
    analogWrite(mainlights, fadeValue);         
    delay(fadetime);  
  }
}
///////////////////////////////////////////////////////////////////////////////////////////
void hightide1()
{ digitalWrite(powerhead1,HIGH);
  lcd.setCursor(0,3);
  lcd.print("High Tide");
  delay(7200000);
  digitalWrite(powerhead1,LOW);
}
void hightide2()
{ digitalWrite(powerhead1,HIGH);
  lcd.setCursor(0,3);
  lcd.print("Low Tide ");
  delay(7200000);
  digitalWrite(powerhead1,LOW);
}

///////////////////////////////////////////////////////////////////////////////////////////



void setup()
{

 // digitalWrite(refugium, LOW);
 // digitalWrite(ledmatrix, LOW);
  analogWrite(mainlights, 0); //starts lights as 'off'
  pinMode(heat, OUTPUT);
  pinMode(fan, OUTPUT);
  pinMode(powerhead1, OUTPUT);
  pinMode(powerhead2,OUTPUT);
  pinMode(ledmatrix, OUTPUT);
  pinMode(refugium, OUTPUT);

  lcd.begin(20, 4);  // sets LCD screen
  //lcd.setCursor(5,3); 
 // lcd.print("Tide"); //this is always displayed
  sensors.begin();  // starts temp sensor
  Wire.begin(); //starts onewire communication
  Serial.begin(9600); //possibly unnecessary

  byte second, minute, hour;


  setSyncProvider(RTC.get);   //get the time from the RTC


  ///@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2.2
  ///////////Lighting cycle
  Alarm.alarmRepeat(8,30,00,sunrise);
  Alarm.alarmRepeat(9,30,00,noon);
  Alarm.alarmRepeat(8,30,00,sunset);
  Alarm.alarmRepeat(10,00,00,hightide1);    //10am high tide in (duration 2 hours)
  Alarm.alarmRepeat(20,00,00,hightide2);   //10pm high tide in

}


void  loop()
{
  Alarm.delay(1000); // service the alarm timers once per second
  digitalClockDisplay();
  temperature();
  wavemaker();
}
 
Nice job. Good diy project.
 
How is the controller working out for you? My buddy bought me an Uno for helping him out with some stuff. He left it on my desk saying "have fun, make something with the kids." lol

Once I get my tank up and running I might try and do something similar with it.
 
The controller has been rock solid, the old code from reef central would sometimes give me strange LCD errors but still worked. The code I did with the time.alarms has been error free though.
I'm keeping the code up on github. There's a branch I'm testing has functioning weather patterns, I am trying to get the random feature to work though. It doesn't seem very random hah.

Github.com/johntan/reef-controller
 
Sweetness! Once I get the tank setup and cycling I'll pull out the Uno and get the github info from you if you don't mind. I'm a developer by profession so I can't wait to start messing with this.
 
I envy those of you that can make up your own controllers. This stuff is amazing to me. I have done a good chunk of programming, and this is WAY over my head
 
I think this should be stickied ! :) Sounds like a fun little project with potential for future expansion. Great for the do-it-yourselfer who wants a basic low cost controller. If I didn't already dump in excess of $500 for my controller and misc bits, I'd probably give this a try.
 
Update

I'm resurrecting this post since a buddy of mine asked for clarification on how I put this together - so I made some very simple diagrams that should be helpful. I'm still looking for a PH module to this, if anyone knows how to build one pm me!

Relays, real time clock, from arduino-direct
resistors/transistors from radio shack
temp sensor from maxim (free sample)
led's and drivers from rapidled

The code to power this is at github.com/johntan/Reef-Controller
The only issue I've had is if the controller is on the same power strip as something being turned on and off, or if you unplug something on the same power strip, the LCD goes blank. My solution is keeping the controller on it's own outlet.
The controller still works 100% with the LCD blank though!

Obviously I make no guarantees with this system but for me, it's been running happy since December.
Each pdf is a different module I built in stages.

Temp View attachment temp.pdf
LCD View attachment lcd.pdf
Time View attachment time.pdf
Lights View attachment lights.pdf
Relays View attachment relays.pdf
 
I still plan on trying this at some point. I ordered a bunch of stuff from Maxim in my "sample pack"; they didn't have the exact temp sensor so I ended up with a + version I think. Actually got four different temp sensors, but only two of them would be usable (three-legged version). The other two were teenie-tiny ones I'd never be able to solder. I also got a water sensor I think, but I doubt I can use that either.

Thanks for the update!
 
all that code is far beyond anything my little brain could ever hope to comprehend, but very cool nonetheless! Nice job.

I'll just stick to buying an apex :o
 
I'm also working on an Arduino based controller with another open source developer. Here's what we have working.

Control heater on/off based on temperature
Control pumps on/off
Read pH
Read ORP
Read EC
LCD display
Ethernet interface (local and internet control)
Serial interface
Webapp
Log data to pachube
Control Lighting w/ pwm fade in/out for LED's

Here is what's coming down the pike:

View/control aquarium online
Auto-correction dosing
Automatic feeding
Calcium
Nitrate
Ammonia
Oxygen
Nitrite
Moon lighting cycle
Random storm modes
Wifi interface
Store last run times (example: ATO)

We would definitely like to expand the team. Anyone interested in collaborating, feel free to reach out. I'm in the Medford area.
 
Back
Top