Natural Reef Aquarium Lighting Controller

In theory you should be able to do something like the following;

PHP:
// Auxilery Pins 

byte auxPins[] = { 1, 1, 1, 1, 2, 2, 2, 2}; 

byte auxChannels = 8; 

int auxStart[] = { 510, 540, 680, 750, 512, 542, 682, 752}; 
int auxStop[] = { 512, 542, 682, 752, 514, 544, 684, 754};

Above would run the 2 channels at different minutes of the day. You could do it for as many channels as you like.

haven't test run anything but there is no reason it shouldn't work.
 
Below is a revision to display the current moon cycle on an LED screen. You can also define a time period that the moon channels will be set to its low value.

PHP:
// Natural Reef Aquarium Lighting V2.7.3 
// 9/04/2014 
// 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; 
// Additon of off/on times for the moon light to allow total darkenss
// Addition of Moon information to LCD printout
// 
// 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; 

// Minute Counter 
int minCounter;  // Time counter in minutes 

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

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

byte BluePWMHigh[] = { 255, 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, 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, 25 };          // Value in degrees (sun angle) that each Blue string will be at max output (Larger = more sunlight) 
byte WhitePWMHigh[] = { 255, 255 };        // 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 (Larger = more sunlight) 
byte UVPWMHigh[] = { 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 };               // Low value for UV PWM - if your values are noraml this is 0, if your values are inverted this is 255 
float UVFull[] = { 30 };              // Value in degrees (sun angle) that each UV string will be at max output (Larger = more sunlight) 
byte MoonPWMHigh[] = { 255 };             // 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 

// Auxilery Pins 

byte auxPins[] = { 4, 8, 12 }; 

byte auxChannels = 3; 

int auxStart[] = { 510, 540, 480 }; 
int auxStop[] = { 1230, 1140, 1200 }; 
   
// Set for the location of the world you want to replicate.
 
float latitude = -19.770621;   // + to N  Defualt - (-19.770621) Heart Reef, Great Barrier Reef, QLD, Australia  
float longitude = 149.238532;  // + to E  Defualt - (149.238532) 
int TimeZone = 10;             // + to E  Defulat - (10) 

// Sunlight Variables 

int delayTime = 0;     // start time delay in minutes,  - will push the day back, + will bring the day forward 

// Moon Variables

float moon;  // Moon cylce value

int moonOff = 225;  // off time for moon light in minutes (If you do not want to use this feature please set the value to -1)
int moonOn = 840; // on time for moon light in minutes (If you do not want to use this feature please set the value to -1)

// Float map

float floatMap(float x, float in_min, float in_max, int out_min, int out_max) 
{ 
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 
} 

// Main Sun Cycle

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.0 - _month) / 12.0); 
    float y = _year + 4800.0 - a; 
    float m = _month + (12.0 * a) - 3.0; 
    float AH; 
    int result; 

    float 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.0); 

    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.0)*(1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(((2.0 * GMAS) * M_PI) / 180.0) * (0.019993 - 0.000101 * JC) + sin(((3.0 * JC) * M_PI) / 180.0) * 0.000289; 

    float STL = GMLS + SEoC; 

    float STA = GMAS + SEoC; 

    float SRV = (1.000001018 * (1.0 - EEO * EEO)) / (1.0 + EEO * cos((STA * M_PI) / 180.0)); 

    float SAL = STL - 0.00569 - 0.00478 * sin(((125.04 - 1934.136 * JC) * M_PI) / 180.0); 

    float MOE = 23.0 + (26.0 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60.0) / 60.0; 

    float OC = MOE + 0.00256 * cos(((215.04 - 1934.136 * JC) * M_PI) / 180.0); 

    float SD = (asin(sin((OC * M_PI) / 180.0) * sin((SAL * M_PI) / 180.0))) * (180.0 / M_PI); 

    float vy = tan(((OC / 2.0) * M_PI) / 180.0) * tan(((OC / 2.0) * M_PI) / 180.0); 

    float EQoT = (4.0 * (vy * (sin(2.0 * ((GMLS * M_PI) / 180.0)) - 2.0 * EEO * sin((GMAS * M_PI) / 180.0) + 4.0 * EEO * vy * sin((GMAS * M_PI) / 180.0) * cos(2.0 * ((GMLS * M_PI) / 180.0)) - 0.5 * vy * vy * sin(4.0 * ((GMLS * M_PI) / 180.0)) - 1.25 * EEO * EEO * sin(2 * ((GMAS * M_PI) / 180))))) * (180 / M_PI); 

    float HAS = acos(cos((90.833 * M_PI) / 180.0) / (cos((latitude * M_PI) / 180.0) * cos((SD * M_PI) / 180.0)) - tan((latitude * M_PI) / 180.0) * tan((SD * M_PI) / 180.0)) * (180.0 / M_PI); 

    float SN = (720.0 - 4.0 * longitude - EQoT + TimeZone * 60.0); 

    float SR = SN - HAS * 4.0; 

    float SS = SN + HAS * 4.0; 

    float STD = 8.0 * HAS; 

    float TST = fmod((((_hour)+(_min / 60.0) + (_sec / 3600.0)) / 24.0) * 1440.0 + EQoT + 4.0 * longitude - 60.0 * TimeZone, 1440.0) + delayTime; 

    if (TST / 4 < 0.0) 
    { 
        AH = ((TST / 4.0) + 180.0); 
    } 
    else 
    { 
        AH = ((TST / 4.0) - 180.0); 
    } 

    float SZA = (acos(sin((latitude * M_PI) / 180.0) * sin((SD * M_PI) / 180.0) + cos((latitude * M_PI) / 180.0) * cos((SD * M_PI) / 180.0) * cos((AH * M_PI) / 180.0))) * (180.0 / M_PI); 

    float SEA = 90.0 - SZA; 

    if (SEA <= 0.0) 
    { 
        result = _ledLow; 
    } 

    if (SEA > 0.0 && SEA < _fullSun) 
    { 
        result = map(SEA, 0, _fullSun, _ledLow, _ledHigh); 
    } 

    if (SEA >= _fullSun) 
    { 
        result = _ledHigh; 
    } 

    analogWrite(_ledPin, result); 
    return result; 

} 

