Arduino sketches

you should be able to change the start and finish times as you have suggested, as long as you change them all there should be no impact to the program.
 
Never occured to me that using LED's you could do this. As a person who tries to create a full natural ecosystem type system the idea of mimicing nature in the lighting is awesome. Going to start saving for an LED setup now lol. Won't miss the T-5 bulb bill yearly either lol. Love this hobby.

Nobble
 
Hi!
I got some problem with a sketch I'm using. I have posted this on another thread (link) but have not got any respond.

The problem I have is when the light should turn on and when it time to shut down.
It does not ramp up or down as it should. In the morning it turns on at fullpower for about 10 minutes and then it shut off and then start to ramp up as it should.
The same thing happens at the evening. It start to ramp down as it should but when it's time to shut down complely it it power up to fullpower for about 10 minutes and then it shut off.

Another issue is that the moonlight seems to be on at almost full power.

So, can any one of you pro take a look at the sketch and see whats wrong?

The system is build by using Meanwell LDD-1000h and 700H driver.
The rtc clock I'm using is tinyrtc and I use this sketch to set it (link)

The computer I'm using is run with Linux Mint and the arduino board is Arduino Uno.

The librarys I use can be found "here"

And here is the sketch:
Code:
// Natural Reef Aquarium Lighting V2.3
// 16/06/2013
// Developed by J. Harp (nUm - RTAW Forums, Numlock10 - Reef Central Forums)
// Formulas based off of information from NOAA website for sunrise / sunset times.
// Includes Lunar Simulation.
// Compiled in Arduino 1.5.2
//
// Testing;
// Additonal colour channels
// Unique "fullsun" values for each string
//
// Future Development:
// Weather Simulation
//
// Please feel free to use this and modify as you see fit, if you have any comments or suggestions please let me know via messages on the forums listed above.
//

#include <math.h> 
#include <Wire.h> 
#define DS1307_I2C_ADDRESS 0x68

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;

// LED variables (Change to match your needs)
byte bluePins[]      =  {6};      // PWM pins for blues
byte whitePins[]     =  {10, 11};    // PWM pins for whites
byte uvPins[]        =  {5, 9};         // PWM pins for UVs
byte moonPins[]      =  {3};            // PWM pins for moonlights

byte blueChannels    =        1;    // how many PWMs for blues (count from above)
byte whiteChannels   =        2;    // how many PWMs for whites (count from above)
byte uvChannels      =        2;    // how many PWMs for uv (count from above)
byte moonChannels    =        1;    // how many PWMs from moon (count from above)

byte BluePWMHigh[]          =       {255};        // High value for Blue PWM each vale is for each string - if your values are noraml this is 255, if your values are inverted this is 0
byte BluePWMLow[]           =       {0};            // Low value for Blue PWM - if your values are noraml this is 0, if your values are inverted this is 255
float BlueFull[]            =       {25};          // Value in degrees (sun angle) that each Blue string will be at max output
byte WhitePWMHigh[]         =       {200, 200};        // High value for White PWM - if your values are noraml this is 255, if your values are inverted this is 0
byte WhitePWMLow[]          =       {0, 0};            // Low value for White PWM - if your values are noraml this is 0, if your values are inverted this is 255
float WhiteFull[]           =       {37.5, 37.5};      // Value in degrees (sun angle) that each White string will be at max output
byte UVPWMHigh[]            =       {255, 255};             // High value for UV PWM - if your values are noraml this is 255, if your values are inverted this is 0
byte UVPWMLow[]             =       {0, 0};               // Low value for UV PWM - if your values are noraml this is 0, if your values are inverted this is 255
float UVFull[]              =       {30, 30};              // Value in degrees (sun angle) that each UV string will be at max output
byte MoonPWMHigh[]          =       {150};             // High value for Moon PWM - if your values are noraml this is 255, if your values are inverted this is 0
byte MoonPWMLow[]           =       {0};               // Low value for Moon PWM - if your values are noraml this is 0, if your values are inverted this is 255

// Set for the location of the world you want to replicate.

float latitude = -17.730211;   // + to N  Defualt - (-19.770621) Heart Reef, Great Barrier Reef, QLD, Australia 
float longitude = 177.127218;  // + to E  Defualt - (149.238532)
int TimeZone = 12;             // + to E  Defulat - (10)

// Julian Century Varaiable

float JC;

// Sunlight Variables

//float fullSun = 37.5;  // sun elevation in deg that we will assume full sunlight values (Larger = more sunlight)
int delayTime = -150;     // start time delay in minutes,  - will push the day back, + will bring the day forward


int SunLight (byte _ledPin, byte _ledHigh, byte _ledLow, float _fullSun, byte _year, byte _month, byte _day, byte _hour, byte _min, byte _sec)
{
  float a = floor((14 - _month)/12);
  float y = _year + 4800 - a;
  float m = _month + (12 * a) - 3;
  float AH;
  int result;
  
  JC = (((_day + floor(((153.0 * m) + 2.0) / 5.0) + (365.0 * y) + floor(y / 4.0) - floor(y / 100.0) + floor(y / 400.0) - 32045.0) + ((_hour / 24.0) + (_min / 1444.0) + (_sec / 86400.0))) - 2451556.08) / 36525.0;
  
  float GMLS = fmod(280.46646+JC*(36000.76983 + JC * 0.0003032),360);
  
  float GMAS = 357.52911 + JC * (35999.05029 - 0.0001537 * JC);
  
  float EEO = 0.016708634 - JC * (0.000042037 + 0.0000001267 * JC);
  
  float SEoC = sin((GMAS * M_PI)/180)*(1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(((2 * GMAS) * M_PI) / 180) * (0.019993 - 0.000101 * JC) + sin(((3 * JC) * M_PI) / 180) * 0.000289;
  
  float STL = GMLS + SEoC;
  
  float STA = GMAS + SEoC;
  
  float SRV = (1.000001018 * (1 - EEO * EEO)) / (1 + EEO * cos((STA * M_PI) / 180));
  
  float SAL = STL - 0.00569 - 0.00478 * sin(((125.04 - 1934.136 * JC) * M_PI) / 180);
  
  float MOE = 23 + (26 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60) / 60;
  
  float OC = MOE + 0.00256 * cos(((215.04 - 1934.136 * JC) * M_PI) / 180);
  
  float SD = (asin(sin((OC * M_PI) / 180) * sin((SAL * M_PI) / 180))) * (180 / M_PI);
  
  float vy = tan(((OC / 2) * M_PI) / 180) * tan(((OC / 2) * M_PI) / 180);
  
  float EQoT = (4 * (vy * (sin(2 * ((GMLS * M_PI) / 180)) - 2 * EEO * sin((GMAS * M_PI) / 180) + 4 * EEO * vy * sin((GMAS * M_PI) / 180) * cos( 2 * ((GMLS * M_PI) / 180)) - 0.5 * vy * vy * sin(4 * ((GMLS * M_PI) / 180)) - 1.25 * EEO * EEO * sin(2 * ((GMAS * M_PI) / 180))))) * (180 / M_PI);
  
  float HAS = acos(cos((90.833 * M_PI) / 180) / (cos((latitude * M_PI) / 180) * cos((SD * M_PI) / 180)) - tan((latitude * M_PI) / 180) * tan((SD * M_PI) / 180)) * (180 / M_PI);

  float SN = (720 - 4 * longitude - EQoT + TimeZone * 60);

  float SR = SN - HAS * 4;

  float SS = SN + HAS * 4;
 
  float STD = 8 * HAS;
  
  float TST = fmod((((_hour) + (_min / 60.0) + (_sec / 3600.0)) / 24.0)*1440 + EQoT + 4 * longitude - 60 * TimeZone,1440)+delayTime;
 
  if (TST / 4 < 0)
  {
  AH = ((TST / 4.0) + 180);
  }
  else
  {
  AH = ((TST / 4.0) - 180);  
  }
  
  float SZA = (acos(sin((latitude * M_PI) / 180) * sin((SD * M_PI) / 180) + cos((latitude * M_PI) / 180) * cos((SD * M_PI) / 180) * cos((AH * M_PI) / 180))) * (180 / M_PI);
  
  int SEA = 90 - SZA;
  
  if (SEA < 0)  
  {
   result = _ledLow;    
  }
  
  if (SEA > 0 && SEA < _fullSun)
  {
  result = map(SEA,0,_fullSun,_ledLow,_ledHigh);
  }
  
  if (SEA > _fullSun)  
  {
  result = _ledHigh;
  }
  
  analogWrite(_ledPin, result);  
  return result;
  
}

int MoonLight (float JC, byte _ledPin, byte _ledHigh, byte _ledLow)
{
 int result;
 
 float MS = fmod((2456318.69458333 - JC),29.530589);
 
 if(MS < 14.7518)
 {
  result = map(MS,0,14.7518,_ledLow,_ledHigh);
 }
 
 if( MS > 14.7518)
 {
   result = map(MS,14.7518,29.530589,_ledHigh,_ledLow);
 }
 analogWrite(_ledPin, result); 
 return result;
}
 

/***** RTC Functions *******/
/***************************/
// 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) );
}

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

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup() {
delay(500);
Serial.begin(57600);
Wire.begin();
}

