Moonphase on custom main

Do you have a question on how to do something.
Ask in here.
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Moonphase on custom main

Post by dpitalo »

Would it be possible to show what phase the moon(moonlights) is in on the main screen?
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Hmm do you mean the % or the day of the phase? If I remember right by the code of moonphase you would only be able to extract the day out of it - then would have to write a statement declaring what days = quartermoon, half moon, full moon, no moon ect for text to be displayed on the main

if you want % its something like this

Code: Select all

ReefAngel.LCD.DrawText(0,255,70,82,"Moon%");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(),COLOR_CORNFLOWERBLUE, 105, 109, 1);  
Problem is that this is a byte function and is already returning the value of what the pwm channel should be set to. So we can't return the day unless we set a global variable and equate the global variable to what day of the moonphase were in(I'd have to look more at the code below to find out what its doing exactly to tell you what variable to use to equate the global). Also you would have to edit the libraries to add the global variable as moonphase() is in ReefAngel_Globals.cpp

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;
}
grr i just typed up a code for you to use instead of editing the libraries and closed the browser...damnit here goes again gime a few min I have a solution but I gotta retype it
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

if you add this to your custom main() you could do it based off of moonlight() pwm value returned

Code: Select all

if (ReefAngel.PWM.GetActinicValue() ==0) ReefAngel.LCD.DrawText(0,255,12,12,"No Moon");
if else(ReefAngel.PWM.GetActinicValue() >=1 && ReefAngel.PWM.GetActinicValue() < 20) ReefAngel.LCD.DrawText(0,255,12,12,"New Moon");
if else(ReefAngel.PWM.GetActinicValue() >=20 && ReefAngel.PWM.GetActinicValue() < 35) ReefAngel.LCD.DrawText(0,255,12,12,"Cresent Moon");
if else(ReefAngel.PWM.GetActinicValue() >=35 && ReefAngel.PWM.GetActinicValue() < 45) ReefAngel.LCD.DrawText(0,255,12,12,"Half Moon");
if else(ReefAngel.PWM.GetActinicValue() >=45 && ReefAngel.PWM.GetActinicValue() < 60) ReefAngel.LCD.DrawText(0,255,12,12,"Gibbous Moon");
if else(ReefAngel.PWM.GetActinicValue() >=60 && ReefAngel.PWM.GetActinicValue() < 80) ReefAngel.LCD.DrawText(0,255,12,12,"Full Moon");

If you want I can try to look at the code of moonphase() some more then we would be able to include whether is is waxing or waning
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Re: Moonphase on custom main

Post by dpitalo »

that's awesome!

I've got to learn how to place things on the custom main. I'll give it a shot in a few.

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

Re: Moonphase on custom main

Post by binder »

dpitalo wrote: I've got to learn how to place things on the custom main. I'll give it a shot in a few.
That's the hard part. I was having Dave create a custom main screen generator app, but that has kind of stalled out now. Maybe we can get him to get it working better (or maybe I should just work on it too).

curt
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Its pretty simple, just trial and error getting things perfectly placed ect ect. A generator would be nice, even if it wasn't a generator a program that you could preview what the code you wrote produces would be cool - right now its load > oops > fix position > load > hope its right > oops > fix > load > ok! haha

this is what the code is

ReefAngel.LCD.DrawText(TextColor, BackgroundColor, HorizontalPosition, VerticalPosition, Contents)
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase on custom main

Post by binder »

Deckoz2302 wrote:Its pretty simple, just trial and error getting things perfectly placed ect ect. A generator would be nice, even if it wasn't a generator a program that you could preview what the code you wrote produces would be cool - right now its load > oops > fix position > load > hope its right > oops > fix > load > ok! haha
Hahah...yep, I'm all too familiar with that loop. :)

curt
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Re: Moonphase on custom main

Post by dpitalo »

