Moonphase calculation

Related to the development libraries, released by Curt Binder
Post Reply
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Moonphase calculation

Post by rimai »

Because the old MoonlightPWM() function only dealt with using the one of the ATO ports modified to work as 5V PWM signals, I decided to create a new one that actually does nothing but calculate the moonphase.
This way, the user can simply use the value and assign to whatever channel he/she wishes to connect the dimmable moonlight.

Code: Select all

byte MoonPhase()
{
  int m,d,y;
  int yy,mm;
  long K1,K2,K3,J,V;
  byte PWMvalue;
  m=month();
  d=day();
  y=year();
  yy=y-((12-m)/10);
  mm=m+9;
  if (mm>=12) mm-=12;
  K1=365.25*(yy+4712);
  K2=30.6*mm+.5;
  K3=int(int((yy/100)+49)*.75)-38;
  J=K1+K2+d+59-K3;
  V=(J-2451550.1)/0.29530588853;
  V-=int(V/100)*100;
  V=abs(V-50);
  PWMvalue=4*abs(50-V);  // 5.12=100%    4=~80%
  //pinMode(lowATOPin,OUTPUT);
  return (PWMvalue*100)/255;
}
Roberto.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

An example on how to use this would be:

Code: Select all

    ReefAngel.PWM.SetActinic(MoonPhase());
This line would apply the calculated value of the moon phase on the actinic channel.
Roberto.
icecool2
Posts: 62
Joined: Tue Jul 19, 2011 3:12 pm

Re: Moonphase calculation

Post by icecool2 »

How would you apply this to the PWMSlope function? I'd like to be able to slope down to the current moon phase and then stay there for some number of hours and then dim out the rest of the way to 0. Having a second PWMSlope setting function within the loop won't work I don't think. That would just cause the LEDs to blink.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Are you using the channel for your actinics too or just moonlights?
Roberto.
icecool2
Posts: 62
Joined: Tue Jul 19, 2011 3:12 pm

Re: Moonphase calculation

Post by icecool2 »

I'm only using the actinic and daylight channels. I'd like to set a moon look using both of those channels at very low values.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Which driver are you using?
Meanwell drivers cut off at around 15% and it's still quite bright.
Roberto.
icecool2
Posts: 62
Joined: Tue Jul 19, 2011 3:12 pm

Re: Moonphase calculation

Post by icecool2 »

I'm using Recom drivers. I built the drive circuitry myself. Meanwells didn't exist when I started with LEDs ;)
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Best way to do that and avoid the flickering is to use an if statement to check for time.
Something like this:

Code: Select all

  if (hour()>20 || hour()<9)
  {
    ReefAngel.PWM.SetActinic(MoonPhase()/10);
  }
  else
  {
    ReefAngel.PWM.SetActinic(PWMSlope(9,0,20,0,15,100,60,ReefAngel.PWM.GetActinicValue()));
  }
The above code uses the MoonPhase calculation from 8pm to 9am and the PWMSlope otherwise.
The division by 10 would reduce the calculation by a factor of 10, which would cause full moon to drive the LEDs at 10%. You can choose your own value if 10% is too much.
Let me know if this works for you.
Roberto.
NanoTrevor
Posts: 69
Joined: Thu Jun 02, 2011 1:58 pm

Re: Moonphase calculation

Post by NanoTrevor »

hey roberto, what about setting this to use channel 3 of the pwm exp module, where i have my moonlight connected?
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Pretty simple.

Code: Select all

  PWMChannel[LEDPWM3]=MoonPhase();
Roberto.
NanoTrevor
Posts: 69
Joined: Thu Jun 02, 2011 1:58 pm

Re: Moonphase calculation

Post by NanoTrevor »

lol, yup simple, or so i think. lol. so plug the moonlight code into the pde at the bottom right? then just call that function in the loop? also what about comp. with the inverted pucks?
icecool2
Posts: 62
Joined: Tue Jul 19, 2011 3:12 pm

Re: Moonphase calculation

Post by icecool2 »

rimai wrote:Best way to do that and avoid the flickering is to use an if statement to check for time.
Something like this:

Code: Select all

  if (hour()>20 && hour()<9)
  {
    ReefAngel.PWM.SetActinic(MoonPhase()/10);
  }
  else
  {
    ReefAngel.PWM.SetActinic(PWMSlope(9,0,20,0,15,100,60,ReefAngel.PWM.GetActinicValue()));
  }
The above code uses the MoonPhase calculation from 8pm to 9am and the PWMSlope otherwise.
The division by 10 would reduce the calculation by a factor of 10, which would cause full moon to drive the LEDs at 10%. You can choose your own value if 10% is too much.
Let me know if this works for you.
I did something similar to that, but I added in another PWMSlope to get it to fade down to the moonlight value. I think this should work.

Code: Select all

     if(hour() >= 18) {
         ReefAngel.PWM.SetActinic(PWMSlope(11,0,18,0,70,(100-(MoonPhase()/10)),120,ReefAngel.PWM.GetActinicValue()));
     } else {
        ReefAngel.PWM.SetActinic(PWMSlope(11,0,20,0,100,70,120,ReefAngel.PWM.GetActinicValue()));
     }
Note that my LEDs are off at 100 and on full at 0.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

It is still wrong.
Both SetActinic Statement still has inverted slope values. You can't use start value of 100 and end value of 70.
In your case, you have to set the PWMSlope to go from 0 to 30%, just like any other meanwell user would do.
Then, use math to invert the values. Simply use 100 - PWM value to invert it.
So, you code should look something like this:

Code: Select all

     if(hour() >= 18) {
         ReefAngel.PWM.SetActinic(100-PWMSlope(11,0,18,0,0,MoonPhase()/10,120,ReefAngel.PWM.GetActinicValue()));
     } else {
        ReefAngel.PWM.SetActinic(100-PWMSlope(11,0,20,0,0,30,120,ReefAngel.PWM.GetActinicValue()));
     }
Let me know of this works.
Roberto.
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase calculation

Post by binder »

does this function need to be placed in the libraries to replace the existing function:

Code: Select all

void ReefAngelClass::MoonlightPWM(byte RelayID, bool ShowPWM)
If so, it would be simple for me to remove the above function and then just add the Moonlight function (that is at the beginning of this post) to the libraries so it could be utilized.

curt
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

I think you can leave the old one in there and just add the new one. If not used, it won't get included in the compiled file anyway.
Although they seem to do same thing, they really don't. The new MoonPhase() doesn't do anything but the calculation of the %. Then, with this number, you can add it to whatever channel you have your moonlights on. The previous one was linked to one of the ATO pins and was watching for a relay status change, which was too complicated. I still use it though :)
Roberto.
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase calculation

Post by binder »

Ok cool. Then I'll plan on adding this one in to the globals file so it will be a generic function (which is appears to be).

curt
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase calculation

Post by binder »

This function has been added to the Globals file and will be a global function in the upcoming 0.8.5.17 release. You will be able to use it exactly like the examples are in this topic.

curt
icecool2
Posts: 62
Joined: Tue Jul 19, 2011 3:12 pm

Re: Moonphase calculation

Post by icecool2 »

Excellent. I'll look for the new release.
agentgreen
Posts: 97
Joined: Wed Jul 06, 2011 6:45 am

Re: Moonphase calculation

Post by agentgreen »

Could you elaborate on the programming for this? When I tried this, my moonlights didn't come on.

Does this basically start the % at 0, and then over the course of the month, ramp up to 100% than back down to 0%?

Here is my PDE:


// Autogenerated file by RAGen (v1.0.4.92), (09/09/2011 07:48)
// RA_090911_0748.pde
//
// This version designed for v0.8.5 Beta 12 or later

/* The following features are enabled for this PDE File:
#define DisplayImages
#define WavemakerSetup
#define DateTimeSetup
#define VersionMenu
#define MetalHalideSetup
#define DirectTempSensor
#define DisplayLEDPWM
#define StandardLightSetup
#define RelayExp
*/


#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

byte MoonPhase()
{
int m,d,y;
int yy,mm;
long K1,K2,K3,J,V;
byte PWMvalue;
m=month();
d=day();
y=year();
yy=y-((12-m)/10);
mm=m+9;
if (mm>=12) mm-=12;
K1=365.25*(yy+4712);
K2=30.6*mm+.5;
K3=int(int((yy/100)+49)*.75)-38;
J=K1+K2+d+59-K3;
V=(J-2451550.1)/0.29530588853;
V-=int(V/100)*100;
V=abs(V-50);
PWMvalue=4*abs(50-V); // 5.12=100% 4=~80%
//pinMode(lowATOPin,OUTPUT);
return (PWMvalue*100)/255;
}

void setup()
{
ReefAngel.Init(); //Initialize controller

ReefAngel.FeedingModePorts = B00011000;
ReefAngel.WaterChangePorts = B00011000;
ReefAngel.WaterChangePortsE[0] = B11000000;
ReefAngel.OverheatShutoffPorts = B11000100;
ReefAngel.LightsOnPorts = B00000011;

// Ports that are always on
ReefAngel.Relay.On(Port3);
ReefAngel.Relay.On(Box1_Port1);
ReefAngel.Relay.On(Box1_Port4);
}

void loop()
{
ReefAngel.ShowInterface();

// Specific functions
ReefAngel.MHLights(Port1);
ReefAngel.MHLights(Port2);
ReefAngel.Wavemaker1(Port4);
ReefAngel.Wavemaker2(Port5);
ReefAngel.StandardHeater(Port6);
ReefAngel.StandardLights(Box1_Port3);
ReefAngel.DelayedOn(Box1_Port2, 2);

if (hour()>22 && hour()<9)
{
ReefAngel.PWM.SetActinic(MoonPhase());
ReefAngel.PWM.SetDaylight(MoonPhase());
}

}
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Basically, this code will only turn moonlights on between 11pm and 8am.
Also, the moonphase is calculated according to the cycle of the moon. The cycle is somewhere around of 29days, where new moon would output 0% and full moon would output 100%.
In the code above, the % should be displayed in the RA screen too. Both AP and DP should show the % of intensity.
Roberto.
jemw
Posts: 41
Joined: Sat Oct 08, 2011 9:21 am

Re: Moonphase calculation

Post by jemw »

I have found that this statement does not work as expected:
if (hour()>22 && hour()<9)
{
ReefAngel.PWM.SetActinic(MoonPhase());
ReefAngel.PWM.SetDaylight(MoonPhase());
}

My moonlights were on all the time.

To make my moonlights turn on at 7PM and turn off at 7AM I found:

Added this code to the setup to turn them off by default (power failure etc.):
// Set Actinic and Daylight off by default
ReefAngel.PWM.SetActinic(0);
ReefAngel.PWM.SetDaylight(0);

And then added this code to the loop function:
if ( hour() <= 6 || hour () >= 19 ) // Moonlights on from 7PM to 7AM
{
ReefAngel.PWM.SetActinic(MoonPhase());
ReefAngel.PWM.SetDaylight(MoonPhase());
}
else
{
ReefAngel.PWM.SetActinic(0);
ReefAngel.PWM.SetDaylight(0);

}
_____
Jim
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase calculation

Post by rimai »

Yes, it was a typo that I made. I fixed it on my previous post too.
Thanks for your help!!! :)
Roberto.
Post Reply