void loop() {
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);
  if (psecond != second){
    psecond = second;
  Serial.print(rtcHrs);
  Serial.print(":");
  Serial.print(rtcMins);
  Serial.print(":");
  Serial.print(second);
  Serial.print(" ");
  Serial.print(dayOfMonth);
  Serial.print("/");
  Serial.print(month);
  Serial.print("/");
  Serial.println(year);
  update_leds();
  }
}

void update_leds ( void ){
  int i;
  byte value;
  int MS;
  Serial.println("Blue LED's");
  for (i = 0; i < blueChannels; i++)
  {
    value = SunLight(bluePins[i],BluePWMHigh[i],BluePWMLow[i],BlueFull[i],year,month,dayOfMonth,rtcHrs,rtcMins,second);
    Serial.print(map(value,BluePWMLow[i],BluePWMHigh[i],0,100));
    Serial.print("% ");
  }
  Serial.println();
  Serial.println("White LED's");
  for (i = 0; i < whiteChannels; i++)
  {
    value = SunLight(whitePins[i],WhitePWMHigh[i],WhitePWMLow[i],WhiteFull[i],year,month,dayOfMonth,rtcHrs,rtcMins,second);
    Serial.print(map(value,WhitePWMLow[i],WhitePWMHigh[i],0,100));
    Serial.print("% ");
  }
  Serial.println();
  Serial.println("UV LED's");
  for (i = 0; i < uvChannels; i++)
  {
    value = SunLight(uvPins[i],UVPWMHigh[i],UVPWMLow[i],UVFull[i],year,month,dayOfMonth,rtcHrs,rtcMins,second);
    Serial.print(map(value,UVPWMLow[i],UVPWMHigh[i],0,100));
    Serial.print("% ");
  }
  Serial.println();
  Serial.println("Moon Value");
  for (i = 0; i < moonChannels; i ++)
  {
  MS = MoonLight(JC, moonPins[i],MoonPWMHigh[i],MoonPWMLow[i]);
  Serial.println(MS);
  Serial.print(map(MS,MoonPWMLow[i],MoonPWMHigh[i],0,100));
  Serial.print("% ");
  }
  Serial.println();
}
 
Arduino BuckPuck Controller

Arduino BuckPuck Controller

Iv'e been trying for 2 days to figure out how to invert the output of this code.

I have this code working on a pico tank running a few Cree led's with some NPN Transistors and a laptop power supply. Everything is working fine.

Now I'm building another fixture using BuckPucks as drivers and have them interfaced nicely. The issue is I need to reverse the output. So instead of 0 for Off and 255 for Max, I need 255 for Off and 0 for Max. I could do it with circuitry but code would be cleaner.