Here's what I managed to do. I only made a couple of changes. First if the lights are off, it just displays "Off". Second, I got rid of the "moon" on the end of each phase, so it now just displays "new", "full, "half", etc.
ra-screen-2.jpg
ra-screen-2.jpg (33.93 KiB) Viewed 9383 times
Thanks again to all the people I stole code from and to Deckoz2302 for doing the moon phase thingy. :D

Only other thing left to do is recalibrate the ph probe, but that'll have to wait until 2012 as the LFS is closed today. Such is life.

Also a copy of my PDE should anyone want to do the same.

Code: Select all

#define SIMPLE_MENU
#define DisplayLEDPWM

#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>

#define AutoTopOff        1
#define Daylight          2
#define Relay3            3
#define Heater            4
#define Skimmer           5
#define MetalHalide       6
#define SeaSwirl          7
#define Return            8


#include <avr/pgmspace.h>
//Create the menu entries
prog_char menu1_label[] PROGMEM= "Chow Time";
prog_char menu2_label[] PROGMEM= "h2o Change";
prog_char menu3_label[] PROGMEM= "Force Halide On";
prog_char menu4_label[] PROGMEM= "ph Calibration";
prog_char menu5_label[] PROGMEM= "Set Date Time";
//Group menu entries together
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label,
menu4_label, menu5_label
};

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.Relay.On(MetalHalide);
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry4()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry5()
{
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
ReefAngel.LCD.DrawLargeText(COLOR_BLACK, COLOR_WHITE, 6, 3, "Dave's 40g Reef");
ReefAngel.LCD.DrawDate(6, 120);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 14, 131, 14);
//pingSerial();
x = 12;
y += MENU_START_ROW+1;
ReefAngel.LCD.DrawText(COLOR_BLUE, COLOR_WHITE, x, y+6, "Temp:       ph");
char text[7];
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+75, y+18, text);
//pingSerial();

ConvertNumToString(text, ReefAngel.Params.Temp1, 10);
y += MENU_START_ROW*2;
x = 10;
ReefAngel.LCD.Clear(DefaultBGColor,x,y,x+(16*4),y+16);
//pingSerial();
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
//pingSerial(); 

//Start Moon Phase Display
x += (16*4) + 8;
y += MENU_START_ROW+3;
ReefAngel.LCD.DrawText(COLOR_BLACK, COLOR_WHITE, 12, 55, "Moon Phase:");
if (ReefAngel.PWM.GetActinicValue() ==0) ReefAngel.LCD.DrawText(20,255,81,55,"Off");
else if(ReefAngel.PWM.GetActinicValue() >=1 && ReefAngel.PWM.GetActinicValue() < 20) ReefAngel.LCD.DrawText(20,255,81,55,"New");
else if(ReefAngel.PWM.GetActinicValue() >=20 && ReefAngel.PWM.GetActinicValue() < 35) ReefAngel.LCD.DrawText(20,255,81,55,"Cresent");
else if(ReefAngel.PWM.GetActinicValue() >=35 && ReefAngel.PWM.GetActinicValue() < 45) ReefAngel.LCD.DrawText(20,255,81,55,"Half");
else if(ReefAngel.PWM.GetActinicValue() >=45 && ReefAngel.PWM.GetActinicValue() < 60) ReefAngel.LCD.DrawText(20,255,81,55,"Gibbous");
else if(ReefAngel.PWM.GetActinicValue() >=60 && ReefAngel.PWM.GetActinicValue() < 80) ReefAngel.LCD.DrawText(20,255,81,55,"Full");
//End Display Moon Phase Display


byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 102, TempRelay);
}

void DrawCustomGraph()
{
}

