(Another) Arduino Light Controller DIY build.

Reef Aquarium & Tank Building Forum

Help Support Reef Aquarium & Tank Building Forum:

Katchupoy

Well-known member
Joined
Jul 9, 2003
Messages
2,193
Location
Kent 98031
I dont know if its "another" because I dont know if someone here already made one which is good news so they can share their expertise, I hope.

Hello to all, its me again, sharing my step by step Arduino (Light) Controller build. If you are not familiar with my previous DIY Build, I just finished a 36 LED build on my 75 gallon mixed tank.

So I hope you I will be able to teach some of you who does not know arduino, and also learn from the arduino experts here since this is also my first time building one.

Based on my reading/research on these threads, forum and websites...

ARDUINO - Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. Its like having a computer doing a very specific function. Costs less, and consume less energy to run.

THREAD ABOUT DOING A CONTROLLER FROM SCRATCH - a huge thread on another forum doing arduino from scratch.

FULL BLOWN ARDUINO REEF CONTROLLER - Hoping that someday will be able to do the same. The good thing with Arduino, is its modular. You can add more features as you learn more.

ANOTHER DIY BUILD - another build that I believe is very similar to what Im doing.

So there you go.
 
Last edited:
this is great we were gonna try and build this for my plasma light to allow for ramp up and ramp down to simulate true sunrise and true sunset.
 
i believe its a 0-10v its got a manual dimmer on it now ill take a picture of the control box here in a min and post it
 
Thatguy, manual? do you mean like a potentiometer? that you adjust manually? This is perfect because its the same thing that i have. So Im using arduino to control my lights with a "TWIST"... lol... I mean control it not digitally but by means of analog.... similar concept as this....

200902161222.jpg


lol, so please be kind with me if Im not doing it the right way.... Why this way? Im not sure how to do it the correct way. I believe I need a transistor, etc, etc, etc.... maybe people here can help with the correct way, but right now Im set to "analog" way..... Servo's that turn my potentiometer for me... lol
 
i was thinking of just taking it out all together and do it digital so i can have set times with set percentages
 
The arduino is perfect for that application. It actually uses a pwm voltage signal to step up and step down. What I found cool about the arduino is that you can controll it by 1 percent. Which is awesome so you could technically set it to simulate the sun exactly. As in adjust 1% every 7.2 minutes. that would take you through a whole cycle of on and off. However there are other ways of doing the dimming that are not quite as cool as the arduino and that is if you have the linear potentiometer already you can get a cheap LED RGB controller and use it as the 10 volt reference signal for 3 channels.
 
Wow, I did not expect to have a huge (I mean huge) learning curve for these arduino sketches, but dont worry, we will disect it for everybody to learn.

While I am learning a lot of stuff, here is the partial parts list for now....

$24 DFRDUINO DUEMILANOVE 328 (ARDUINO COMPATIBLE) - So far this is the cheapest I can find.

$17 LCD SHIELD FOR ARDUINO - from the same store as above. Cheapest I can find too with buttons that might came handy. Hey I found this that has free shipping

$9 DS1307 REAL TIME CLOCK - Also the cheapest.

Note: the LCD and the ARDUINO came from the same store in CHINA, with very fast shipping DHL. But $14.00 for shipping and handling. So if you can source out these parts better than me, good for you.

Based on reefcentral TYPHON project, the cost of the project is around $40 - $60. So our target is the same thing maybe more, since theirs is custom made, mine is not. I am just lost with that thread so I decided to just buy ready made parts. Good or bad, I dont know. Learning curve? definitely. Adding functions other than controlling light in the future? priceless....
 
Last edited:
Amazon.com: hacktronics

with shipping from the us. plus there are solderless boards and they have boxes to put your arduino in. i did also se a dc motor control board in there as well. the only thing i couldnt find was the RTC. oh yeah there are books in this link too
 
Ok, I believe I got it.

Because of the basic know how I have with regards to coding Arduino which I believe is the same or similar as C++. Here is my first attempt on the code itself.

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



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



const int ledPin1 =  3;          // the number of the LED pin
const int ledPin2 =  2;

int ledState1 = LOW;             // ledState used to set the RELAY
int ledState2 = LOW; 
long previousMillis1 = 0;        // will store last time RELAY was updated
long previousMillis2 = 0;
long interval1 = 5000;           // interval at which to blink (milliseconds)
long interval2 = 3000;



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 = 5 ;   // time for blue LEDs to dim on and off in minutes
int whiteramptime = 5 ;  // 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 = 5 ;    // amount of time array is on at full power in minutes
int ontime = 12 ;        // time of day (hour, 24h clock) to begin photoperiod fade in
int blue = 10;           // blue LEDs connected to digital pin 5
int white = 11;          // white LEDs connected to digital pin 6



LiquidCrystal lcd(8, 9, 4, 5, 6, 7);



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  C L O C K  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



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

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  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());
}