Off before sunrise is easy
From:
if (mins <= start || mins <= mins > start + period) {
analogWrite(ledPin, 0);

To:
if (mins <= start || mins <= mins > start + period) {
analogWrite(ledPin, 255);

I even had the ramp working once. But after that it falls apart.
I'm thinking there is an easy fix, but I can't figure it out.

Any help would be appreciated.




Code:
/*
 Arduino LED controller for reef aquariums

// paramterized LED lighting control for reef aquariums
// use a DS1307 RTC to kick off lighting schedules
//   fade up on a given slope
//         delay a set amount
//         fade back down
//   such that the photoperiod lasts the correct amount of time


//  Circuit
// 
// PWM pins described below connected to dimming circuits on drivers
// ledMaster pin below connected to a 120V AC relay to turn the LED drivers on and off (optional)
// grounds from drivers connected to arduino ground
// DS1307 RTC connected via I2C
*/

// Pins to control LEDs. Change these if you're using different pins.
int togSwitch = 10;  // RTC Overide Switch
int blueLed = 3;     // LED PWM channel for blues
int whiteLed = 9;   // LED PWM channel for whites
int uvLed = 11;      // select the pin for the LED
int moonLed = 6;      // select the pin for the LED
int whitePot = A0;    // select the input pin for the potentiometer
int bluePot = A1;    // select the input pin for the potentiometer
int uvPot = A2;    // select the input pin for the potentiometer
int moonPot = A3;    // select the input pin for the potentiometer

// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;

// Other variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight. Don't change this.

int blueStartMins = 510;    // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int whiteStartMins = 510;   // minute to start whites. Same as above.
int uvStartMins = 510;   // minute to start ultra violet. Same as above.
int moonStartMins = 1260;   // minute to start moon lights. Same as above.

int bluePhotoPeriod = 750;  // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int whitePhotoPeriod = 750; // photoperiod in minutes, whites. Same as above.
int uvPhotoPeriod = 750; // photoperiod in minutes, ultra violets. Same as above.
int moonPhotoPeriod = 480; // photoperiod in minutes, moon lights. Same as above.
int fadeDuration = 0;      // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.
int togState = 0;         // variable for reading the toggle switch status

//int blueMax = 200;          // max intensity for blues. Change if you want to limit max intensity.
//int whiteMax = 200;         // max intensity for whites. Same as above.


/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
void setLed(int mins,    // current time in minutes
            int ledPin,  // pin for this channel of LEDs
            int start,   // start time for this channel of LEDs
            int period,  // photoperiod for this channel of LEDs
            int fade,    // fade duration for this channel of LEDs
            int ledMax   // max value for this channel
            )  {
  if (mins <= start || mins <= mins > start + period)  {
    analogWrite(ledPin, 0);
  }
  if (mins > start && mins <= start + fade)  {
    analogWrite(ledPin, map(mins - start, 0, fade, 0, ledMax));
  }
    if (mins > start + fade && mins <= start + period - fade)  {
    analogWrite(ledPin, ledMax);
  }
    if (mins > start + period - fade && mins <= start + period)  {
    analogWrite(ledPin, map(mins - start - period + fade, 0, fade, ledMax, 0));
  }
}

/***** RTC Functions *******/
/***************************/
// 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.write(0);
   Wire.write(decToBcd(second));
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(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)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup()  { 
  
pinMode(togSwitch, INPUT);
  Wire.begin();
  Serial.begin(9600);
} 

/***** Main Loop ***********/
/***************************/
void loop()  { 
  // get time from RTC and put in hrs and mins variables
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);
  minCounter = rtcHrs * 60 + rtcMins;
  
  Serial.println(second);
  Serial.print("MinCount");
  Serial.println(minCounter);     
  
int sensorValueb = analogRead (bluePot);
int blueMax = map (sensorValueb, 0, 1023, 0, 255);

int sensorValuew = analogRead (whitePot);
int whiteMax = map (sensorValuew, 0, 1023, 0, 255);

int sensorValueu = analogRead (uvPot);
int uvMax = map (sensorValueu, 0, 1023, 0, 255);

int sensorValuem = analogRead (moonPot);
int moonMax = map (sensorValuem, 0, 1023, 0, 255);
 
int togState = digitalRead(togSwitch);

if (psecond != second){ 
    psecond = second;}    

   if(togState == HIGH)
   {
     analogWrite(whiteLed, whiteMax);
     analogWrite(blueLed, blueMax);
     analogWrite(uvLed, uvMax);
     analogWrite(moonLed, moonMax);
   }

  else
   {
     setLed(minCounter, whiteLed, whiteStartMins, whitePhotoPeriod, fadeDuration, whiteMax);
     setLed(minCounter, blueLed, blueStartMins, bluePhotoPeriod, fadeDuration, blueMax);
     setLed(minCounter, uvLed, uvStartMins, uvPhotoPeriod, fadeDuration, uvMax);
     setLed(minCounter, moonLed, moonStartMins, moonPhotoPeriod, fadeDuration, moonMax);
   }
 
  delay(50);
}
 
It looks like you have a few of your map functions reversed along with the min and max in the main light loop;

PHP:
/*
 Arduino LED controller for reef aquariums

// paramterized LED lighting control for reef aquariums
// use a DS1307 RTC to kick off lighting schedules
//   fade up on a given slope
//         delay a set amount
//         fade back down
//   such that the photoperiod lasts the correct amount of time


//  Circuit
// 
// PWM pins described below connected to dimming circuits on drivers
// ledMaster pin below connected to a 120V AC relay to turn the LED drivers on and off (optional)
// grounds from drivers connected to arduino ground
// DS1307 RTC connected via I2C
*/

// Pins to control LEDs. Change these if you're using different pins.
int togSwitch = 10;  // RTC Overide Switch
int blueLed = 3;     // LED PWM channel for blues
int whiteLed = 9;   // LED PWM channel for whites
int uvLed = 11;      // select the pin for the LED
int moonLed = 6;      // select the pin for the LED
int whitePot = A0;    // select the input pin for the potentiometer
int bluePot = A1;    // select the input pin for the potentiometer
int uvPot = A2;    // select the input pin for the potentiometer
int moonPot = A3;    // select the input pin for the potentiometer

// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;

// Other variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight. Don't change this.

int blueStartMins = 510;    // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int whiteStartMins = 510;   // minute to start whites. Same as above.
int uvStartMins = 510;   // minute to start ultra violet. Same as above.
int moonStartMins = 1260;   // minute to start moon lights. Same as above.

int bluePhotoPeriod = 750;  // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int whitePhotoPeriod = 750; // photoperiod in minutes, whites. Same as above.
int uvPhotoPeriod = 750; // photoperiod in minutes, ultra violets. Same as above.
int moonPhotoPeriod = 480; // photoperiod in minutes, moon lights. Same as above.
int fadeDuration = 0;      // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.
int togState = 0;         // variable for reading the toggle switch status

//int blueMax = 200;          // max intensity for blues. Change if you want to limit max intensity.
//int whiteMax = 200;         // max intensity for whites. Same as above.


/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
void setLed(int mins,    // current time in minutes
            int ledPin,  // pin for this channel of LEDs
            int start,   // start time for this channel of LEDs
            int period,  // photoperiod for this channel of LEDs
            int fade,    // fade duration for this channel of LEDs
            int ledMax   // max value for this channel
            )  {
  if (mins <= start || mins <= mins > start + period)  {
    analogWrite(ledPin, 255);
  }
  if (mins > start && mins <= start + fade)  {
    analogWrite(ledPin, map(mins - start, 0, fade, 255, ledMax));
  }
    if (mins > start + fade && mins <= start + period - fade)  {
    analogWrite(ledPin, ledMax);
  }
    if (mins > start + period - fade && mins <= start + period)  {
    analogWrite(ledPin, map(mins - start - period + fade, 0, fade, ledMax, 255));
  }
}

/***** RTC Functions *******/
/***************************/
// 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.write(0);
   Wire.write(decToBcd(second));
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(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)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup()  { 
  
pinMode(togSwitch, INPUT);
  Wire.begin();
  Serial.begin(9600);
} 

/***** Main Loop ***********/
/***************************/
void loop()  { 
  // get time from RTC and put in hrs and mins variables
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);
  minCounter = rtcHrs * 60 + rtcMins;
  
  Serial.println(second);
  Serial.print("MinCount");
  Serial.println(minCounter);     
  
int sensorValueb = analogRead (bluePot);
int blueMax = map (sensorValueb, 0, 1023, 255, 0);

int sensorValuew = analogRead (whitePot);
int whiteMax = map (sensorValuew, 0, 1023, 255, 0);

int sensorValueu = analogRead (uvPot);
int uvMax = map (sensorValueu, 0, 1023, 255, 0);

int sensorValuem = analogRead (moonPot);
int moonMax = map (sensorValuem, 0, 1023, 255, 0);
 
int togState = digitalRead(togSwitch);

if (psecond != second){ 
    psecond = second;}    

   if(togState == HIGH)
   {
     analogWrite(whiteLed, whiteMax);
     analogWrite(blueLed, blueMax);
     analogWrite(uvLed, uvMax);
     analogWrite(moonLed, moonMax);
   }

  else
   {
     setLed(minCounter, whiteLed, whiteStartMins, whitePhotoPeriod, fadeDuration, whiteMax);
     setLed(minCounter, blueLed, blueStartMins, bluePhotoPeriod, fadeDuration, blueMax);
     setLed(minCounter, uvLed, uvStartMins, uvPhotoPeriod, fadeDuration, uvMax);
     setLed(minCounter, moonLed, moonStartMins, moonPhotoPeriod, fadeDuration, moonMax);
   }
 
  delay(50);
}