void setup()
{
  ReefAngel.Init();   //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
  ReefAngel.Relay.On(Return);  //Turn Return on at startup
  ReefAngel.Relay.On(Skimmer); //Turn Skimmer on at startup
  ReefAngel.Relay.On(SeaSwirl); //Turn SeaSwirl on at startup
}
void loop()
{

  ReefAngel.StandardATO(AutoTopOff,10);       //Setup AutoTopOff as Auto Top-Off function with 10s timeout
  ReefAngel.MHLights(MetalHalide,10,0,22,30,15); //Daylight schedule 10:00am - 10:30pm with 15min cool down
  ReefAngel.StandardHeater(Heater,788,792);   // Setup Heater to turn on at 78.8F and off at 79.2F
  
    if (hour()>=22 || hour()<=9)
  {
    ReefAngel.PWM.SetActinic(MoonPhase());
  }
  else
  {
    ReefAngel.PWM.SetActinic(0);
  }

  ReefAngel.ShowInterface(); //Draw the Standard Interface
}

Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

No Problem
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Ok I rewrote it to get waning/waxing/first/last

add above setup()

Code: Select all

byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
add to custom main()

Code: Select all

 ReefAngel.LCD.DrawText(0,255,8,97,"Moon");
  DayAge = MoonAge(day(), month(), year());
  MoonState(DayAge);
  char* ThisPhaseLabel[]={"New","Waxing Crescent","First Quarter","Waxing Gibbous","Full","Waning Gibbous","Last Quarter","Waning Crescent"};
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,ThisPhaseLabel[ThisPhase]);
add this after loop

Code: Select all

int JulianDate(int d, int m, int y)
{ 
  int mm, yy;
  int k1, k2, k3;
  int j;

  yy = y - (int)((12 - m) / 10);
  mm = m + 9;
  if (mm >= 12)
  {
    mm = mm - 12;
  }
  k1 = (int)(365.25 * (yy + 4712));
  k2 = (int)(30.6001 * mm + 0.5);
  k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
  // 'j' for dates in Julian calendar:
  j = k1 + k2 + d + 59;
  if (j > 2299160)
  {
    // For Gregorian calendar:
    j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
  }
  return j;
}

double MoonAge(int d, int m, int y)
{ 
    int j = JulianDate(d, m, y);
    //Calculate the approximate phase of the moon
    int ip = (j + 4.867) / 29.53059;
    ip = ip - abs(ip); 
    //After several trials I've seen to add the following lines, 
    //which gave the result was not bad 
    if(ip < 0.5)
        int ag = ip * 29.53059 + 29.53059 / 2;
    else
        int ag = ip * 29.53059 - 29.53059 / 2;
    // Moon's age in days
    byte ag = abs(ag) + 1;
    return ag;
}

byte MoonState(byte D)
{
  switch(D){
  case 1: 
    0, 29;
    ThisPhase = 0;
  case 2: 
    1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
  case 3: 
    7;
    ThisPhase = 2;
  case 4: 
    8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
  case 5: 
    14;
    ThisPhase = 4;
  case 6: 
    15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
  case 7: 
    22;
    ThisPhase = 6;
  case 8: 
    23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
  default: 
    return 0;
  }
}
Last edited by Deckoz2302 on Wed Jan 04, 2012 7:13 pm, edited 1 time in total.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase on custom main

Post by rimai »

May I give you a suggestion on this one?
I like it :)
But, you can save a little bit of code size if you store the variables into an array:

Code: Select all

char* ThisPhaseLabel[]={"New","Waxing Crescent","First Quarter","Waxing Gibbous","Full","Waning Gibbous","Last Quarter","Waning Crescent"};
Then you can just use one line to display:

Code: Select all

ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,ThisPhaseLabel[ThisPhase]);
I haven't tried, but it should work.

Well, the best way would be to store the string into PROGMEM, but that would just complicate things by 10 fold.
Roberto.
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Yea I thought about doing a char or string array - but I thought arduino char arrays are single letter...hmm ill try it out though

ps that works, it probably didnt work for me because i did a char array not a char*
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Moonphase on custom main

Post by StuGotz »

Deckoz2302 wrote:Ok I rewrote it to get waning/waxing/first/last

add above setup()

Code: Select all

byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
add to custom main()

