Sunrise Sunset Calculation Durations

Expansion modules and attachments
Post Reply
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Sunrise Sunset Calculation Durations

Post by lnevo »

Did you test it yet? Glad we came up with something :) curious if it works as designed
clw143
Posts: 118
Joined: Fri Jun 21, 2013 8:20 pm
Location: Louisiana

Re: Sunrise Sunset Calculation Durations

Post by clw143 »

It is up and running and functioning as intended.

Only time will tell if the coral enjoys it.
89delta
Posts: 163
Joined: Mon Oct 15, 2012 7:21 pm
Location: Leesburg, GA

Re: Sunrise Sunset Calculation Durations

Post by 89delta »

Very cool. Now we can factor in seasonal shifts....

Sent from my Samsung Galaxy Note 3
clw143
Posts: 118
Joined: Fri Jun 21, 2013 8:20 pm
Location: Louisiana

Re: Sunrise Sunset Calculation Durations

Post by clw143 »

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.

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()
{
}



clw143
Posts: 118
Joined: Fri Jun 21, 2013 8:20 pm
Location: Louisiana

Re: Sunrise Sunset Calculation Durations

Post by clw143 »

So I commented out this

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);
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?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Sunrise Sunset Calculation Durations

Post by lnevo »

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
clw143
Posts: 118
Joined: Fri Jun 21, 2013 8:20 pm
Location: Louisiana

Re: Sunrise Sunset Calculation Durations

Post by clw143 »

What would be the best way for once per day? Just do the calculation and write the locations anytime after midnight?

Code: Select all

if ( (now()%86400==00000) {

}
How would I add, if time = something or a reset was performed?
clw143
Posts: 118
Joined: Fri Jun 21, 2013 8:20 pm
Location: Louisiana

Re: Sunrise Sunset Calculation Durations

Post by clw143 »

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);
    }
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Sunrise Sunset Calculation Durations

Post by lnevo »

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]) {
...
}
Post Reply