Try and let me know if it works.
 
Thanks Jason, It works perfectly. I had another version that I was getting real close on, but wasn't as clean as this. Sweet!

This is going to work GREAT.
I build a lot of small DIY LED fixtures using BuckBlock's and couldn't find an example where someone controlled one with a Arduino. The code I posted in 545 is great for 0v to 5v and then back to 0v. I knew I could build a small circuit for each channel to convert it to 0v - 10v to drive Meanwells or anything like that. I'm currently running it on a 6g cube with 4 channels driving some NPN transistors that are connected directly to the LED's.

The cool thing about the BuckBlock's is they will work off 0v - 10v or by placing a 20k pot between the dimming wires. So I connected a 2N4401 NPN Transistor between the dimming leads of the BuckBlock with the center lead (Base) to the Arduino. When there is no power the BuckBlock is at 100%. As you apply voltage to the transistor it pulls the BuckBlock down until it is off. Very smooth transition with limited circuitry and no need for a 0 to 10v conversion.

I added a couple things to the original code. The toggle switch let's me override the clock (sometimes I want to look at the tank after sunset). The potentiometers give me full control of each channels brightness in either mode (clock or override) without going into the code to adjust. It's a pretty sweet setup.
I want to thank everybody on this thread that created the base code, and Jason (NumLock10) for inverting it.

Now with a wall wart, Arduino Nano, RTC and a BuckBlock you can have a Sunrise/Sunset/Moon LED setup with as few as 3 LED's.
 
Just checked it out. Very Nice!
Tons of cool features. I like the way you built in the min and max for easy inversion. I'll probably stick with this code as I run a longer daylight cycle in all my tanks.
The moon cycle is something I'd like to add to this code. I have it already on 2 of my other tanks with Reef Keepers. I have moonlight bulbs on my 6g, but they are set with fixed on/off times. I just adjust the intensity every couple nights with the moonlight pot as I watch the intensity on the 150g go up and down with the lunar cycle.

Thanks Again for the fix. I got home from work and the lights were already on there way down for the night. They are now off so I'm gonna pull the light and get everything in a project box.
 
Added a LCD Screen (I2c 20x4) to the sketch late last night. It currently displays the maxLed value for each string with 0 - 99.
Looking for the command that will display the output value of the ledPin. I tried analogRead & digitalRead (whiteLed); and got a strange number that didn't change much as I adjusted the lights up and down with the potentiometers. Not sure what to read to catch the actual output.
I'm thinking I'll reconfigure the display to give me date & time on line 1.
Daytime Intensity or blueLed pin3 output value on line 2 (I'll have to throw in a little calc to invert the numbers and give me a 0 - 100 readout).
And Moonlight Intensity moonLed pin6 output value on line 3
Don't know what I'll put on line 4, maybe "Happy Reefing"
Lemme know what you think. I'm open to ideas. Just had the screen in my parts box and figured it would be a simple addition.


Code:
/* 
 Arduino LED controller for reef aquariums 

// paramterized LED lighting control for reef aquariums 
// use a DS1307 RTC to kick off lighting schedules 
//   fade up on a given slope 
//         delay a set amount 
//         fade back down 
//   such that the photoperiod lasts the correct amount of time 


//  Circuit 
//  
// PWM pins described below connected to dimming circuits on drivers 
// ledMaster pin below connected to a 120V AC relay to turn the LED drivers on and off (optional) 
// grounds from drivers connected to arduino ground 
// DS1307 RTC connected via I2C
*/ 

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#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


// Pins to control LEDs. Change these if you're using different pins. 
int togSwitch = 10;  // RTC Overide Switch 
int blueLed = 3;     // LED PWM channel for blues 
int whiteLed = 9;   // LED PWM channel for whites 
int uvLed = 11;      // select the pin for the LED 
int moonLed = 6;      // select the pin for the LED 
int whitePot = A0;    // select the input pin for the potentiometer 
int bluePot = A1;    // select the input pin for the potentiometer 
int uvPot = A2;    // select the input pin for the potentiometer 
int moonPot = A3;    // select the input pin for the potentiometer 

// Set up RTC 
//#include "Wire.h" 
#define DS1307_I2C_ADDRESS 0x68 

// RTC variables 
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond; 

// Other variables. These control the behavior of lighting. Change these to customize behavoir 
int minCounter = 0;         // counter that resets at midnight. Don't change this. 

int blueStartMins = 400;    // minute to start blues. Change this to the number of minutes past 
                            //    midnight you want the blues to start. 
int whiteStartMins = 420;   // minute to start whites. Same as above. 
int uvStartMins = 410;   // minute to start ultra violet. Same as above. 
int moonStartMins = 1200;   // minute to start moon lights. Same as above. 

int bluePhotoPeriod = 840;  // photoperiod in minutes, blues. Change this to alter the total 
                            //    photoperiod for blues. 
int whitePhotoPeriod = 720; // photoperiod in minutes, whites. Same as above. 
int uvPhotoPeriod = 720; // photoperiod in minutes, ultra violets. Same as above. 
int moonPhotoPeriod = 660; // photoperiod in minutes, moon lights. Same as above. 
int fadeDuration = 180;      // duration of the fade on and off for sunrise and sunset. Change 
                            //    this to alter how long the fade lasts. 
int togState = 0;         // variable for reading the toggle switch status 

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


/****** LED Functions ******/ 
/***************************/ 
//function to set LED brightness according to time of day 
//function has three phases - ramp up, hold, and ramp down 
void setLed(int mins,    // current time in minutes 
            int ledPin,  // pin for this channel of LEDs 
            int start,   // start time for this channel of LEDs 
            int period,  // photoperiod for this channel of LEDs 
            int fade,    // fade duration for this channel of LEDs 
            int ledMax   // max value for this channel 
            )  { 
  if (mins <= start || mins <= mins > start + period)  { 
    analogWrite(ledPin, 255); 
  } 
  if (mins > start && mins <= start + fade)  { 
    analogWrite(ledPin, map(mins - start, 0, fade, 255, ledMax)); 
  } 
    if (mins > start + fade && mins <= start + period - fade)  { 
    analogWrite(ledPin, ledMax); 
  } 
    if (mins > start + period - fade && mins <= start + period)  { 
    analogWrite(ledPin, map(mins - start - period + fade, 0, fade, ledMax, 255)); 
  } 
} 

/***** RTC Functions *******/ 
/***************************/ 
// 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.write(0); 
   Wire.write(decToBcd(second)); 
   Wire.write(decToBcd(minute)); 
   Wire.write(decToBcd(hour)); 
   Wire.write(decToBcd(dayOfWeek)); 
   Wire.write(decToBcd(dayOfMonth)); 
   Wire.write(decToBcd(month)); 
   Wire.write(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) 
{ 
  Wire.beginTransmission(DS1307_I2C_ADDRESS); 
  Wire.write(0); 
  Wire.endTransmission(); 

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 

  *second     = bcdToDec(Wire.read() & 0x7f); 
  *minute     = bcdToDec(Wire.read()); 
  *hour       = bcdToDec(Wire.read() & 0x3f); 
  *dayOfWeek  = bcdToDec(Wire.read()); 
  *dayOfMonth = bcdToDec(Wire.read()); 
  *month      = bcdToDec(Wire.read()); 
  *year       = bcdToDec(Wire.read()); 
} 

void setup()  {  
   
pinMode(togSwitch, INPUT); 
  Wire.begin(); 
  //Serial.begin(9600);     //Uncomment to check the time on the RTC
  
   lcd.begin (20,4);
  
// Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                   // go home

  lcd.print("White");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print("Royal Blue");
  lcd.setCursor ( 0, 2 );        // go to the next line
  lcd.print("Ultra Violet");
  lcd.setCursor ( 0, 3 );        // go to the next line
  lcd.print("Moon Lights");
  
}  

/***** Main Loop ***********/ 
/***************************/ 
void loop()  {  
  // get time from RTC and put in hrs and mins variables 
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year); 
  minCounter = rtcHrs * 60 + rtcMins; 
   
  //Serial.println(second);     //Uncomment to check the time on the RTC
  //Serial.print("MinCount");   //Same as above
  //Serial.println(minCounter); //Same as above
   
int sensorValueb = analogRead (bluePot); 
int blueMax = map (sensorValueb, 0, 1023, 255, 0); 

int sensorValuew = analogRead (whitePot); 
int whiteMax = map (sensorValuew, 0, 1023, 255, 0); 

int sensorValueu = analogRead (uvPot); 
int uvMax = map (sensorValueu, 0, 1023, 255, 0); 

int sensorValuem = analogRead (moonPot); 
int moonMax = map (sensorValuem, 0, 1023, 255, 0); 
  
int togState = digitalRead(togSwitch); 


lcd.setCursor (14,0);
  lcd.print(sensorValuew/10.3);
  
  lcd.setCursor (14,1);
  lcd.print(sensorValueb/10.3);
  
  lcd.setCursor (14,2);
  lcd.print(sensorValueu/10.3);
  
  lcd.setCursor (14,3);
  lcd.print(sensorValuem/10.3);

  



if (psecond != second){  
    psecond = second;}     

   if(togState == HIGH) 
   { 
     analogWrite(whiteLed, whiteMax); 
     analogWrite(blueLed, blueMax); 
     analogWrite(uvLed, uvMax); 
     analogWrite(moonLed, moonMax); 
   } 

  else 
   { 
     setLed(minCounter, whiteLed, whiteStartMins, whitePhotoPeriod, fadeDuration, whiteMax); 
     setLed(minCounter, blueLed, blueStartMins, bluePhotoPeriod, fadeDuration, blueMax); 
     setLed(minCounter, uvLed, uvStartMins, uvPhotoPeriod, fadeDuration, uvMax); 
     setLed(minCounter, moonLed, moonStartMins, moonPhotoPeriod, fadeDuration, moonMax); 
   } 
  
  delay(500); 
}
 