Code: Select all

 ReefAngel.LCD.DrawText(0,255,8,97,"Moon");
  DayAge = MoonAge(day(), month(), year());
  MoonState(DayAge);
  if (ThisPhase == 0) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"New");
  else if (ThisPhase == 1) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Waxing Crescent");
  else if (ThisPhase == 2) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"First Quarter");
  else if (ThisPhase == 3) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Waxing Gibbous");
  else if (ThisPhase == 4) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Full");
  else if (ThisPhase == 5) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Waning Gibbous");
  else if (ThisPhase == 6) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Last Quarter");
  else if (ThisPhase == 7) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,97,"Waning Crescent");
add this after loop

Code: Select all

int JulianDate(int d, int m, int y)
{ 
  int mm, yy;
  int k1, k2, k3;
  int j;

  yy = y - (int)((12 - m) / 10);
  mm = m + 9;
  if (mm >= 12)
  {
    mm = mm - 12;
  }
  k1 = (int)(365.25 * (yy + 4712));
  k2 = (int)(30.6001 * mm + 0.5);
  k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
  // 'j' for dates in Julian calendar:
  j = k1 + k2 + d + 59;
  if (j > 2299160)
  {
    // For Gregorian calendar:
    j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
  }
  return j;
}

double MoonAge(int d, int m, int y)
{ 
    int j = JulianDate(d, m, y);
    //Calculate the approximate phase of the moon
    int ip = (j + 4.867) / 29.53059;
    ip = ip - abs(ip); 
    //After several trials I've seen to add the following lines, 
    //which gave the result was not bad 
    if(ip < 0.5)
        int ag = ip * 29.53059 + 29.53059 / 2;
    else
        int ag = ip * 29.53059 - 29.53059 / 2;
    // Moon's age in days
    byte ag = abs(ag) + 1;
    return ag;
}

byte MoonState(byte D)
{
  switch(D){
  case 1: 
    0, 29;
    ThisPhase = 0;
  case 2: 
    1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
  case 3: 
    7;
    ThisPhase = 2;
  case 4: 
    8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
  case 5: 
    14;
    ThisPhase = 4;
  case 6: 
    15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
  case 7: 
    22;
    ThisPhase = 6;
  case 8: 
    23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
  default: 
    return 0;
  }
}

Thanks!
SuperDodge
Posts: 52
Joined: Sun Feb 12, 2012 11:16 am

Re: Moonphase on custom main

Post by SuperDodge »

I'm trying to use this and I keep getting "Waning Crescent" no matter what. Does the last section of code go into the end of the loop or in a separate section after it?
Image
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase on custom main

Post by binder »

I see problems with this function:

Code: Select all

byte MoonState(byte D)
{
  switch(D){
  case 1: 
    0, 29;
    ThisPhase = 0;
  case 2: 
    1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
  case 3: 
    7;
    ThisPhase = 2;
  case 4: 
    8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
  case 5: 
    14;
    ThisPhase = 4;
  case 6: 
    15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
  case 7: 
    22;
    ThisPhase = 6;
  case 8: 
    23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
  default: 
    return 0;
  }
}
1. Why are there just numbers with commas on a single line with a semi-colon at the end? Those lines should yield an error compiling. I think they are supposed to be commented out maybe?

2. There are no breaks in the switch statement. It will always return ThisPhase as 7.

3. Why does it return a value when you don't even use the return value?

I cleaned up the code and I think this may work better. What do you think?

Code: Select all


// above setup()
void MoonState(byte D);

// after loop()
void MoonState(byte D)
{
  switch(D){
  default:
  case 1: 
    //0, 29;
    ThisPhase = 0;
	break;
  case 2: 
    //1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
	break;
  case 3: 
    //7;
    ThisPhase = 2;
	break;
  case 4: 
    //8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
	break;
  case 5: 
    //14;
    ThisPhase = 4;
	break;
  case 6: 
    //15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
	break;
  case 7: 
    //22;
    ThisPhase = 6;
	break;
  case 8: 
    //23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
	break;
  }
}
I removed the return value, commented out those lines that do nothing and then added in the breaks so the value should be updated properly.
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Hmm my bad for not responding. I just threw it together and never really went back over it.oops
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Moonphase on custom main