// Main Moon Cycle

int MoonLight(byte _ledPin, byte _ledHigh, byte _ledLow, byte _year, byte _month, byte _day, byte _hour, byte _min, byte _sec) 
{ 
    int result; 

    float a = floor((14.0 - _month) / 12.0); 
    float y = _year + 4800.0 - a; 
    float m = _month + (12.0 * a) - 3.0;  
    float mJDN = ((_day  + ((153.0 * m + 2.0) / 5.0) + (365.0 * y) + (y / 4.0) - ( y / 100.0) + (y / 400.0) - 32045.0) + 730483.71); 
    float mJDR = (_hour / 24.0) + (_min / 1444.0) + (_sec / 86400.0); 
    float mJD = mJDN + mJDR;      
    moon = fmod((mJD - 2456318.69458333), 29.530589);
	if (minCounter > moonOff && minCounter < moonOn)
	{
		result = _ledLow;
	}
	else
	{
		if (moon <= 14.7652945) 
		{ 
			result = floatMap(moon, 0.0, 14.7652945, _ledHigh, _ledLow); 
		} 
		if (moon >= 14.7652946) 
		{ 
			result = floatMap(moon, 14.7652946, 29.530589, _ledLow, _ledHigh); 
		} 
	}
    analogWrite(_ledPin, result); 
    return result; 
} 

// Main Aux Pin Cycle

int AuxUpdate (byte _pin, int _mins, int _start, int _stop) 
{ 
  byte auxVal; 
  if (_mins < _start || _mins > _stop) 
  { 
    auxVal = LOW; 
  } 
  if (_mins >= _start && _mins <= _stop) 
  { 
    auxVal = HIGH; 
  } 
 digitalWrite(_pin, auxVal); 
 return auxVal; 
}  

