Sunrise Sunset Calculation Durations
Re: Sunrise Sunset Calculation Durations
Did you test it yet? Glad we came up with something curious if it works as designed
Re: Sunrise Sunset Calculation Durations
It is up and running and functioning as intended.
Only time will tell if the coral enjoys it.
Only time will tell if the coral enjoys it.
Re: Sunrise Sunset Calculation Durations
Very cool. Now we can factor in seasonal shifts....
Sent from my Samsung Galaxy Note 3
Sent from my Samsung Galaxy Note 3
Re: Sunrise Sunset Calculation Durations
Tonight I observed that my controller is ramping the lights up to max and then back to where they belong. I'm not sure if it occurs all day or just during set. I only noticed because there was no lights on in the living room yet.
I suspect maybe there is something that needs to go infront or behind something else in my code. Below is my code, any help will be appreciated.
I suspect maybe there is something that needs to go infront or behind something else in my code. Below is my code, any help will be appreciated.
Code: Select all
#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 <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <ReefAngel.h>
#include <SunLocation.h>
////// Place global variable code below here
byte DailyAlk;
byte DailyCalc;
byte wp40mode; //Mode Byte
byte DayMins;
SunLocation sl;
////// Place global variable code above here
void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
// Add Standard Menu
ReefAngel.AddStandardMenu();
// Ports toggled in Feeding Mode
ReefAngel.FeedingModePorts = Port3Bit | Port6Bit | Port7Bit| Port8Bit;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = Port7Bit;
// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
ReefAngel.OverheatProbe = T1_PROBE;
// Ports that are always on
ReefAngel.Relay.On( Port3 ); //Mag 12 Return Pump
ReefAngel.Relay.On( Port4 ); //Reef Octopus Skimmer
////// Place additional initialization code below here
// initialize the sunrise / sunset location
sl.Init(30.197220, -92.080637); // Latitude , Longitude values set (LA)
sl.SetOffset(-5,0,-5,0); // rise_hour, rise_seconds, set_hour, set_seconds (LA)
////// Place additional initialization code above here
}
void loop()
{
//Alkalinity Drip
if (ReefAngel.Params.PH < 840) {
ReefAngel.DosingPumpRepeat(Port1, 15,
InternalMemory.DP1RepeatInterval_read(),
InternalMemory.DP1Timer_read());
}
//Calcium Drip
ReefAngel.DosingPumpRepeat(Port2, 30,
InternalMemory.DP2RepeatInterval_read(),
InternalMemory.DP2Timer_read());
//Cooling Fans
ReefAngel.StandardFan( Port6 );
//Ehiem 150W Heater
ReefAngel.StandardHeater( Port7 );
//MAXI Jet 600 ATO Pump
ReefAngel.StandardATO( Port8 );
//Right & Left Philips Rebel ES Royal Blue and Cool White & UV & Cree XT-E Green
ReefAngel.PWM.Channel1PWMSlope(InternalMemory.ActinicOffset_read());
//Right Daylight Cree XP-G2 R5 Cool White
ReefAngel.PWM.Channel2PWMSlope();
//Right Actinic Cree XT-E Royal Blue
ReefAngel.PWM.Channel3PWMSlope(InternalMemory.ActinicOffset_read());
//Left Daylight Cree XP-G2 R5 Cool White
ReefAngel.PWM.Channel4PWMSlope();
//Left Actinic Cree XT-E Royal Blue
ReefAngel.PWM.Channel5PWMSlope(InternalMemory.ActinicOffset_read());
////// Place your custom code below here
// handle updating sunrise and sunset values
sl.CheckAndUpdate();
DayMins = ((NumMins(sl.GetSetHour(), sl.GetSetMinute()))-(NumMins(sl.GetRiseHour(), sl.GetRiseMinute())));
int duration = map((DayMins), 850, 615, 150, 60);
InternalMemory.ActinicOffset_write(duration);
InternalMemory.PWMSlopeDuration1_write(duration);
InternalMemory.PWMSlopeDuration2_write(duration);
InternalMemory.PWMSlopeDuration3_write(duration);
InternalMemory.PWMSlopeDuration4_write(duration);
InternalMemory.PWMSlopeDuration5_write(duration);
//PWM Expansion Channels = 0 if Overheat or Lights off
if ((ReefAngel.Params.Temp[T1_PROBE]>InternalMemory.OverheatTemp_read()) || (now()<sl.GetSunRise() || now()>sl.GetSunSet())) {
ReefAngel.PWM.SetChannel (1,0);
ReefAngel.PWM.SetChannel (2,0);
ReefAngel.PWM.SetChannel (3,0);
ReefAngel.PWM.SetChannel (4,0);
ReefAngel.PWM.SetChannel (5,0);
}
// moonlight are on between sunset hour and sunrise hour
if (hour()>=sl.GetSetHour() || hour()<=sl.GetRiseHour()) ReefAngel.PWM.SetChannel (0, (map(MoonPhase(), 0,100,9.9,25)));
else ReefAngel.PWM.SetChannel (0,0);
//Start Feeding Mode at 17:00 (hour*60*60)
if ( (now()%86400==61200) /*|| (now()%86400==39600) */) ReefAngel.FeedingModeStart();
//Hydor Evolution 1400 Circulation Pump & LED Cooling Fan (Port5) Off Between sunrise hour and sunset hour
if (hour()<sl.GetRiseHour() || hour()>=sl.GetSetHour()) {
ReefAngel.Relay.Off(Port5);
}
else {
ReefAngel.Relay.On(Port5);
}
ReefAngel.CustomVar[0]=DailyAlk;
ReefAngel.CustomVar[1]=DailyCalc;
ReefAngel.CustomVar[3]=duration;
DailyAlk = ((InternalMemory.DP1Timer_read() * (.75)) * (1440 / InternalMemory.DP1RepeatInterval_read())); //Alk ml/day
DailyCalc = ((InternalMemory.DP2Timer_read() * (.75)) * (1440 / InternalMemory.DP2RepeatInterval_read())); //Calc ml/day
//assignmenets are = and comparisons are ==
if (ReefAngel.CustomVar[5] > 0){
ReefAngel.PWM.SetDaylight( millis()%((10 * ReefAngel.CustomVar[6]))<((10 * ReefAngel.CustomVar[7]))?100:0); //Custom "W1"
ReefAngel.PWM.SetActinic( millis()%((10 * ReefAngel.CustomVar[6]))>((10 * ReefAngel.CustomVar[6])-(10 * ReefAngel.CustomVar[7]))?0:100); //Custom "W1"
wp40mode=10;
}else{
if (hour()>=sl.GetRiseHour() && hour()<12) wp40mode=6; //sunrise hour - 11:59am
else if (hour()>=12 && hour()<17) wp40mode=7; //12pm - 4:59pm
else if (hour()>=17 && hour()<18) wp40mode=5; //5pm - 5:59pm
else if (hour()>=18 && hour()<24) wp40mode=3; //6pm - 11:59pm
else wp40mode=4; //12am - sunrise hour
};
if (wp40mode==9) ReefAngel.PWM.SetDaylight( 100 ); //Full Speed
if (wp40mode==9) ReefAngel.PWM.SetActinic( 100 ); //Full Speed
if (wp40mode==8) ReefAngel.PWM.SetDaylight( 100/3 ); //Third Speed
if (wp40mode==8) ReefAngel.PWM.SetActinic( 100/3 ); //Third Speed
if (wp40mode==7) ReefAngel.PWM.SetDaylight( millis()%1300<750?75:0); //Custom "W1"
if (wp40mode==7) ReefAngel.PWM.SetActinic( millis()%1300>550?0:75); //Custom "W1"
if (wp40mode==6) ReefAngel.PWM.SetDaylight( TidalSwellMode(60,true ) ); //WaveMaxSpeed, PulseSync
if (wp40mode==6) ReefAngel.PWM.SetActinic( TidalSwellMode(60,false ) ); //WaveMaxSpeed, PulseSync
if (wp40mode==5) ReefAngel.PWM.SetDaylight( NutrientTransportMode(0,75,2000,true ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==5) ReefAngel.PWM.SetActinic( NutrientTransportMode(0,75,2000,false ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==4) ReefAngel.PWM.SetDaylight( LongPulseMode(0,50,3,true ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (s), PulseSync
if (wp40mode==4) ReefAngel.PWM.SetActinic( LongPulseMode(0,50,3,false ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (s), PulseSync
if (wp40mode==3) ReefAngel.PWM.SetDaylight( ShortPulseMode(0,65,1200,true ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==3) ReefAngel.PWM.SetActinic( ShortPulseMode(0,65,1200,false ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==2) ReefAngel.PWM.SetDaylight( ReefCrestMode(50,20,true ) ); //WaveSpeed, WaveOffset, PulseSync
if (wp40mode==2) ReefAngel.PWM.SetActinic( ReefCrestMode(50,20,false ) ); //WaveSpeed, WaveOffset, PulseSync
if (wp40mode==1) ReefAngel.PWM.SetDaylight( SineMode(0,100,10,true ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==1) ReefAngel.PWM.SetActinic( SineMode(0,100,10,false ) ); //PulseMinSpeed, PulseMaxSpeed, PulseDuration (ms), PulseSync
if (wp40mode==0) ReefAngel.PWM.SetDaylight( TideMode(20,100,20 ) ); //WaveSpeed, minOffset, maxOffset
if (wp40mode==0) ReefAngel.PWM.SetActinic( TideMode(20,100,20 ) ); //WaveSpeed, minOffset, maxOffset
//WP-40s off for water change
if( ReefAngel.DisplayedMenu==WATERCHANGE_MODE ) ReefAngel.PWM.SetDaylight(0);
if( ReefAngel.DisplayedMenu==WATERCHANGE_MODE ) ReefAngel.PWM.SetActinic(0);
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "clw143" );
ReefAngel.ShowInterface();
}
void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
char text[7];
ReefAngel.LCD.DrawDate(6, 3);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 132, 11);
pingSerial();
ReefAngel.LCD.Clear(DefaultBGColor,0,25,132,33);
ReefAngel.LCD.DrawText(0,255,18,14,"Jebao WP40 Mode:");
if (wp40mode==0) ReefAngel.LCD.DrawLargeText(COLOR_GREEN,255,42,25,"Tide");
else if(wp40mode==1) ReefAngel.LCD.DrawLargeText(COLOR_RED,255,42,25,"Sine");
else if (wp40mode==2) ReefAngel.LCD.DrawLargeText(COLOR_ORANGE,255,23,25,"Reef Crest");
else if (wp40mode==4) ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255,23,25,"Long Pulse");
else if (wp40mode==3) ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255,23,25,"Short Pulse");
else if (wp40mode==5) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,8,25,"Nutrient Trnsp.");
else if (wp40mode==7) ReefAngel.LCD.DrawLargeText(COLOR_BLUE,255,40,25,"W1");
else if (wp40mode==6) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,25,"Tidal Swell");
else if (wp40mode==8) ReefAngel.LCD.DrawLargeText(COLOR_BLUE,255,25,25,"1/3 Power");
else if (wp40mode==9) ReefAngel.LCD.DrawLargeText(COLOR_BLUE,255,23,25,"Full Power");
else if (wp40mode==10) ReefAngel.LCD.DrawLargeText(COLOR_RED,255,23,25,"W1 Test");
pingSerial();
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 34, 132, 34);
ReefAngel.LCD.DrawText(0,255,10,37,"Disp");
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 8, 45, text, Num8x8);
pingSerial();
ReefAngel.LCD.DrawText(0,255,53,37,"Room");
ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 50, 45, text, Num8x8);
pingSerial();
ReefAngel.LCD.DrawText(0,255,95,37,"Sump");
ConvertNumToString(text, ReefAngel.Params.Temp[T3_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 93, 45, text, Num8x8);
pingSerial();
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 53, 132, 53);
ReefAngel.LCD.DrawText(0,255,10,56,"pH");
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 27, 56, text, Num8x8);
pingSerial();
ReefAngel.LCD.DrawText(0,255,67,56,"WP40");
ConvertNumToString(text, ReefAngel.PWM.GetDaylightValue(),1);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 95, 56, text, Num8x8);
ReefAngel.LCD.DrawText(0,255,118,56," %");
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 65, 132, 65);
pingSerial();
{
char buf[16];
sprintf(buf, "%02d:%02d", sl.GetRiseHour(), sl.GetRiseMinute());
ReefAngel.LCD.DrawText(0,255,2,67,"Sun");
ReefAngel.LCD.DrawText(0,255,21,67,"Rise: ");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,49,67,buf);
sprintf(buf, "%02d:%02d", sl.GetSetHour(), sl.GetSetMinute());
ReefAngel.LCD.DrawText(0,255,80,67,"Set: ");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,102,67,buf);
}
ReefAngel.LCD.DrawText(0,255,8,75,"Moon: ");
ConvertNumToString(text, MoonPhase(),1);
ReefAngel.LCD.DrawText(COLOR_BLUE,255,40,75,text);
ReefAngel.LCD.DrawText(0,255,58,75," %");
ReefAngel.LCD.DrawText(0,255,28,83,MoonPhaseLabel());
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 92, 132, 92);
pingSerial();
ReefAngel.LCD.DrawLargeText(COLOR_BLUE,255,7,96,"Shaun & Kerri's");
ReefAngel.LCD.DrawLargeText(0,255,7,108,"90Gal Reef Tank");
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 118, TempRelay);
pingSerial();
}
void DrawCustomGraph()
{
}
Re: Sunrise Sunset Calculation Durations
So I commented out this
and the repeated ramping of lights during sun set stopped, the current duration stayed where it was in memory at 81 minutes for the 5 channels and for the ActinicOffset.
During ramping I could watch the % on the android app for output ramp up when I keep hitting the refresh button, the duration value I never observed a change in the custom variables. If I used the app to over ride the LED% the ramping stopped.
Any thoughts?
Code: Select all
InternalMemory.ActinicOffset_write(duration);
InternalMemory.PWMSlopeDuration1_write(duration);
InternalMemory.PWMSlopeDuration2_write(duration);
InternalMemory.PWMSlopeDuration3_write(duration);
InternalMemory.PWMSlopeDuration4_write(duration);
InternalMemory.PWMSlopeDuration5_write(duration);
During ramping I could watch the % on the android app for output ramp up when I keep hitting the refresh button, the duration value I never observed a change in the custom variables. If I used the app to over ride the LED% the ramping stopped.
Any thoughts?
Re: Sunrise Sunset Calculation Durations
Verify the durations that are getting written to memory. Also you are writing to memory locations every iteration of your loop...this is a quick way to corrupt those memory locations. Do it once a day or only if the value differs
Re: Sunrise Sunset Calculation Durations
What would be the best way for once per day? Just do the calculation and write the locations anytime after midnight?
How would I add, if time = something or a reset was performed?
Code: Select all
if ( (now()%86400==00000) {
}
Re: Sunrise Sunset Calculation Durations
Can I just go like this to get it to only write on a change?
Code: Select all
int S1 = (NumMins(sl.GetSetHour(), sl.GetSetMinute()));
int S2 = (NumMins(sl.GetRiseHour(), sl.GetRiseMinute()));
int DayMins = (S1-S2);
int duration = map((DayMins), 615, 850, 60, 150);
if (duration = duration){
}else{
ReefAngel.CustomVar[3]=duration;
InternalMemory.ActinicOffset_write(duration);
InternalMemory.PWMSlopeDuration1_write(duration);
InternalMemory.PWMSlopeDuration2_write(duration);
InternalMemory.PWMSlopeDuration3_write(duration);
InternalMemory.PWMSlopeDuration4_write(duration);
InternalMemory.PWMSlopeDuration5_write(duration);
}
Re: Sunrise Sunset Calculation Durations
You can't compare duration with itself it will always be equal. Plus you are using = as assignment instead of comparison ==
I would change it to this:
if (duration!=ReefAngel.CustomVar[3]) {
...
}
I would change it to this:
if (duration!=ReefAngel.CustomVar[3]) {
...
}