Post by jsclownfish »

Any luck testing this out? I tried it wiht Curt's suggestion, but all I get is "new".

-Jon
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

I'll have to look at this again - to all who have been having problems with some of my code I apologize for not responding lately. Between work, having a house built, and prepping for a 9 tank biospecific setup on one system when I move and everything else in between life has been a little hectic.
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: Moonphase on custom main

Post by Deckoz2302 »

Try this

Code: Select all

// above setup()
void MoonState(byte D);

// after loop()
void MoonState(byte D)
{
  switch(D){
  default:
  case 1: 
    if(D == 0 || D ==29);
    ThisPhase = 0;
   break;
  case 2: 
    if(D >=1 && D <=6);
    ThisPhase = 1;
   break;
  case 3: 
    if(D ==7);
    ThisPhase = 2;
   break;
  case 4: 
    if( D >= 8 && D <=13);
    ThisPhase = 3;
   break;
  case 5: 
    if (D ==14);
    ThisPhase = 4;
   break;
  case 6: 
    if( D >= 15 && D<=21);
    ThisPhase = 5;
   break;
  case 7: 
    if(D == 22)
    ThisPhase = 6;
   break;
  case 8: 
    if( D>=23 && D <=28);
    ThisPhase = 7;
   break;
  }
}
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Moonphase on custom main

Post by binder »

That code is exactly the same as what I posted except it adds in additional conditions that are not needed and will not evaluate or change any of the processing. I added some comments of how the compiler will (or at least should) process and evaluate the code during execution. All (well, almost all) assignments of ThisPhase will take place regardless of the IF checks (except case 7).

Code: Select all

void MoonState(byte D)
{
  switch(D){
  default:
  case 1: 
    if(D == 0 || D ==29);  // could be true if D is 0 or 29, but D would most likely be 1 in this case
    ThisPhase = 0;
   break;
  case 2: 
    if(D >=1 && D <=6);  // always true since D is 2, empty statement gets called with ;
    ThisPhase = 1;
   break;
  case 3: 
    if(D ==7);  // never true, D is 3
    ThisPhase = 2;
   break;
  case 4: 
    if( D >= 8 && D <=13);  // never true, D is 4 and not in range
    ThisPhase = 3;
   break;
  case 5: 
    if (D ==14);  // never true, D is 5
    ThisPhase = 4;
   break;
  case 6: 
    if( D >= 15 && D<=21);  // never evaluate true, since D is 6
    ThisPhase = 5;
   break;
  case 7: 
// This statement will never be true and ThisPhase will never get set to 6 because D will never be 22
    if(D == 22)  
    ThisPhase = 6;
   break;
  case 8: 
    if( D>=23 && D <=28);  // This line will always evaluate false since 8 is outside the range
    ThisPhase = 7;
   break;
  }
}
If it works, great, but it "shouldn't" do anything different than the code that I posted except consume more space.
Just adding my 2 cents of the switch statement.
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Moonphase on custom main

Post by jsclownfish »

Here is what I tried.....

before setup....

Code: Select all

// Moon Global Variables - Thanks Deckoz2302!
byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
char* ThisPhaseLabel[]={
    "New","Waxing Crescent","First Quarter","Waxing Gibbous","Full","Waning Gibbous","Last Quarter","Waning Crescent"                        };
void Moonstate(byte D);

in DrawCustomMain...

Code: Select all

// Display the % Moonlight
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 23,"MN:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(), COLOR_BLACK, 82, 23, 1);
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 100, 23,"%");
//moonphase
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor,64,43,"MP:");
ReefAngel.LCD.DrawSingleMonitor(MoonPhase(), COLOR_BLACK, 92, 43, 1); 
// Display Moon Phase & State
    DayAge = MoonAge(day(), month(), year());
    MoonState(DayAge);
    ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255,5,93,ThisPhaseLabel[ThisPhase]);