Hello, I'm sort of new here... been reading alot and the more I read the more confused I get. In short I have the hardware side figured out, and only 1 string of lights hooked up to the arduino for testing & playing. I'm not good at understanding the programming - let alone try to write a complete program for my needs. :crazy1:

My fixture currently has 7 strings of (5) 1 watt leds for a total of 35 leds.
2-strings of blues, 2-strings of cool whites, 2-strings of warm white, 1-string of ultra violet. Eventually after I get the programming figured out i'm going to be switching out 1 or 2 strings of the whites for red, green, yellow, cyan, etc... Also i'm going to hook up my cooling fan, refugium light, and later my (2) mini 12v pumps.

Some of my questions on the programming side is... say if I use 1 of the sketches posted on here, can I remove some functions - (example)-(remove the temp sensor function) and still have the sketch work properly? And what can I remove and still have it function. I was looking at this sketch by (Numlock10)...

// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// Temperature Sensor

#include <avr/pgmspace.h>
#define THERM_PIN 0 // 10ktherm & 10k resistor as divider.

int therm;
int fanTemp = 300; // Temp Fans turn on
int offTemp = 800; // Temp LEDs turn off

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;


// LED variables (Change to match your needs)
byte bluePins[] = {5, 3, 9}; // PWM pins for blues - if you plan to use the photo stagger, please place the pins in the order you would like them to start
byte whitePins[] = {10, 11, 6}; // PWM pins for whites - if you plan to use the photo stagger, please place the pins in the order you would like them to start

byte blueChannels = 3; // how many PWMs for blues (count from above)
byte whiteChannels = 3; // how many PWMs for whites (count from above)

int photoStagger = 10; // offset for east - west delay on each channel in minutes
int startOffset = 120; // offset for start times in minutes - used if you want to change the start and finish time of the cycle. i.e move it to a later time in the day
int colourOffset = 30; // offset for whites to start after blues start in minutes

byte blueLevel[] = {100, 100, 100}; // max intensity for Blue LED's %
byte whiteLevel[] = {85, 85, 85}; // max intensity for White LED's %

byte blueMin[] = {0, 0, 0}; // minimum intensity for Blue LED's %
byte whiteMin[] = {0, 0, 0}; // minimum intensity for White LED's %


// Month Data for Start, Stop, Photo Period and Fade (based off of actual times, best not to change)

int daysInMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //Days in each month

int minMinuteStart[12] = {310, 332, 348, 360, 372, 386, 394, 387, 364, 334, 307, 298}; //Minimum start times in each month
int maxMinuteStart[12] = {331, 347, 360, 372, 386, 394, 388, 365, 335, 308, 298, 309}; //Max start time in each month

int minMinuteFade[12] = {350, 342, 321, 291, 226, 173, 146, 110, 122, 139, 217, 282}; //Minimum fade time in each month
int maxMinuteFade[12] = {342, 321, 291, 226, 173, 146, 110, 122, 139, 217, 282, 350}; //Max fade time in each month

int minMinuteStop[12] = {1152, 1150, 1132, 1103, 1077, 1064, 1068, 1080, 1092, 1101, 1115, 1135}; //minimum stop times each month
int maxMinuteStop[12] = {1151, 1133, 1104, 1078, 1064, 1068, 1080, 1091, 1101, 1114, 1134, 1151}; //maximum stop times each month


// Weather variables

int weather = 1; // 0 off, 1 on

int clearDays[12] = {15, 12, 20, 23, 28, 37, 43, 48, 51, 41, 29, 23};
int cloudyDays[12] = {60, 61, 62, 60, 64, 63, 68, 66, 63, 54, 52, 53};


float clearDay = .8; // Max cloud value on clear day (percent of max string value)
float cloudyDay = .3; // Max cloud value on cloudy day (percent of max string value)
float normalDay = .5; // Max cloud value on normal day (percent of max string value)

byte value;
int day, fadeOn, fadeOff, time, pause, count, cloud;
long start, finish;