/***** 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); 
        for (int i = 0; i < auxChannels; i++) 
        { 
          pinMode(auxPins[i], OUTPUT); 
        } 
    Serial.begin(9600); 
    Wire.begin(); 
} 

void loop() { 
        minCounter = rtcHrs * 60 + rtcMins;  
    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_aux(); 
        update_leds(); 
    } 
} 

void update_leds(){ 
    if (blueChannels > 0){ 
        Serial.println("Blue LED's"); 
        for (int i = 0; i < blueChannels; i++) 
        { 
            byte 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(); 
    } 
    if (whiteChannels > 0){ 
        Serial.println("White LED's"); 
        for (int i = 0; i < whiteChannels; i++) 
        { 
            byte 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(); 
    } 
    if (uvChannels > 0){ 
        Serial.println("UV LED's"); 
        for (int i = 0; i < uvChannels; i++) 
        { 
            byte 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(); 
    } 

    if (moonChannels > 0){ 
        Serial.println("Moon Value"); 
        for (int i = 0; i < moonChannels; i++) 
        { 
            byte value = MoonLight(moonPins[i], MoonPWMHigh[i], MoonPWMLow[i], year, month, dayOfMonth, rtcHrs, rtcMins, second); 
			if (moon >= 0 && moon < 1.845662)
			{
				Serial.print("New Moon - ");
			}
			if (moon >= 1.845662 && moon < 5.536985)
			{
				Serial.print("Waxing Crescent - ");
			}
			if (moon >= 5.536985 && moon < 9.228309)
			{
				Serial.print("First Quarter - ");
			}
			if (moon >= 9.228309 && moon < 12.91963)
			{
				Serial.print("Waxing Gibbous - ");
			}
			if (moon >= 12.91963 && moon < 16.61096)
			{
				Serial.print("Full Moon");
			}
			if (moon >= 16.61096 && moon < 20.30228)
			{
				Serial.print("Waning Gibbous - ");
			}
			if (moon >= 20.30228 && moon < 23.9936)
			{
				Serial.print("Third Quarter - ");
			}
			if (moon >= 23.9936 && moon < 27.68493)
			{
				Serial.print("Waning Crescent - ");
			}
			if (moon >= 27.68493)
			{
				Serial.print("New Moon - ");
			}
			Serial.print(map(value, MoonPWMLow[i], MoonPWMHigh[i], 0, 100)); 
			Serial.print("% "); 
        } 
        Serial.println(); 
    } 
} 

void update_aux(){ 
  Serial.print(minCounter); 
  Serial.println(); 
  for (int i = 0; i < auxChannels; i++) 
  { 
    byte value = AuxUpdate(auxPins[i], minCounter, auxStart[i], auxStop[i]); 
    Serial.print("Pin "); 
    Serial.print(auxPins[i]); 
    Serial.print(" Value "); 
    Serial.print(value); 
    Serial.println(); 
  } 
 }

Please let me know if you encounter any issues with this code.

Cheers,
 
I have made a few corrections to this code, please let me know if you have any issues.

PHP:
// Natural Reef Aquarium Lighting V2.7.3  
// 23/04/2014  
// 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;  
// Additon of off/on times for the moon light to allow total darkenss 
// Addition of Moon information to LCD printout 
//  
// 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, pminute;  

// Minute Counter  
int minCounter;  // Time counter in minutes  

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

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

byte BluePWMHigh[] = { 255, 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, 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, 25 };          // Value in degrees (sun angle) that each Blue string will be at max output (Larger = more sunlight)  
byte WhitePWMHigh[] = { 255, 255 };        // 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 (Larger = more sunlight)  
byte UVPWMHigh[] = { 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 };               // Low value for UV PWM - if your values are noraml this is 0, if your values are inverted this is 255  
float UVFull[] = { 30 };              // Value in degrees (sun angle) that each UV string will be at max output (Larger = more sunlight)  
byte MoonPWMHigh[] = { 255 };             // 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  

// Auxilery Pins  

byte auxPins[] = { 4, 8, 12 };  

byte auxChannels = 3;  

int auxStart[] = { 510, 540, 480 };  
int auxStop[] = { 1230, 1140, 1200 };  
    
// Set for the location of the world you want to replicate. 
  
float latitude = -19.770621;   // + to N  Defualt - (-19.770621) Heart Reef, Great Barrier Reef, QLD, Australia   
float longitude = 149.238532;  // + to E  Defualt - (149.238532)  
int TimeZone = 10;             // + to E  Defulat - (10)  

// Sunlight Variables  

int delayTime = 0;     // start time delay in minutes,  - will push the day back, + will bring the day forward  

// Moon Variables 

//float moon;  // Moon cylce value 

int moonOff = 1225;  // off time for moon light in minutes (If you do not want to use this feature please set the value to -1) 
int moonOn = 1281; // on time for moon light in minutes (If you do not want to use this feature please set the value to -1) 

// Float map 

float floatMap(float x, float in_min, float in_max, int out_min, int out_max)  
{  
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;  
}  

// Main Sun Cycle 

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.0 - _month) / 12.0);  
    float y = _year + 4800.0 - a;  
    float m = _month + (12.0 * a) - 3.0;  
    float AH;  
    int result;  

    float 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.0);  

    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.0)*(1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(((2.0 * GMAS) * M_PI) / 180.0) * (0.019993 - 0.000101 * JC) + sin(((3.0 * JC) * M_PI) / 180.0) * 0.000289;  

    float STL = GMLS + SEoC;  

    float STA = GMAS + SEoC;  

    float SRV = (1.000001018 * (1.0 - EEO * EEO)) / (1.0 + EEO * cos((STA * M_PI) / 180.0));  

    float SAL = STL - 0.00569 - 0.00478 * sin(((125.04 - 1934.136 * JC) * M_PI) / 180.0);  

    float MOE = 23.0 + (26.0 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60.0) / 60.0;  

    float OC = MOE + 0.00256 * cos(((215.04 - 1934.136 * JC) * M_PI) / 180.0);  

    float SD = (asin(sin((OC * M_PI) / 180.0) * sin((SAL * M_PI) / 180.0))) * (180.0 / M_PI);  

    float vy = tan(((OC / 2.0) * M_PI) / 180.0) * tan(((OC / 2.0) * M_PI) / 180.0);  

    float EQoT = (4.0 * (vy * (sin(2.0 * ((GMLS * M_PI) / 180.0)) - 2.0 * EEO * sin((GMAS * M_PI) / 180.0) + 4.0 * EEO * vy * sin((GMAS * M_PI) / 180.0) * cos(2.0 * ((GMLS * M_PI) / 180.0)) - 0.5 * vy * vy * sin(4.0 * ((GMLS * M_PI) / 180.0)) - 1.25 * EEO * EEO * sin(2 * ((GMAS * M_PI) / 180))))) * (180 / M_PI);  

    float HAS = acos(cos((90.833 * M_PI) / 180.0) / (cos((latitude * M_PI) / 180.0) * cos((SD * M_PI) / 180.0)) - tan((latitude * M_PI) / 180.0) * tan((SD * M_PI) / 180.0)) * (180.0 / M_PI);  

    float SN = (720.0 - 4.0 * longitude - EQoT + TimeZone * 60.0);  

    float SR = SN - HAS * 4.0;  

    float SS = SN + HAS * 4.0;  

    float STD = 8.0 * HAS;  

    float TST = fmod((((_hour)+(_min / 60.0) + (_sec / 3600.0)) / 24.0) * 1440.0 + EQoT + 4.0 * longitude - 60.0 * TimeZone, 1440.0) + delayTime;  

    if (TST / 4 < 0.0)  
    {  
        AH = ((TST / 4.0) + 180.0);  
    }  
    else  
    {  
        AH = ((TST / 4.0) - 180.0);  
    }  

    float SZA = (acos(sin((latitude * M_PI) / 180.0) * sin((SD * M_PI) / 180.0) + cos((latitude * M_PI) / 180.0) * cos((SD * M_PI) / 180.0) * cos((AH * M_PI) / 180.0))) * (180.0 / M_PI);  

    float SEA = 90.0 - SZA;  

    if (SEA <= 0.0)  
    {  
        result = _ledLow;  
    }  

    if (SEA > 0.0 && SEA < _fullSun)  
    {  
        result = map(SEA, 0, _fullSun, _ledLow, _ledHigh);  
    }  

    if (SEA >= _fullSun)  
    {  
        result = _ledHigh;  
    }  

    analogWrite(_ledPin, result);  
    return result;  

}  

// Main Moon Cycle 

int MoonLight(byte _ledPin, byte _ledHigh, byte _ledLow, byte _year, byte _month, byte _day, byte _hour, byte _min)  
{  
    int result;  

    float a = floor((14.0 - _month) / 12.0);  
    float y = _year + 4800.0 - a;  
    float m = _month + (12.0 * a) - 3.0;   
    float mJDN = ((_day  + ((153.0 * m + 2.0) / 5.0) + (365.0 * y) + (y / 4.0) - ( y / 100.0) + (y / 400.0) - 32045.0) + 730483.71);  
    float mJDR = (_hour / 24.0) + (_min / 1444.0);  
    float mJD = mJDN + mJDR;       
    float moon = fmod((mJD - 2456318.69458333), 29.530589); 
    if (minCounter > moonOff && minCounter < moonOn) 
    { 
        result = _ledLow;
        moon = -1.0;
    } 
    else 
    { 
        if (moon <= 14.7652945)  
        {  
            result = floatMap(moon, 0.0, 14.7652945, _ledHigh, _ledLow);  
        }  
        if (moon >= 14.7652946)  
        {  
            result = floatMap(moon, 14.7652946, 29.530589, _ledLow, _ledHigh);  
        }  
    } 
    analogWrite(_ledPin, result);
    Serial.print(result);
    Serial.println();
            if (moon >= 0.0 && moon < 3.691324) 
            { 
                Serial.print("Full Moon - "); 
            } 
            if (moon >= 3.691324 && moon < 7.382647) 
            { 
                Serial.print("Waning Gibbous - "); 
            } 
            if (moon >= 7.382647 && moon < 11.07397) 
            { 
                Serial.print("Third Quarter - "); 
            } 
            if (moon >= 11.07397 && moon < 14.76529) 
            { 
                Serial.print("Waning Crescent - "); 
            } 
            if (moon >= 14.76529 && moon < 18.45662) 
            { 
                Serial.print("New Moon"); 
            } 
            if (moon >= 18.45662 && moon < 22.14794) 
            { 
                Serial.print("Waxing Crescent - "); 
            } 
            if (moon >= 22.14794 && moon < 25.83927) 
            { 
                Serial.print("First Quarter - "); 
            } 
            if (moon >= 29.83927 && moon < 29.53059) 
            { 
                Serial.print("Waxing Gibbous - "); 
            } 
            if (moon >= 29.53059) 
            { 
                Serial.print("Full Moon - "); 
            }
            if (moon < 0)
            {
              Serial.print("Moon Off - ");
            }
    
    return result;  
}  

// Main Aux Pin Cycle 

int AuxUpdate (byte _pin, int _mins, int _start, int _stop)  
{  
  byte auxVal;  
  if (_mins < _start || _mins > _stop)  
  {  
    auxVal = LOW;  
  }  
  if (_mins >= _start && _mins <= _stop)  
  {  
    auxVal = HIGH;  
  }  
 digitalWrite(_pin, auxVal);  
 return auxVal;  
}   

/***** 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);  
        for (int i = 0; i < auxChannels; i++)  
        {  
          pinMode(auxPins[i], OUTPUT);  
        }  
    Serial.begin(9600);  
    Wire.begin();  
}  

void loop() {  
        minCounter = rtcHrs * 60 + rtcMins;   
    getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);  
    if (psecond != second){  
        psecond = second;
        if(rtcHrs <= 9)
        {
        Serial.print("0");
        Serial.print(rtcHrs);  
        Serial.print(":"); 
        }
        else
        {
        Serial.print(rtcHrs);  
        Serial.print(":");
        }   
        if(rtcMins <= 9)
        {
        Serial.print("0");
        Serial.print(rtcMins);  
        Serial.print(":"); 
        }
        else
        {
        Serial.print(rtcMins);  
        Serial.print(":");
        }   
        if(second <= 9)
        {
        Serial.print("0");
        Serial.print(second);  
        Serial.print(" "); 
        }
        else
        {
        Serial.print(second);  
        Serial.print(" ");
        }   
        Serial.print(dayOfMonth);  
        Serial.print("/");  
        Serial.print(month);  
        Serial.print("/");  
        Serial.println(year);
    }
    if (pminute != rtcMins)
  {
        pminute = rtcMins;  
        update_aux();  
        update_leds();
        update_moon();  
    }  
}  

void update_leds(){  
    if (blueChannels > 0){  
        Serial.println("Blue LED's");  
        for (int i = 0; i < blueChannels; i++)  
        {  
            byte 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();  
    }  
    if (whiteChannels > 0){  
        Serial.println("White LED's");  
        for (int i = 0; i < whiteChannels; i++)  
        {  
            byte 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();  
    }  
    if (uvChannels > 0){  
        Serial.println("UV LED's");  
        for (int i = 0; i < uvChannels; i++)  
        {  
            byte 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();  
    }  
}
void update_moon(){
    if (moonChannels > 0){  
        Serial.println("Moon Value");  
        for (int i = 0; i < moonChannels; i++)  
        {  
            byte value = MoonLight(moonPins[i], MoonPWMHigh[i], MoonPWMLow[i], year, month, dayOfMonth, rtcHrs, rtcMins);   
            Serial.print(floatMap(value, MoonPWMLow[i], MoonPWMHigh[i], 0.0, 100.0));  
            Serial.print("% ");  
        }  
        Serial.println();  
    }  
}  

void update_aux(){  
  Serial.print(minCounter);  
  Serial.println();  
  for (int i = 0; i < auxChannels; i++)  
  {  
    byte value = AuxUpdate(auxPins[i], minCounter, auxStart[i], auxStop[i]);  
    Serial.print("Pin ");  
    Serial.print(auxPins[i]);  
    Serial.print(" Value ");  
    Serial.print(value);  
    Serial.println();  
  }  
 }

Cheers,
 
Had a chance to try it out, and it doesn't seem to print out correctly. It will print 1 correct read. Then it goes to only printing the date / time.
 
I changed the serial print out to only run the light calculations once per minute. The print out should print the time each second, and the light values once per minute. Do the lights work as expected?

Thanks,
 
I had a chance to run this and watch the print outs. The moon lights don't ramp up or down. I have them set to come on at about 2pm & off about 1:30 am. They come on at (moon value) 34, first quarter 68.00% and shut off at the same values. And I also noticed that it doesn't change in value for the different moon phases, if it is supposed to. It stayed at the 34 & 68.00% when it switched to waxing gibbous.
 
Can you please see if this will run on the Typhon?

I have modified some of it to compile in Arduino 1.5.2

Let me know if you need the modified Button Library.

If this will run on the Typhon I will work on getting it updated to include my code.

PHP:
/*
// Typhon firmware
// v0.2 alpha 2010-23-11
// N. Enders, R. Ensminger
// Changes made by BoostLED have notations as below.
// This sketch provides firmware for the Typhon LED controller.
// It provides a structure to fade 4 independent channels of LED lighting
// on and off each day, to simulate sunrise and sunset.
//
// Current work in progress:
// - store all LED variables in EEPROM so they are not reset by a loss of power
//
// Future developments may include:
// - moon phase simulation
// - storm simulation
// 
// Sketch developed in Arduino-18
// Requires LiquidCrystal, Wire, EEPROM, EEPROMVar, and Button libraries.
// Button is available here: http://www.arduino.cc/playground/Code/Button
// EEPROMVar is available here: http://www.arduino.cc/playground/uploads/Profiles/EEPROMVar_01.zip
*/

