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.
// 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 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);
}
/*
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);
}
/*
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);
}
Have a look at this code. It displayed the time and date along with the values being fed to the drivers.
/*
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);
}
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