// Other variables - Do not need to be changed.

int minCounter; // counter that resets at midnight
long secCounter; // counter for seconds - needed for weather
int fadeDuration; // minutes to fade - calculated by map above
int ledStartMins; // minute to start led's - calculated by map above
int ledStopMins; // minute to stop led's - calculated by map above
byte blueOut[] = {0, 0, 0}; // used for invert of PWM
byte blueMinOut[] = {0, 0, 0};
byte whiteOut[] = {0, 0, 0}; // used for invert of PWM
byte whiteMinOut[] = {0, 0, 0};
int valueBlue[] = {0, 0, 0}; // value for clouds
int valueWhite[] = {0, 0, 0}; // value for clouds
int blueOI[] = {0, 0, 0}; // value for clouds
int whiteOI[] = {0, 0, 0}; // value for clouds

/****** LED Functions ******/
/***************************/

//function to set LED brightness according to time of day

byte setLed(
int mins, // current time in minutes
byte ledPin, // pin for this channel of LEDs
int start, // start time for this channel of LEDs
int fade, // fade duration for this channel of LEDs
int stop, // stop time for this channel of LEDs
byte ledMax, // max value for this channel of LEDs
byte ledMin, // minumum value for this channel of LEDs
long begin, // time cloud cycle begins in seconds
long secs, // current time in seconds
int on, // time for cloud to fade on in seconds
int off, // time for cloud to fade off in seconds
long time, // time of cloud
byte value, // value for cloud
int therm, // tempature
int offTemp // tempature shudown

// max value for this channel
) {
byte ledVal = 255;
if (mins <= start || mins >= stop) //this is when the LEDs are off, thus ledVal is 255;
{
ledVal = ledMin;
}
if (mins > start && mins <= start + fade) //this is sunrise
{
ledVal = map(mins, start, start + fade, ledMin, ledMax);
}
if (mins > start + fade && mins < stop - fade && weather == 1)
{
ledVal = ledMax;
if (count == 1){
if (secs >= begin && secs < begin + fadeOn)
{
ledVal = map(secs, begin, begin + on, ledMax, value);
}
if (secs >= begin + on && secs < begin + on + time)
{
ledVal = value;
}
if (secs >= begin + on + time && secs < begin + on + time + off)
{
ledVal = map(secs, begin + on + time, begin + on + time + off, value, ledMax);
}
if (secs >= begin + on + time + off)
{
ledVal = ledMax;
}
if (secs >= finish)
{
count = 0;
}
}
}
if (mins > start + fade && mins < stop - fade && weather == 0)
{
ledVal = ledMax;
}
if (mins < stop && mins >= stop - fade) //this is the sunset
{
ledVal = map(mins, stop - fade, stop, ledMax, ledMin);
}
if (therm >= 600)
{
ledVal = map(therm, 600, offTemp, ledMax, 255);
}
if (therm >= offTemp)
{
ledVal = 255;
}
analogWrite(ledPin, ledVal);
return ledVal;
}

/***** RTC Functions *******/
/***************************/
// 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) );
}

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

Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f);
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}

void setup() {

// init I2C
Serial.begin(9600);
// Display ON
Serial.print(0xfe, BYTE);
Serial.print(0x41, BYTE);
// Backlight ON
Serial.print(0xfe, BYTE);
Serial.print(0x52, BYTE);
// Home Cursor and Clear Screen
Serial.print(0xfe, BYTE);
Serial.print(0x51, BYTE);
// Underline Off
Serial.print(0xfe, BYTE);
Serial.print(0x48, BYTE);
Wire.begin();
randomSeed(analogRead(1));
}

/***** Main Loop ***********/
/***************************/
void loop(){
getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);

//minCounter = map(second, 1, 60, 350, 1110);
minCounter = rtcHrs * 60 + rtcMins;
secCounter = (long)minCounter * 60 + (long)second;

// Thermal

therm = analogRead(THERM_PIN)-238;

// Start and Stop Times, Fade Time Functions

ledStartMins = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteStart[month-1], maxMinuteStart[month-1]) + startOffset; //LED Start time
fadeDuration = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteFade[month-1], maxMinuteFade[month-1]); //LED Fade time
ledStopMins = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteStop[month-1], maxMinuteStop[month-1]) + startOffset; // LED Stop time

// Weather Functions

if (minCounter == 0 && second == 0 || day == 0){
{
day = random(1,101);
}
}
if (count == 0){
if (day < clearDays[month-1]) // Clear Day
{
int t;
for (t = 0; t < blueChannels; t++)
{
valueBlue[t] = random(clearDay*blueLevel[t],blueLevel[t]);
}
for (t = 0; t < whiteChannels; t++)
{
valueWhite[t] = random(clearDay*whiteLevel[t],whiteLevel[t]);
}
}
if (day >= clearDays[month-1] && day <= cloudyDays[month-1]) // Cloudy Day
{
int t;
for (t = 0; t < blueChannels; t++)
{
valueBlue[t] = random(cloudyDay*blueLevel[t],normalDay*blueLevel[t]);
}
for (t = 0; t < whiteChannels; t++)
{
valueWhite[t] = random(cloudyDay*whiteLevel[t],normalDay*whiteLevel[t]);
}
}
if (day > cloudyDays[month-1]) // Normal Day
{
int t;
for (t = 0; t < blueChannels; t++)
{
valueBlue[t] = random(normalDay*blueLevel[t],blueLevel[t]);
}
for (t = 0; t < whiteChannels; t++)
{
valueWhite[t] = random(normalDay*whiteLevel[t],whiteLevel[t]);
}
}

fadeOn = random(1,5); // Fade on of cloud in seconds
fadeOff = random(1,5); // Fade off of cloud in seconds
time = random(30,1200); // Length of cloud in seconds
pause = random(5,1200); // Time between clouds in seconds
start = secCounter; // Sets cycle start time
finish = start + fadeOn + time + fadeOff + pause; // Sets cylce finish time in seconds
count = 1;
}


// Invert PWM signal

int t;
for (t = 0; t < blueChannels; t++)
{
blueOut[t] = map(blueLevel[t], 0, 100, 218, 0);
}
for (t = 0; t < blueChannels; t++)
{
blueMinOut[t] = map(blueMin[t], 0, 100, 218, 0);
}
for (t = 0; t < whiteChannels; t++)
{
whiteOut[t] = map(whiteLevel[t], 0, 100, 218, 0);
}
for (t = 0; t < whiteChannels; t++)
{
whiteMinOut[t] = map(whiteMin[t], 0, 100, 218, 0);
}
for (t = 0; t < blueChannels; t++)
{
blueOI[t] = map(valueBlue[t], 0, 100, 218, 0);
}
for (t = 0; t < whiteChannels; t++)
{
whiteOI[t] = map(valueWhite[t], 0, 100, 218, 0);
}