// include the libraries:
#include <Button.h>
#include <EEPROMVar.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Wire.h>


/**** Define Variables & Constants ****/
/**************************************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68

// create the LCD
LiquidCrystal lcd(8, 7, 5, 4, 16, 2);

// set up backlight
int bkl         = 6;        // backlight pin
byte bklIdle    = 10;       // PWM value for backlight at idle
byte bklOn      = 70;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu = Button(12,PULLDOWN);
Button select = Button(13,PULLDOWN);
Button plus = Button(14,PULLDOWN);
Button minus = Button(15,PULLDOWN);

// Button state constants.
byte buttonNotPressed  = 0;
byte buttonUniquePress = 1;
byte buttonIsPressed   = 2;
byte slowCount = 3;         // number of intervals to do a "slowDelay" when holding a button
int slowDelay = 1000;       // milliseconds to delay when initially holding a button
int fastDelay = 100;        // milliseconds to delay after holding the button for "slowCount" intervals

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.

EEPROMVar<boolean> inverted = false; //Modified by NetSurge

// Used for button hold down
int intervalCounter = 0;
int oldIntervalCounter;
unsigned long currMil = 0;         // current millisecond

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4

// Variables making use of EEPROM memory:
EEPROMVar<int> oneStartMins = 750;     // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;   // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;           // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                                      //    this channel.
EEPROMVar<int> twoStartMins = 810;
EEPROMVar<int> twoPhotoPeriod = 600;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 60;
EEPROMVar<int> threeStartMins = 810;
EEPROMVar<int> threePhotoPeriod = 600;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 60;
EEPROMVar<int> fourStartMins = 480;
EEPROMVar<int> fourPhotoPeriod = 510;  
EEPROMVar<int> fourMax = 100;          
EEPROMVar<int> fourFadeDuration = 60;  

typedef struct {
 int Led;            // channel pin
 int StartMins;      // minute to start this channel.
 int PhotoPeriod;    // photoperiod in minutes for this channel.
 int Max;            // max intensity for this channel, as a percentage
 int FadeDuration;   // duration of the fade on and off for sunrise and sunset for
                     //    this channel.
} 
channelVals_t;
channelVals_t channel[4];

/*
int oneStartMins = 1380;    // minute to start this channel.
int onePhotoPeriod = 120;   // photoperiod in minutes for this channel.
int oneMax = 100;           // max intensity for this channel, as a percentage
int oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                            //    this channel.                                    
int twoStartMins = 800;
int twoPhotoPeriod = 60;
int twoMax = 100;
int twoFadeDuration = 15;
int threeStartMins = 800;
int threePhotoPeriod = 60;
int threeMax = 100;
int threeFadeDuration = 30;
int fourStartMins = 800;
int fourPhotoPeriod = 120;  
int fourMax = 100;          
int fourFadeDuration = 60;  
*/