and after the loop

Code: Select all

// Moon Calculators - Thanks Deckoz2302!
int JulianDate(int d, int m, int y)
{ 
  int mm, yy;
  int k1, k2, k3;
  int j;

  yy = y - (int)((12 - m) / 10);
  mm = m + 9;
  if (mm >= 12)
  {
    mm = mm - 12;
  }
  k1 = (int)(365.25 * (yy + 4712));
  k2 = (int)(30.6001 * mm + 0.5);
  k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
  // 'j' for dates in Julian calendar:
  j = k1 + k2 + d + 59;
  if (j > 2299160)
  {
    // For Gregorian calendar:
    j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
  }
  return j;
}

double MoonAge(int d, int m, int y)
{ 
  int j = JulianDate(d, m, y);
  //Calculate the approximate phase of the moon
  int ip = (j + 4.867) / 29.53059;
  ip = ip - abs(ip); 
  //After several trials I've seen to add the following lines, 
  //which gave the result was not bad 
  if(ip < 0.5)
    int ag = ip * 29.53059 + 29.53059 / 2;
  else
    int ag = ip * 29.53059 - 29.53059 / 2;
  // Moon's age in days
  byte ag = abs(ag) + 1;
  return ag;
}
void MoonState(byte D)
{
  switch(D){
  default:
  case 1: 
    //0, 29;
    ThisPhase = 0;
   break;
  case 2: 
    //1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
   break;
  case 3: 
    //7;
    ThisPhase = 2;
   break;
  case 4: 
    //8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
   break;
  case 5: 
    //14;
    ThisPhase = 4;
   break;
  case 6: 
    //15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
   break;
  case 7: 
    //22;
    ThisPhase = 6;
   break;
  case 8: 
    //23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
   break;
  }
}
Maybe I have something in the wrong place, but the MoonPhase and works appropriately, but the DayAge is always 1, hence the name always stays "new".

-Jon
User avatar
mvwise
Posts: 48
Joined: Sat Apr 21, 2012 7:44 pm
Location: Burlington, Ontario, Canada

Re: Moonphase on custom main

Post by mvwise »

I have been following along and looking at the coding used. While trying it out I was getting all kinds of erroneous results too, so I went looking around for other codes. I have come across this code that seems to be very simple and when I run the manual calculations through a spreadsheet I come extremely close to the actual moon phase calendars.

Globals Defined:

Code: Select all

// Globals Needed for MoonPhase from Deckoz2302
byte ThisPhase;
int MoonState(int,int,int);
char* ThisPhaseLabel[]={"      New Moon","Waxing Crescent Moon"," First Quarter Moon","Waxing Gibbous  Moon","     Full  Moon",
                        "Waning Gibbous  Moon"," Last Quarter  Moon","Waning Crescent Moon"};

Code used in Custom Main:

Code: Select all

// Display Moon Phase during night and Sky Type During Day
        if (ReefAngel.PWM.GetChannelValue(0) > 0)  //If Moonlights are active
        {
          ThisPhase = MoonState(day(), month(), year());
          ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,6,94,ThisPhaseLabel[ThisPhase]);
        }
        else
          ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,6,94,"    Clear  Skies");
Note that I have only left a placeholder for daytime use as I have not coded for clouds or storms yet.

Code used after Loop():

Code: Select all

// Moon Phase Calculator  - courtesy of www.voidware.com/moon_phase.com
  int MoonState(int d, int m, int y)
  { 
    /*
    Calculates the moon phase (0-7), accurate to 1 segment.
    0 = New Moon
    1 = Waxing Crescent Moon
    2 = First Quarter Moon
    3 = Waxing Gibbous Moon
    4 = Full Moon
    5 = Waning Gibbous Moon
    6 = Last Quarter Moon
    7 = Waning Crescent Moon
    */
        
    int c, e, fd;
    double jd;
    int b;

    if (m < 3)
    {
      y--;
      m += 12;
    }
    ++m;
    c = 365.25 * y;
    e = 30.6 * m;
    jd = c + e + d - 694041.09;    // jd is total days elapsed
    jd /= 29.53;                   // divide by the moon cycle (29.53 days)
    fd = jd;                       // int(jd) -> fd, take integer part of jd
    jd -= fd;                      // subtract integer part to leave fractional part of original jd
    b = jd * 8 + .5;               // scale fraction from 0-8 and round by adding 0.5
    b = b & 7;                     // 0 and 8 are the same so turn 8 into 0
    return b;
  }