// LED State and Serial Print
if (psecond != second){
psecond = second;
// set LED states
Serial.print(0xfe, BYTE);
Serial.print(0x45, BYTE);
Serial.print(0x02, BYTE);
Serial.print(0x01, BYTE);
if(dayOfMonth < 10)
Serial.print("0");
Serial.print(dayOfMonth,DEC);
Serial.print("/");
if(month < 10)
Serial.print("0");
Serial.print(month,DEC);
Serial.print("/");
Serial.println(year,DEC);
Serial.print(" - ");
if(rtcHrs < 10)
Serial.print("0");
Serial.print(rtcHrs,DEC);
Serial.print(":");
if(rtcMins < 10)
Serial.print("0");
Serial.print(rtcMins,DEC);
Serial.print(":");
if(second < 10)
Serial.print("0");
Serial.println(second,DEC);
// Cursor to column 1, line 2
Serial.print(0xfe, BYTE);
Serial.print(0x45, BYTE);
Serial.print(0x03, BYTE);
Serial.print(0x02, BYTE);
Serial.print(therm / 10.,1);
Serial.println(" C");
Serial.print(" - ");
if (day < clearDays[month-1]){
Serial.println("Clear");}
if (day >= clearDays[month-1] && day <= cloudyDays[month-1]){
Serial.println("Cloudy");}
if (day > cloudyDays[month-1]){
Serial.println("Normal");}
update_leds();
}
delay(50);
}


void update_leds( void ){
int i;
byte ledVal;
Serial.print(0xfe, BYTE);
Serial.print(0x45, BYTE);
Serial.print(0x01, BYTE);
Serial.print(0x03, BYTE);
Serial.println("Blue ");
for (i = 0; i < blueChannels; i++){
ledVal = setLed(minCounter, bluePins, ledStartMins - (photoStagger * (i+1)), fadeDuration, ledStopMins + 30 + (photoStagger * (map(i+1, 1, blueChannels, blueChannels, 1))), blueOut, blueMinOut, start, secCounter, fadeOn, fadeOff, time, blueOI, therm, offTemp);
if(i <= blueChannels)
Serial.print(map(ledVal, 0, 255, 100, 0));
Serial.println("% ");
}
Serial.print(0xfe, BYTE);
Serial.print(0x45, BYTE);
Serial.print(0x01, BYTE);
Serial.print(0x04, BYTE);
Serial.println("White ");
for (i = 0; i < whiteChannels; i++){
ledVal = setLed(minCounter, whitePins, ledStartMins + colourOffset + (photoStagger * (i+1)), fadeDuration, ledStopMins - colourOffset - (photoStagger * (map(i+1, 1, whiteChannels, whiteChannels, 1))), whiteOut, whiteMinOut, start, secCounter, fadeOn, fadeOff, time, whiteOI, therm, offTemp);
if(i <= whiteChannels)
Serial.print(map(ledVal, 0, 255, 100, 0));
Serial.println("% ");
}
}
 