/****** RTC Functions ******/
/***************************/

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

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

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-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
void getDate(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());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
int   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
)  {
 int val = 0;

 //fade up
 if (mins > start || mins <= start + fade)  {
   val = map(mins - start, 0, fade, 0, ledMax);
 }

 //fade down
 if (mins > start + period - fade && mins <= start + period)  {
   val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
 }

 //off or post-midnight run.
 if (mins <= start || mins > start + period)  {
   if((start+period)%1440 < start && (start + period)%1440 > mins )
   {
     val=map((start+period-mins)%1440,0,fade,0,ledMax);
   }
   else  
     val = 0; 
 }


//invert for BuckPuck Functions
//Added by NetSurge
if(inverted){
//  val=~val;
//  val=val&255;
//  ledMax=~ledMax;
//  ledMax=100-ledMax;
}
 if (val > ledMax)  {
   val = ledMax;
 } 

 if (val < 0) {
   val = 0; 
 } 


if(inverted){
 analogWrite(ledPin, map(val, 0, 100, 255, 0));
}
else{
 analogWrite(ledPin, map(val, 0, 100, 0, 255));
}

//Debugging info 0-255 PWM Output
//Modified by NetSurge
/*
if(inverted){
if(ledPin == 9){
lcd.setCursor(0,0);
 lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 10){
 lcd.setCursor(4,0);
 lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 11){
 lcd.setCursor(8,0);
 lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 3){
 lcd.setCursor(12,0);
 lcd.print(map(val, 0, 100, 255, 0));
}
}


else{
if(ledPin == 9){
lcd.setCursor(0,0);
 lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 10){
 lcd.setCursor(4,0);
 lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 11){
 lcd.setCursor(8,0);
 lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 3){
 lcd.setCursor(12,0);
 lcd.print(map(val, 0, 100, 0, 255));
 }
}

*/

 if(override){
   val=overpercent;
 }

 return val;
}

/**** Display Functions ****/
/***************************/

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
boolean ampm    //print am/pm?
)  {
 int hr = (mins%1440)/60;
 int mn = mins%60;
 if(hr<10){
   lcd.print(" ");
 }
 lcd.print(hr);
 lcd.print(":");
 if(mn<10){
   lcd.print("0");
 }
 lcd.print(mn); 
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
byte mn,
byte sec      //time to print
)  
{

 if(hr<10){
   lcd.print(" ");
 }
 lcd.print(hr, DEC);
 lcd.print(":");
 if(mn<10){
   lcd.print("0");
 }

 lcd.print(mn, DEC);
 lcd.print(":");
 if(sec<10){
   lcd.print("0");
 }
 lcd.print(sec, DEC);
}