As I mentioned earlier, I plugged the mathematic calculations into a spreadsheet and come up with pretty accurate results, however, when using the code in my sketch I am getting different results. In an attempt to search for the culprit I was getting odd readings for year() in that the function was using 220 rather than 2012. This may be one factor but I'm thinking there may be other issues in how it calculates. I would appreciate anyones help if they could figure something out.
Image
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase on custom main

Post by rimai »

I still don't understand why the MoonPhase() doesn't work.
Could you please elaborate?
Roberto.
User avatar
mvwise
Posts: 48
Joined: Sat Apr 21, 2012 7:44 pm
Location: Burlington, Ontario, Canada

Moonphase on custom main

Post by mvwise »

Maybe I've been looking at the forum too much and am missing something obvious?

My understanding is that MoonPhase() results in a percentage of moon exposed on a given day. This percentage could then be used to select new, full, quarter, crescent and gibbous moons.

However, based on what I have seen on the forum, some over-enthusiastic reefers, myself included, would like to know if the crescent and gibbous is waxing or waning. I suppose it's overkill, but I don't believe this can be culled from MoonPhase().

If it can be done, why not try it - I figure!


---
I am here: http://tapatalk.com/map.php?laxcxd
Sent from my Matthew's iPhone using Tapatalk
Image
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase on custom main

Post by rimai »

Ahh, now I got what the whole deal is :oops:
Let me think about it.
Roberto.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase on custom main

Post by rimai »

Try this function.
Add to end of loop(). If it works, I'll make part of the libraries.

Code: Select all

char* MoonPhaseLabel()
{
  int m,d,y;
  int yy,mm;
  long K1,K2,K3,J;
  double 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)/29.530588853;
  V -= floor(V);
  if (V<0) V++;
  if (V<0.0625) return "New Moon";
  else if (V<0.1875) return "Waxing Crescent";
  else if (V<0.3125) return "First Quarter";
  else if (V<0.4375) return "Waxing Gibbous";
  else if (V<0.5625) return "Fuul Moon";
  else if (V<0.6875) return "Waning Gibbous";
  else if (V<0.8125) return "Last Quarter";
  else if (V<0.9375) return "Waning Crescent";
  else return "New Moon";
}
You can draw on the screen with something like this:

Code: Select all

ReefAngel.LCD.DrawText(0,255,10,10,MoonPhaseLabel());
Roberto.
User avatar
mvwise
Posts: 48
Joined: Sat Apr 21, 2012 7:44 pm
Location: Burlington, Ontario, Canada

Moonphase on custom main

Post by mvwise »

Great, thanks!

This seems to be working. Current state is New, which it is, do I'll monitor it for the next few days to see if it changes, but it looks good so far.

Now I just need to at storm, clouds and lightning to a two channel light setup.


---
I am here: http://tapatalk.com/map.php?vfij5r
Sent from my Matthew's iPhone using Tapatalk
Image
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Moonphase on custom main

Post by DrewPalmer04 »

I've been messing with this a bit and I keep getting errors? How do I go about adding this to my custom main? Was the global variable added to the libraries? Do I need to do this? Thanks!
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Moonphase on custom main

Post by rimai »

The function was not added to libraries yet.
Nobody confirmed it working yet.
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Moonphase on custom main

Post by DrewPalmer04 »

I'll test it and report back if I can figure out how to upload this. Help? :)
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
Post Reply