Weasel, do you have a RTC (Real Time Clock)? What kind of drivers are you using for your strings? If your new to coding I would start with something simple and work my way up to the code you posted above. Also when posting code us the code brackets (the # button in advanced).
 
Added IR Remote control to the simple version of the Reef LED controller. Got the IR Remote and receiver from Adafruit for $7.00 and was able to remove the potentiometers and the override switch. Now everything is controlled with the remote. I used the IR Library & Decoder from instructables.com http://www.instructables.com/id/The-Easiest-Way-to-Use-Any-IR-Remote-with-Ardiuno/?ALLSTEPS
I'm also using pins A2 & A3 to power the RTC. That way you can push the RTC right into the header PINS on an UNO for prototyping. I'm using a pro-mini as the final board to run the fixture. I'll post a couple pictures next. It's a small fixture but great for working with to get this thing figured out, and all the electronics can fit in the top section, eliminating the external box I was using before (post #523).

Here is the modified code that is working fine, but any suggestions are welcome. I use BuckPucks so code is inverted (255 = Off).

Code:
/*
 Arduino LED controller for reef aquariums

// paramterized LED lighting control for reef aquariums
// use a DS1307 RTC to kick off lighting schedules
// fade up on a given slope, delay a set amount, fade back down
// IR Commands set max channel levels with a master override command.

//  Circuit
// 
// PWM pins described below connected to dimming circuits on drivers 255 = Off
// grounds from drivers connected to arduino ground
// DS1307 RTC connected via I2C - SDA connected to A4, SCL connected to A5
*/

// Pins to control LEDs. Change these if you're using different pins.

const int receiver = 11; // pin 1 of IR receiver to Arduino pin 11
int RTCvcc = A3;   //Power for the RTC - Connect to VCC on RTC
int RTCneg = A2;   //Negative for the RTC - Connect to GND on RTC
int irSwitch = 13; //Mode indicator - RTC Override command

int whiteLed = 5;   // LED PWM channel for whites
int blueLed = 6;    // LED PWM channel for blues
int uvLed = 9;      // LED PWM channel for Ultra Violets
int moonLed = 10;   // LED PWM channel for Moonlights

int lastCounterW;     //keeps track of last value for IR
int lastCounterB;
int lastCounterU;
int lastCounterM;

int whiteMax;       //Max level of string set by the IR Remote
int blueMax;
int uvMax;
int moonMax;


// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
#include <IRremote.h> // use the library for IR

IRrecv irrecv(receiver); // create instance of 'irrecv'
 
decode_results results;

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;

// Other variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight. Don't change this.

int blueStartMins = 390;    // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int whiteStartMins = 420;   // minute to start whites. Same as above.
int uvStartMins = 405;      // minute to start ultra violet. Same as above.
int moonStartMins = 1200;   // minute to start moon lights. Same as above.

int bluePhotoPeriod = 840;  // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int whitePhotoPeriod = 720; // photoperiod in minutes, whites. Same as above.
int uvPhotoPeriod = 840;    // photoperiod in minutes, ultra violets. Same as above.
int moonPhotoPeriod = 660;  // photoperiod in minutes, moon lights. Same as above.
int fadeDuration = 120;     // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.


/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
void setLed(int mins,    // current time in minutes
            int ledPin,  // pin for this channel of LEDs
            int start,   // start time for this channel of LEDs
            int period,  // photoperiod for this channel of LEDs
            int fade,    // fade duration for this channel of LEDs
            int ledMax   // max value for this channel
            )  {
   if (mins <= start || mins > start + period)  { 
    analogWrite(ledPin, 255); 
  } 
  if (mins > start && mins <= start + fade)  { 
    analogWrite(ledPin, map(mins - start, 0, fade, 255, ledMax)); 
  } 
    if (mins > start + fade && mins <= start + period - fade)  { 
    analogWrite(ledPin, ledMax); 
  } 
    if (mins > start + period - fade && mins <= start + period)  { 
    analogWrite(ledPin, map(mins - start - period + fade, 0, fade, ledMax, 255)); 
  }
}

/***** RTC Functions *******/
/***************************/
// 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.write(0);
   Wire.write(decToBcd(second));
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(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)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

boolean LEDon = true; // initializing LEDon as true

void setup()  { 
  
  Wire.begin();
  pinMode(RTCvcc, OUTPUT); 
  pinMode(RTCneg, OUTPUT);
  pinMode(irSwitch, OUTPUT);
  digitalWrite(RTCvcc, HIGH);
  digitalWrite(RTCneg, LOW);
  irrecv.enableIRIn();
//  Serial.begin(9600);     //Uncomment to check values below
} 

/***** Main Loop ***********/
/***************************/
void loop()  
{ 
  // get time from RTC and put in hrs and mins variables
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);
  minCounter = rtcHrs * 60 + rtcMins;

  whiteMax = lastCounterW;
  blueMax = lastCounterB;  
  uvMax = lastCounterU;
  moonMax = lastCounterM; 
 { 
  if (irrecv.decode(&results))
  {
    if (results.value == 16615543){
      whiteMax = (whiteMax + (255/15));
      }
       
    if (results.value == 16582903){
      whiteMax = (whiteMax - (255/15));
      }
       
    if (results.value == 16623703){
      blueMax = (blueMax + (255/15));
      }
       
    if (results.value == 16591063){
      blueMax = (blueMax - (255/15));
      }
    if (results.value == 16619623){
      uvMax = (uvMax + (255/15));
      }
       
    if (results.value == 16586983){
      uvMax = (uvMax - (255/15));
      }      
    if (results.value == 16607383){
      moonMax = (moonMax + (255/15));
      }
       
    if (results.value == 16599223){
      moonMax = (moonMax - (255/15));
      }
   
 if (results.value == 16605343)  // change zero to your IR remote button number
     {
       if (LEDon == true)        // is LEDon equal to true? 
         {
           LEDon = false;             
         }
         
        else
          {
            LEDon = true;         
          }
     }
        
      irrecv.resume();  
  }
    
    if (whiteMax > 255){
    whiteMax = 255;
      }
   
    if (whiteMax < 17){
    whiteMax = 0;
      }
  
    if (blueMax > 255){
    blueMax = 255;
      }
   
    if (blueMax < 17){
    blueMax = 0;
      }
      
    if (uvMax > 255){
    uvMax = 255;
      }
   
    if (uvMax < 17){
    uvMax = 0;
      }    
      if (moonMax > 255){
    moonMax = 255;
      }
   
    if (moonMax < 17){
    moonMax = 0;
    }
}
  lastCounterW = whiteMax;         //remember Max Value setting
  lastCounterB = blueMax;          //
  lastCounterU = uvMax;            //
  lastCounterM = moonMax;          // 
   
      
//Serial.println(" blueMax");     //Uncomment to check the Max levels
//Serial.print(blueMax);          //applies to above
//Serial.println(" LEDon");       //Uncomment to check boolean state
//Serial.print(LEDon);            //applies to above
//Serial.println(" minCounter");  //Uncomment to check minute counter
//Serial.print(minCounter);       //applies to above

 if (psecond != second){ 
    psecond = second;}    


       if (LEDon == false)   // is LEDon equal to true? 
         {   
     analogWrite(whiteLed, whiteMax);
     analogWrite(blueLed, blueMax);
     analogWrite(uvLed, uvMax);
     analogWrite(moonLed, moonMax);
     digitalWrite(irSwitch, HIGH);   // Led Mode indicator for manual override, optional
         }
         
        else 
          {
     setLed(minCounter, whiteLed, whiteStartMins, whitePhotoPeriod, fadeDuration, whiteMax);
     setLed(minCounter, blueLed, blueStartMins, bluePhotoPeriod, fadeDuration, blueMax);
     setLed(minCounter, uvLed, uvStartMins, uvPhotoPeriod, fadeDuration, uvMax);
     setLed(minCounter, moonLed, moonStartMins, moonPhotoPeriod, fadeDuration, moonMax);
     digitalWrite(irSwitch, LOW);  // Led Mode indicator for manual override, optional
          }
     
    
   delay(50);
  }
 
Here are a couple pics
paru3aze.jpg

I'm using it over a Pico so I don't need a bunch of LEDs
a6yqery7.jpg

Power Jack is the only connection.
yjumu9en.jpg
 
Last edited:
seems like a lot of people on this thread know a lot about led's and arduino Here is my question.
I want to set up a remote feeding station. I plan on using a solar panel 12v @3 amp to run a arduino mega (just because I have one extra) and RTC and a 12v 1A or less motor not a servo I plan on uploading a sketch that will be stored in the Eeprom chip and the RTC will be attached to the arduino and have its own battery to keep time. The idea for the sketch is one with just 4 on and off settings that can be set to repeat the 4 feeding times everyday. Each feeding time would need to be controlled to the second. buy controlling the motor I was thinking using a single pin and attach a 5v relay to be triggered buy the pin, so the motor will be run directly from the solar panel the on and off settings would only need to run when the sun is up. I was hoping to not have to use a batter to keep cost and weight down. and if every thing is running off the solar panels only during day light hours then the solar panel should handel it all if not I can add to the panel for more power.

Any one ever do this type of build??

and could some please write the sketch or point me to one I have no programming skill
 
seems like a lot of people on this thread know a lot about led's and arduino Here is my question.
I want to set up a remote feeding station. I plan on using a solar panel 12v @3 amp to run a arduino mega (just because I have one extra) and RTC and a 12v 1A or less motor not a servo I plan on uploading a sketch that will be stored in the Eeprom chip and the RTC will be attached to the arduino and have its own battery to keep time. The idea for the sketch is one with just 4 on and off settings that can be set to repeat the 4 feeding times everyday. Each feeding time would need to be controlled to the second. buy controlling the motor I was thinking using a single pin and attach a 5v relay to be triggered buy the pin, so the motor will be run directly from the solar panel the on and off settings would only need to run when the sun is up. I was hoping to not have to use a batter to keep cost and weight down. and if every thing is running off the solar panels only during day light hours then the solar panel should handel it all if not I can add to the panel for more power.

Any one ever do this type of build??

and could some please write the sketch or point me to one I have no programming skill

here is a great place to start learning how to do coding and building
http://arduino.cc/en/Tutorial/HomePage
 
seems like a lot of people on this thread know a lot about led's and arduino Here is my question.
I want to set up a remote feeding station. I plan on using a solar panel 12v @3 amp to run a arduino mega (just because I have one extra) and RTC and a 12v 1A or less motor not a servo I plan on uploading a sketch that will be stored in the Eeprom chip and the RTC will be attached to the arduino and have its own battery to keep time. The idea for the sketch is one with just 4 on and off settings that can be set to repeat the 4 feeding times everyday. Each feeding time would need to be controlled to the second. buy controlling the motor I was thinking using a single pin and attach a 5v relay to be triggered buy the pin, so the motor will be run directly from the solar panel the on and off settings would only need to run when the sun is up. I was hoping to not have to use a batter to keep cost and weight down. and if every thing is running off the solar panels only during day light hours then the solar panel should handel it all if not I can add to the panel for more power.

Any one ever do this type of build??

and could some please write the sketch or point me to one I have no programming skill

Doing only 4 things throughout the day you don't really need the clock even if you want the feeding cycle to start with the lights coming on and then just time things out using a "delay"........ Why do you need such precision for feeding? If coordinating with other events that could be done via input pins and save the need for the RTC and battery.....
 
Back
Top