Sunrise Sunset Calculation Durations
Sunrise Sunset Calculation Durations
I would like a little help and input on how I would calculate changing the durations (slope) of rising and setting time.
So, as hours per day increase, the duration increases. As hours per day decrease, duration decreases giving the tank the same amount of (insert proper word here... solar radiation??)
I know how to accomplish this in the code, just looking for input on what sort of numbers to apply so the tank is getting "the same amount of light" throughout the varying day lengths.
In my mind this would be something like the period of the curve decreases the duration increases (slopes get steeper) keeping the area under the curve the same? Would that be what I am looking for? Not exactly to scale, but a reference.
So, as hours per day increase, the duration increases. As hours per day decrease, duration decreases giving the tank the same amount of (insert proper word here... solar radiation??)
I know how to accomplish this in the code, just looking for input on what sort of numbers to apply so the tank is getting "the same amount of light" throughout the varying day lengths.
In my mind this would be something like the period of the curve decreases the duration increases (slopes get steeper) keeping the area under the curve the same? Would that be what I am looking for? Not exactly to scale, but a reference.
Re: Sunrise Sunset Calculation Durations
Some quick calculations in excel calculating area under a curve with about a 4 hour per day swing between summer and winter shows I can swing the duration from 2.5 hours for the longest day to 0.5 hours for the shortest day instead of shortening the daylight duration. The duration of 2.5 hours is Actinic Offset as well as the slope duration giving 5 hours or rise time until max light.
Is this data viable and work the way I think it should?
Is this data viable and work the way I think it should?
Re: Sunrise Sunset Calculation Durations
I think you could write something to calculate the amount of time between rise and set and the calculate the slope accordingly.
Actually a map command should do it.
I'll write it up later for you if you need assistance with the code
Actually a map command should do it.
I'll write it up later for you if you need assistance with the code
Re: Sunrise Sunset Calculation Durations
It would be cool to see what you come up with.
It's more the question of will coral be ok with more hours with less time at max PAR equally as less hours with more time at max PAR.
It's more the question of will coral be ok with more hours with less time at max PAR equally as less hours with more time at max PAR.
Re: Sunrise Sunset Calculation Durations
It's really a question of what you want to provide. Typically in Winter when it's shorter hours the intensity is technically higher because we're closer to the sun during that part of the year.
For code, try this
int duration=map(NumMins(sl.GetRiseHour(),sl.GetRiseMinute(),sl.GetSetHour(),sl.GetSetMinute()), 7*60, 13*60, 4*60, 2*60);
That should do it I think. So it's mapping the number of minutes between rise and set and then mapping it from 7-13 hours to 4hours to 2hours. So the shorter the minutes, the closer to 4 hour duration. The longer the daylight time, the closer to 2 hours.
For code, try this
int duration=map(NumMins(sl.GetRiseHour(),sl.GetRiseMinute(),sl.GetSetHour(),sl.GetSetMinute()), 7*60, 13*60, 4*60, 2*60);
That should do it I think. So it's mapping the number of minutes between rise and set and then mapping it from 7-13 hours to 4hours to 2hours. So the shorter the minutes, the closer to 4 hour duration. The longer the daylight time, the closer to 2 hours.
Re: Sunrise Sunset Calculation Durations
According to the libraries:
Code: Select all
int NumMins ( uint8_t ScheduleHour,
uint8_t ScheduleMinute
)
error: too many arguments to function 'int NumMins(uint8_t, uint8_t)Code: Select all
(NumMins(sl.GetRiseHour(),sl.GetRiseMinute(),sl.GetSetHour(),sl.GetSetMinute())
Re: Sunrise Sunset Calculation Durations
Sorry about that if thats the case you'll need to replace that with NumMins(sl.GetSetHour(), sl.GetSetMinute())-NumMins(sl.GetRiseHour(),sl.GetRiseMinute())
Re: Sunrise Sunset Calculation Durations
Why break it apart and not use this?
Code: Select all
NumMins(sl.GetSunSet(), sl.GetSunRise()
Re: Sunrise Sunset Calculation Durations
NumMins takes an hour and a minute. I thought it subtracted the two times.
Re: Sunrise Sunset Calculation Durations
So this is the code I ended up using in case anyone else wants to so something similar.
In this scenario, ActinicOffset = Slope Duration.
On the longest day of the year my Actinic lights take 2.5 hours to ramp up to max and then the daylights turn on and take 2.5 hours to ramp up to max.
On the shortest day the Actinic lights take 1 hour to ramp to max and then the daylights turn on and take 1 hour to ramp to max.
I based these numbers on the attached spreadsheet factoring in MAX hours of day light vs. the Area under the curve in hopes to even out the strength vs. length of daylight swing in order to maintain actual sun rise and sun set times for my location.
Code: Select all
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);
ReefAngel.CustomVar[3]=duration;
On the longest day of the year my Actinic lights take 2.5 hours to ramp up to max and then the daylights turn on and take 2.5 hours to ramp up to max.
On the shortest day the Actinic lights take 1 hour to ramp to max and then the daylights turn on and take 1 hour to ramp to max.
I based these numbers on the attached spreadsheet factoring in MAX hours of day light vs. the Area under the curve in hopes to even out the strength vs. length of daylight swing in order to maintain actual sun rise and sun set times for my location.
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]) {
...
}