/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  O N E S E C O N D   F U N C T I O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



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);
}




/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  R E L A Y 1   O N   O F F   F U N C T I O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/


void relay1()
{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis1 > interval1) {
    // save the last time you blinked the RELAY 
    previousMillis1 = currentMillis;   

    // if the RELAY is off turn it on and vice-versa:
    if (ledState1 == LOW)
      ledState1 = HIGH;
    else
      ledState1 = LOW;

    // set the RELAY with the ledState of the variable:
    digitalWrite(ledPin1, ledState1);
  }
}
  
  
  
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  R E L A Y 2   O N   O F F   F U N C T I O N |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/




void relay2()
{
  unsigned long currentMillis2 = millis();
 
  if(currentMillis2 - previousMillis2 > interval2) {
    // save the last time you blinked the RELAYD 
    previousMillis2 = currentMillis2;   

    // if the RELAY is off turn it on and vice-versa:
    if (ledState2 == LOW)
      ledState2 = HIGH;
    else
      ledState2 = LOW;

    // set the RELAY with the ledState of the variable:
    digitalWrite(ledPin2, ledState2);
  }
}




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




void setup() {
  // set the digital pin as output:
  pinMode(ledPin1, OUTPUT);  
  pinMode(ledPin2, OUTPUT); 
  lcd.clear();


/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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 = 50;
  minute = 59;
  hour = 11;
  dayOfWeek = 6;
  dayOfMonth = 26;
  month = 1;
  year = 11;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

  analogWrite(blue, bluemin);
  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(0, 1);
  lcd.print("blue:");
  lcd.print(33*bluemin/85);
  lcd.print("  white:");
  lcd.print(33*whitemin/85);  
}




/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  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
  



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


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

      // fade blue LEDs in from min to max in increments of 1 point:
      for(int bluefadeval = bluemin ; bluefadeval <= bluemax; bluefadeval ++) // sets the minimum and maximum values
      { 
        analogWrite(blue, bluefadeval); 
        lcd.setCursor(5, 1);
        lcd.print(33*bluefadeval/85);
        lcd.print(" "); 

        int countdown = ((blueramptime*60)/(bluemax-bluemin)); // 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 in increments of 1 point:
      for(int whtfadeval = whitemin ; whtfadeval <= whitemax; whtfadeval ++) // sets the minimum and maximum values
      { 
        analogWrite(white, whtfadeval); 
        lcd.setCursor(14, 1);
        lcd.print(33*whtfadeval/85);
        lcd.print(" "); 

        int countdown = ((whiteramptime*60)/(whitemax-whitemin)); // 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 (((ontime * 60) + blueramptime + whiteramptime) < daybyminute) 
  { 
    if ( daybyminute < ((ontime * 60) + blueramptime + whiteramptime + photoperiod)) // if time is in range of photoperiod, turn lights on to maximum fade value
    {
      analogWrite(white, whitemax);
      analogWrite(blue, bluemax);
      lcd.setCursor(14, 1);
      lcd.print(33*whitemax/85);
      lcd.print(" "); 
      lcd.setCursor(5, 1);
      lcd.print(33*bluemax/85);
      lcd.print(" "); 
    } 
  }
 


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



  if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
  { 
    if (((ontime * 60) + photoperiod + 2*blueramptime + whiteramptime) >= daybyminute)
    {
      // fade white LEDs out from max to min in increments of 1 point:
      for(int whtfadeval = whitemax; whtfadeval >= whitemin; whtfadeval --) // sets the minimum and maximum values
      { 
        analogWrite(white, whtfadeval);
        lcd.setCursor(14, 1);
        lcd.print(33*whtfadeval/85);
        lcd.print(" "); 

        int countdown = ((whiteramptime*60)/(whitemax-whitemin)); // 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 bluefadeval = bluemax; bluefadeval >= bluemin; bluefadeval --) // sets the minimum and maximum values
      { 
        analogWrite(blue, bluefadeval);
        lcd.setCursor(5, 1);
        lcd.print(33*bluefadeval/85);
        lcd.print(" "); 

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


}  // END LOOP
 
There are two parts.

Relay part - if you have a regular on and off style requirements. It can be used for powerheads as a wavetimer.
Dimming part - if you have LED lighting that you want sunrise/sunset effect. Note: that you must have a dimmable driver.

The Dimming Part can also be easily converted to simple ON/OFF function if you have like lighting that does not require dimming. ie: T5s, MH etc.
 
Last edited:
Dimming Part

Here is where you change the variables.

Code:
int blueramptime = 5 ;   // time for blue LEDs to dim on and off in minutes
int whiteramptime = 5 ;  // 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 = 5 ;    // amount of time array is on at full power in minutes
int ontime = 12 ;        // time of day (hour, 24h clock) to begin photoperiod fade in
int blue = 10;           // blue LEDs connected to digital pin 5
int white = 11;          // white LEDs connected to digital pin 6
 
Back
Top