/*
// ATMEG328P-AU Microcontroller LED lighting controller for aquarium use.
// The programming code uses a DS1307 Real Time clock to set the LED lighting schedule. Current date and time can be accessed with the serial monitor set to 9600 baud.
// sunrise/sunset time,length of fade duration, and the length of the day are selectable via the programmed schedule.
// Circuit description
// PWM pins described below connected to dimming circuits on drivers spread among 6 seperate channels.
// DS1307 RTC ( real time clock) connected via I2C protocol.
*/
// Pins to control each channel LEDs. Change these if you're using different pins.
int oneLed = 3; // LED PWM arduino pin for channel one.
int twoLed = 5; // LED PWM arduino pin for channel two
int threeLed = 6; // LED PWM arduino pin for channel three
int fourLed = 9; // LED PWM arduino pin for channel four
int fiveLed = 10; // LED PWM arduino pin for channel five
int sixLed = 11; // LED PWM arduino pin for channel six
#include <WProgram.h>
#include <DS1307.h>
// written by mattt on the Arduino forum and modified by D. Sjunnesson
// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year;
// Other variables. These control the behavior of lighting. Change these to customize behavior.
int minCounter = 0; // counter that resets at midnight. Don't change this.
int oneStartMins = 540; // minute to start channel 1. Change this to the number of minutes past midnight you want to start
int twoStartMins =420; // minute to start channel 2. Change this to the number of minutes past midnight you want to start
int threeStartMins =540; // minute to start channel 3. Change this to the number of minutes past midnight you want to start
int fourStartMins =420; // minute to start channel 4. Change this to the number of minutes past midnight you want to start
int fiveStartMins =420; // minute to start channel 5. Change this to the number of minutes past midnight you want to start
int sixStartMins =420; // minute to start channel 6. Change this to the number of minutes past midnight you want to start
int onePhotoPeriod = 720; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int twoPhotoPeriod = 960; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int threePhotoPeriod = 720; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int fourPhotoPeriod = 960; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int fivePhotoPeriod = 960; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int sixPhotoPeriod = 960; // photoperiod in minutes, for this channel. Change this to alter the total legnth of the day
int fadeDuration = 180; // duration of the fade on and off for sunrise and sunset. Change
// this to alter how long the fade lasts.
int oneMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
int twoMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
int threeMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
int fourMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
int fiveMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
int sixMax = 255; // max intensity for this channel. Change if you want to limit max intensity.
/****** 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);
}// This is when the led's are off, thus ledVal =0
if (mins > start && mins <= start + fade) {
analogWrite(ledPin, map(mins - start, 0, fade, 0, ledMax));
}// This is sunrise. Leds slowly brighten to full intensity
if (mins > start + fade && mins <= start + period - fade) {
analogWrite(ledPin, ledMax);
}//This is when the led's are at maximum intensity
if (mins > start + period - fade && mins <= start + period) {
analogWrite(ledPin, map(mins - start - period + fade, 0, fade, ledMax, 0));
}// This is sunset. LEDs slowly fade out.
}
/***** 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.
/* //remove the forward slash and asterisk at the far left to activate the time date setting code
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second));
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
*/ //remove the forward slash and asterisk at the far left to activate the time date setting code
// Gets the date and time from the ds1307 via the I2C protocol.
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);
Wire.begin();
}
// these functions only occur once.
/***** 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.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
Serial.print(":");
Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
Serial.print(":");
Serial.print(RTC.get(DS1307_SEC,false));//read seconds
Serial.print(" "); // some space for a more happy life
Serial.print(RTC.get(DS1307_MTH,false));//read month
Serial.print("/");
Serial.print(RTC.get(DS1307_DATE,false));//read date
Serial.print("/");
Serial.print(RTC.get(DS1307_YR,false)); //read year
Serial.println();
//set LED values
setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, fadeDuration, oneMax);
setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, fadeDuration, twoMax);
setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, fadeDuration, threeMax);
setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fadeDuration, fourMax);
setLed(minCounter, fiveLed, fiveStartMins, fivePhotoPeriod, fadeDuration, fiveMax);
setLed(minCounter, sixLed, sixStartMins, sixPhotoPeriod, fadeDuration, sixMax);
// Get ready for next iteration of loop
delay(1000);
}