binder, you should use this as there's less variables defined and easier to setup now
Code: Select all
//By Matthew Hockin 2012.
//SWFLTEK library functions, #includes, and #define were copied directly from the Epherma library
//Epherma (SWFLTEK.com) was written by Michael Rice- thanks Michael it works great.
//If you copy from this (its all open source) please
//acknowledge Michael for SWFLTEK library code (obviously labeled) or Matthew Hockin (for the rest).
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <ReefAngel.h>
////// Place global variable code below here
//includes for SWFLTEK functions
#include <stdlib.h>
#include <math.h>
//defines for SWFLTEK functions
#define _sec_rad 206264.806247096370813 // arc-seconds per radian
#define _tilt 0.409092804222329 // axial tilt of earth at epoch, in radians
#define _tropical_year 31556925 // tropical year in seconds... rounding error accumulates to 26 seconds by the year 2136
#define _zenith 3.11250383272322 // 'zenith' of rising (setting) sun in radians (360 - 2 * 90.833 degrees)
//*******************GLOBAL VARIABLE DECLERATIONS FOR MHOCKIN Weather package*************************************
long latitude=-18.285833; // Great Barrier Reef, Australia
long longitude=147.699722; // Great Barrier Reef, Australia
byte dow=0;//day of week
//*******************END HEADER FOR MHOCKIN Weather package*******************************************************
// Additional variables added for Sunrise/Sunset calculation
int SunriseHour, SunriseMin, SunsetHour, SunsetMin;
int userOffset=-(9*3600); // -9 hours
////// Place global variable code above here
void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
// Ports that are always on
////// Place additional initialization code below here
////// Place additional initialization code above here
}
void loop()
{
////// Place your custom code below here
// Set Sunrise and Sunset from MHOCKIN Weather package functions.
if (dow!=day()) // used to see that were in a new day and need to recalculate sunrise and sunset
{
CalSun();
dow=day();
// And let's reset the light schedule
}
////// Place your custom code above here
// This should always be the last line
ReefAngel.ShowInterface();
}
//Start of sunrise, sunset and cloud calculations- runs on reset and once a day thereafter.
void CalSun(){
long newDay;
unsigned long rise;//time in seconds from the year 2000 (GMT) for sunrise
unsigned long set;//time in seconds from the year 2000 (GMT) for sunrise
//Serial.println("CalSun Run Now");
latitude=ddToSeconds(latitude);
longitude=ddToSeconds(longitude);
if (dow==0){//if the controller has resarted we need to find midnight
long hours, minutes;//store current elapsed local hours as total seconds from midnight
time_t t=now();//store current clock time to parse
hours=hour(t);
hours=(hours*3600);//current hour number 0-23 as seconds
minutes=minute(t);
minutes=(minutes*60);//minutes of current hour as seconds
newDay=now();
newDay-=(hours+minutes);//Convert current local unix epoch time to local unix epoch time of midnight
}
else if (dow!=0){//if we did not restart but the day is new then it is midnight and were good to go..
newDay=now();
}
//#define SECS_YR_2000 (946684800) the time at the start of y2k (need to subtract from unix epoch time to bring to Y2K origin
newDay-=946684800;//convert GMT unix Epoch to seconds elasped since 2000 for GMT midnight of today
rise=newDay;//set value to send to SunRise as midnight GMT in seconds from Y2K
set=newDay;//
//Calculate rise time and set time using Epherma Library functions (see end of code)
SunRise(&rise);//call to Epherma function
SunSet(&set);//Call to Epherma functionunsigned long newDay;
/*
Serial.print("rise and set= ");
Serial.println(rise);
Serial.println(set);
Serial.print("newDay as seconds since 2000 to todays midnight= ");
Serial.println(newDay);
*/
// Convert rise/set to normal hours/minutes before we make it an offset from midnight.
// Currently correcting for a 56 minute correction to Sunrise and -19 minute correction to Sunset (8/14/2012@GBR)
SunriseHour=hour(rise+userOffset);
SunriseMin=minute(rise+userOffset);
SunsetHour=hour(set+userOffset);
SunsetMin=minute(set+userOffset);
}//END SunCalc FUNCTION
//********************** DO NOT MESS WITH THIS UNLESS YOU KNOW WHAT YOUR DOING****************************
//THE CODE BELOW THIS copied directly from the SWFLTEK Epherma library constructed by Michael Rice.
//this code is being used freely with attribution to Micahel Rice in accord with his request
// A big thank you for these library functions. Its great!
// decimal degrees
long ddToSeconds(float dd){
return dd * 3600.0;
}
//Degrees, minutes, seconds
long dmsToSeconds(int d, unsigned char m, unsigned char s){
long ret;
ret = labs((long)d);
ret = ret * 3600L + 60L * m + s;
ret = (d<0L) ? -ret : ret;
return ret;
}
/* ------------------------------------------------------------------------------------------------
'Equation of Time'
We use the 'short form equation, which has a theoretical accuracy of about 40 seconds.
The returned value is in seconds.
*/
int equation_of_time(unsigned long dt){
double t;
dt -= 192540UL; // refer to Jan 3 2000 05:29 (first periapsis)
dt %= _tropical_year;
t = dt;
t /= _tropical_year;
t *= 6.283185307179586;
t = -459.27672 * sin(t) + 575.333472 * sin(2.0 * t + 3.588414);
return t;
}
/* -----------------------------------------------------------------------------------------------
'Solar Declination'
Returns declination in radians
Accurate to within 50 arc-seconds
*/
double SolarDeclination(unsigned long dt){
double y;
dt %= _tropical_year;
y = dt;
y /= _tropical_year; // fractional year
y *= 6.283185307179586;
y=0.006918-0.399912*cos(y)+0.070257*sin(y)-0.006758*cos(y*2)+0.000907*sin(y*2)-0.002697*cos(y*3)+0.00148*sin(y*3);
return y;
}
/* ------------------------------------------------------------------------------------------------
Return the period between sunrise and sunset, in seconds.
At high latitudes around the time of the solstices, this could be zero, or all day.
*/
unsigned long daylightseconds(unsigned long dt){
float l, d, e;
long n;
d = -SolarDeclination(dt); // will be positive in Northern winter
l = latitude / _sec_rad; // latitude in radians
e += 60.0 * l * tan(l + d); // latitudinal error
d = tan(l) * tan(d); //
if(d>1.0) return 86400UL;
if(d < -1.0) return 0UL;
d = acos(d);
d /= _zenith;
n = 86400UL * d;
n += e;
return n;
}
/* ------------------------------------------------------------------------------------------------
Modify the passed time stamp to the time of sunrise (or sunset if 'set' is non-zero).
Returns 0 to signal 'normal' completion. If the position is in a polar circle, 1 will be
returned if the sun is above the horizon all day, and -1 if the sun is below the horizon
all day.
*/
char SunRiseSet(unsigned long * dt, char set){
unsigned long daylen;
daylen = daylightseconds(*dt);
if(daylen == 86400UL) return 1; // there is no 'night' today (midnight sun)
if(daylen == 0UL) return -1; // there is no 'day' today
*dt /= 86400UL;
*dt *= 86400UL;
*dt += 43200UL; // set the time stamp to 12:00:00 GMT
*dt -= daylen / 2; // sunrise at the prime meridian
if(set) *dt += daylen; // sunset at the prime meridian
*dt -= equation_of_time(*dt);
*dt -= longitude / 15.0; // rotate to our own meridian
return 0;
}
// 'short' forms of SunRiseSet
char SunRise(unsigned long* when){
return SunRiseSet(when, 0);
}
char SunSet(unsigned long* when){
return SunRiseSet(when, 1);
}