void ovrSetAll(int pct){
 analogWrite(channel[0].Led, map(pct,0,100,0,255));
 analogWrite(channel[1].Led, map(pct,0,100,0,255));
 analogWrite(channel[2].Led, map(pct,0,100,0,255));
 analogWrite(channel[3].Led, map(pct,0,100,0,255));
}

byte buttonCheck(Button *button) {
 if (button->uniquePress()) {
   return buttonUniquePress;
 } 
 else if (button->isPressed()) {
   return buttonIsPressed;
 } 
 else {
   return buttonNotPressed;
 }
}

boolean checkButtonAction(Button *button) {
 byte buttonState = buttonCheck(button);
 unsigned long mil = millis();
 if (buttonState == buttonUniquePress) {
   intervalCounter = slowCount;
   currMil = mil;
   return true;
 } 
 else if (buttonState == buttonIsPressed) {
   if (intervalCounter > 0) {
     if (currMil < (mil - slowDelay)) {
       intervalCounter--;
       currMil = mil;
       return true;
     }
   } 
   else {
     if (currMil < (mil - fastDelay)) {
       currMil = mil;
       return true;
     }
   }
 }
 return false;
}

/**** Setup ****/
/***************/

void setup() {
 // Initialize channel variables. Set LED channel pin and retrieve values from EEPROM
 channel[0].Led = 9;
 channel[0].StartMins = oneStartMins;
 channel[0].PhotoPeriod = onePhotoPeriod;
 channel[0].Max = oneMax;
 channel[0].FadeDuration = oneFadeDuration;
 channel[1].Led = 10;
 channel[1].StartMins = twoStartMins;
 channel[1].PhotoPeriod = twoPhotoPeriod;
 channel[1].Max = twoMax;
 channel[1].FadeDuration = twoFadeDuration;
 channel[2].Led = 11;
 channel[2].StartMins = threeStartMins;
 channel[2].PhotoPeriod = threePhotoPeriod;
 channel[2].Max = threeMax;
 channel[2].FadeDuration = threeFadeDuration;
 channel[3].Led = 3;
 channel[3].StartMins = fourStartMins;
 channel[3].PhotoPeriod = fourPhotoPeriod;
 channel[3].Max = fourMax;
 channel[3].FadeDuration = fourFadeDuration;

// Title & Credits added
 Wire.begin();
 pinMode(bkl, OUTPUT);
 lcd.begin(16, 2);
 digitalWrite(bkl, HIGH);
 lcd.setCursor(0,0); //Modified by NetSurge
 lcd.print("Typhon Reef LED");
 lcd.setCursor(0,1);
 lcd.print("Controller"); 
 delay(1000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("by N. Enders &");
 lcd.setCursor(0,1);
 lcd.print("R. Ensminger    ");
 delay(1000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Brought to you  ");
 lcd.setCursor(0,1);
 lcd.print("by BoostLED     ");
 delay(2000);
 lcd.clear();
 analogWrite(bkl,bklIdle);
}

/***** Loop *****/
/****************/

void loop() {
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
 oldMinCounter = minCounter;
 minCounter = hour * 60 + minute;

 int i;
 for (i=0; i<4; i++) {
   //check & set fade durations
   if(channel[i].FadeDuration > channel[i].PhotoPeriod/2 && channel[i].PhotoPeriod >0) {
     channel[i].FadeDuration = channel[i].PhotoPeriod/2;
   }
   if(channel[i].FadeDuration<1){
     channel[i].FadeDuration=1;
   }
 }

 //check & set any time functions
 //set outputs
 if(!override){
   oneVal = setLed(minCounter, channel[0].Led, channel[0].StartMins, channel[0].PhotoPeriod, channel[0].FadeDuration, channel[0].Max);
   twoVal = setLed(minCounter, channel[1].Led, channel[1].StartMins, channel[1].PhotoPeriod, channel[1].FadeDuration, channel[1].Max);
   threeVal = setLed(minCounter, channel[2].Led, channel[2].StartMins, channel[2].PhotoPeriod, channel[2].FadeDuration, channel[2].Max);
   fourVal = setLed(minCounter, channel[3].Led, channel[3].StartMins, channel[3].PhotoPeriod, channel[3].FadeDuration, channel[3].Max);
 }
 else{
   oneVal = overpercent;
   twoVal = overpercent;
   threeVal = overpercent;
   fourVal = overpercent;
   ovrSetAll(overpercent);
 }
 // Update EEProms with any values that may have changed
 if (channel[0].StartMins != oneStartMins) {
   oneStartMins = channel[0].StartMins;
 }
 if (channel[0].PhotoPeriod != onePhotoPeriod) {
   onePhotoPeriod = channel[0].PhotoPeriod;
 }
 if (channel[0].Max != oneMax) {
   oneMax = channel[0].Max;
 }
 if (channel[0].FadeDuration != oneFadeDuration) {
   oneFadeDuration = channel[0].FadeDuration;
 }
 if (channel[1].StartMins != twoStartMins) {
   twoStartMins = channel[1].StartMins;
 }
 if (channel[1].PhotoPeriod != twoPhotoPeriod) {
   twoPhotoPeriod = channel[1].PhotoPeriod;
 }
 if (channel[1].Max != twoMax) {
   twoMax = channel[1].Max;
 }
 if (channel[1].FadeDuration != twoFadeDuration) {
   twoFadeDuration = channel[1].FadeDuration;
 }
 if (channel[2].StartMins != threeStartMins) {
   threeStartMins = channel[2].StartMins;
 }
 if (channel[2].PhotoPeriod != threePhotoPeriod) {
   threePhotoPeriod = channel[2].PhotoPeriod;
 }
 if (channel[2].Max != threeMax) {
   threeMax = channel[2].Max;
 }
 if (channel[2].FadeDuration != threeFadeDuration) {
   threeFadeDuration = channel[2].FadeDuration;
 }

 if (channel[3].StartMins != fourStartMins) {
   fourStartMins = channel[3].StartMins;
 }
 if (channel[3].PhotoPeriod != fourPhotoPeriod) {
   fourPhotoPeriod = channel[3].PhotoPeriod;
 }
 if (channel[3].Max != fourMax) {
   fourMax = channel[3].Max;
 }
 if (channel[3].FadeDuration != fourFadeDuration) {
   fourFadeDuration = channel[3].FadeDuration;
 }

 //  if (intervalCounter > 0) {
 //    unsigned long milsec = millis();
 //    if ((currMil < (milsec - 1000)) || (currMil > milsec)) {
 //      currMil = milsec;
 //      intervalCounter--;
 //    }
 //  }

 //turn the backlight off and reset the menu if the idle time has elapsed
 if(bklTime + bklDelay < millis() && bklTime > 0 ){
   analogWrite(bkl,bklIdle);
   menuCount = 1;
   lcd.clear();
   bklTime = 0;
 }

 //iterate through the menus
 if(menu.uniquePress()){
   analogWrite(bkl,bklOn);
   bklTime = millis();
   if(menuCount < 21){  //Modified by NetSurge
     menuCount++;
   }
  else {
     menuCount = 1;
   }
   lcd.clear();
 }

 switch (menuCount) {
 case 1:
   doMainMenu(minCounter, oldMinCounter, hour, minute, second,
   oneVal, twoVal, threeVal, fourVal);
   break;
 case 2:
   doOverride(second);
   break;
 case 3:
   doStartTime(0);
   break;
 case 4:
   doEndTime(0);
   break;
 case 5:
   doFadeDuration(0);
   break;
 case 6:
   doMaxIntensity(0);
   break;
 case 7:
  doStartTime(1);
   break;
 case 8:
   doEndTime(1);
   break;
 case 9:
   doFadeDuration(1);
   break;
 case 10:
   doMaxIntensity(1);
   break;
 case 11:
   doStartTime(2);
   break;
 case 12:
   doEndTime(2);
   break;
 case 13:
   doFadeDuration(2);
   break;
 case 14:
   doMaxIntensity(2);
   break;
 case 15:
   doStartTime(3);
   break;
 case 16:
   doEndTime(3);
   break;
 case 17:
   doFadeDuration(3);
   break;
 case 18:
   doMaxIntensity(3);
   break;
 case 19:
   setHour(&hour, minute, second, dayOfWeek, dayOfMonth, month, year);
   break;
 case 20:
   setMinute(hour, &minute, second, dayOfWeek, dayOfMonth, month, year);
   break;
 case 21:
doinvertPWM();
 break;
 }
}

void doMainMenu(int minCounter,
int oldMinCounter,
byte hour,
byte minute,
byte second,
int oneVal,
int twoVal,
int threeVal,
int fourVal) {


//main screen turn on!!!
 if (minCounter > oldMinCounter){
   lcd.clear();
 }
 lcd.setCursor(0,0);

//Take out display time and uncomment in the led funtion for PWM value debugging
//NetSurge
 lcd.print("Time: "); // Displays Time.
 printHMS(hour, minute, second);
 lcd.setCursor(0,1);
 lcd.print(oneVal);
 lcd.setCursor(4,1);
 lcd.print(twoVal);
 lcd.setCursor(8,1);
 lcd.print(threeVal);
 lcd.setCursor(12,1);
 lcd.print(fourVal);

if(inverted){
  lcd.setCursor(15,0);
  lcd.print("V");
 }
 //debugging function to use the select button to advance the timer by 1 minute
 //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
}

void doOverride(byte second) {
 //Manual Override Menu
 lcd.setCursor(0,0);
 lcd.print("SETTING MODE:        "); // Changed by BoostLED
 lcd.setCursor(0,1);

//if(menuSelect ==4){
//menuSelect = 0;            //modified by NetSurge
//}

 if(select.uniquePress()){
   if(menuSelect < 4){
     menuSelect++;
   }
   else{
     menuSelect = 0;
   }
   bklTime = millis();
 }

 if(menuSelect == 0){
   lcd.print("Timer           "); // Changed by BoostLED
   override = false;
 }
 if(menuSelect == 1){
   lcd.print("All Channels ON "); // Changed by BoostLED
   overpercent = 100;
   override = true;
 }
 if(menuSelect == 2){
   lcd.print("All Channels OFF"); // Changed by BoostLED
   overpercent = 0;
   override = true;
 }    
 if(menuSelect == 3){
   override = true;
   lcd.print("Custom ");   // Added by BoostLED
   lcd.print(overpercent,DEC);
   lcd.print("%        "); 
   if (overpercent < 100) {
     if (checkButtonAction(&plus)) {
       overpercent++;
       bklTime = millis();
     }
    }
   if (overpercent > 0) {
     if (checkButtonAction(&minus)) {
       overpercent--;
       bklTime = millis();
     }
   }
 }
 
//invert PWM 
//Modified by NetSurge
/* Moved to Main Menu and not in Overide Menu

if(menuSelect == 4){
  if(inverted == true)
 lcd.print("PWM Inverted:YES ");
  if(inverted == false)
 lcd.print("PWM Inverted:NO ");
 if (checkButtonAction(&minus) || checkButtonAction(&plus)) {
  inverted = !inverted;
}
override = false;
}
*/
}

void doStartTime(int val) {
 //set start time
 lcd.setCursor(0,0);
 lcd.print("Channel ");
 lcd.print(val+1);
 lcd.print(" Start");
 lcd.setCursor(0,1);
 printMins(channel[val].StartMins, true);
 if (channel[val].StartMins < 1440) {
   if (checkButtonAction(&plus)) {
     channel[val].StartMins++;
     if (channel[val].PhotoPeriod > 0) {
       channel[val].PhotoPeriod--;
     } 
    else {
        channel[val].PhotoPeriod = 1439;
     }
     bklTime = millis();
   }
 } 
 if (channel[val].StartMins > 0) {
   if (checkButtonAction(&minus)) {
     channel[val].StartMins--;
     if (channel[val].PhotoPeriod < 1439) {
       channel[val].PhotoPeriod++;
     } 
    else {
       channel[val].PhotoPeriod=0;
     }
     bklTime = millis();
   }
 } 
}

void doEndTime(int val) {
 //set end time
 lcd.setCursor(0,0);
 lcd.print("Channel ");
 lcd.print(val+1);
 lcd.print(" End");
 lcd.setCursor(0,1);
 printMins(channel[val].StartMins+channel[val].PhotoPeriod, true);
 if (checkButtonAction(&plus)) {
   if(channel[val].PhotoPeriod < 1439){
     channel[val].PhotoPeriod++;
   } 
   else {
     channel[val].PhotoPeriod=0;
   }
   bklTime = millis();
 }
 if (checkButtonAction(&minus)) {
   if(channel[val].PhotoPeriod > 0){
     channel[val].PhotoPeriod--;
   } 
   else {
     channel[val].PhotoPeriod = 1439;
   }
   bklTime = millis();
 }
}

void doFadeDuration(int val) {
 //set fade duration
 lcd.setCursor(0,0);
 lcd.print("Channel ");
 lcd.print(val+1);
 lcd.print(" Fade");
 lcd.setCursor(0,1);
 lcd.print("Duration ");
 printMins(channel[val].FadeDuration, false);
 if (channel[val].FadeDuration < channel[val].PhotoPeriod/2 || channel[val].FadeDuration == 0) {
   if (checkButtonAction(&plus)) {
     channel[val].FadeDuration++;
     bklTime = millis();
   }
 }
 if (channel[val].FadeDuration > 1) {
   if (checkButtonAction(&minus)) {
     channel[val].FadeDuration--;
     bklTime = millis();
   }
 }
}


void doMaxIntensity(int val) {
 //set intensity
 lcd.setCursor(0,0);
 lcd.print("Channel ");
 lcd.print(val+1);
 lcd.print(" Max");
 lcd.setCursor(0,1);
 lcd.print("Level: "); // Added by BoostLED
 lcd.print(channel[val].Max);
 lcd.print("%        "); // Added by BoostLED
 if (channel[val].Max < 100) {
   if (checkButtonAction(&plus)) {
     lcd.clear();
     channel[val].Max++;
     bklTime = millis();
   }
 }
 if (channel[val].Max > 0) {
   if (checkButtonAction(&minus)) {
     lcd.clear();
     channel[val].Max--;
     bklTime = millis();
   }
 }
}

//Select Inverted PWM or not
//Added  By NetSurge
void doinvertPWM() {
lcd.setCursor(0,0);
 lcd.print("PWM Inverted... ");
lcd.setCursor(0,1);
  if(inverted == true)
 lcd.print("YES ");
  if(inverted == false)
 lcd.print("NO ");
 if (checkButtonAction(&minus) || checkButtonAction(&plus)) {
  inverted = !inverted;
}
}

void setHour(byte *hour, byte minute, byte second,
byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
 //set hours
 lcd.setCursor(0,0);
 lcd.print("Set Time: Hrs");
 lcd.setCursor(0,1);
 printHMS(*hour, minute, second);
 if (checkButtonAction(&plus)) {
   if (*hour < 23) {
     (*hour)++;
   } 
  else {
     *hour = 0;
   }
   bklTime = millis();
 }
 if (checkButtonAction(&minus)) {
   if (*hour > 0) {
     (*hour)--;
   } 
   else {
     *hour = 23;
   }
   bklTime = millis();
 }
 setDate(second, minute, *hour, dayOfWeek, dayOfMonth, month, year);
}

void setMinute(byte hour, byte *minute, byte second,
byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
 //set minutes
 lcd.setCursor(0,0);
 lcd.print("Set Time: Mins");
 lcd.setCursor(0,1);
 printHMS(hour, *minute, second);
 if (checkButtonAction(&plus)) {
   if (*minute < 59) {
     (*minute)++;
   } 
  else {
     *minute = 0;
   }
   bklTime = millis();
 }
 if (checkButtonAction(&minus)) {
   if (*minute > 0) {
     (*minute)--;
   } 
  else {
     *minute = 59;
   }
   bklTime = millis();
 }
 setDate(second, *minute, hour, dayOfWeek, dayOfMonth, month, year);
}
 
Hello all
I am trying to incorporate this code into my sketch for my aquarium controller.

I am getting a bunch of errors do to the use of Time.h,DS1307RTC.h, libraries in my sketch i assume.

this is the error i get
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond, pminute;

byte second redeclared as a different kind of symbol

I am not a programmer so all my work is copy- paste and then work out the bugs if anyone has any suggestion what i need to do it would greatly be appreciated

thanks James
 
Last edited:
Hi together,
nice work Numlock10! The code works (almost) fine with my hardware.
Unfortunately i have a problem with the PWM configuration.


PHP:
// LED variables (Change to match your needs)   
byte bluePins[] = {3};      // PWM pins for blues   
byte whitePins[] = {9, 10};    // PWM pins for whites   
byte uvPins[] = {11};         // PWM pins for UVs   
byte moonPins[] = {6};         // 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 = 1;    // how many PWMs for uv (count from above)   
byte moonChannels = 1;    // how many PWMs from moon (count from above)

I had setup two withe channels 9 + 10 and also set the count with a value of 2 in the "channel" row for white.
Unfortunately the second value will not be recognized by Arduino and i have no output signal of the pin 10.
If i change the values from {9, 10} to {10, 9} the same is at pin 9.... no output voltage.

What's wrong?


Thanks Thomas
 
Hi again....
please forget my request. It was my fault. :debi:
I forgot to add the value for the second channel in the "byte WhitePWMHigh"

byte WhitePWMHigh[] = {100, 100};

:rolleye1:
 
Back
Top