Arduino Forum

Forum 2005-2010 (read only) => Software => Troubleshooting => Topic started by: adambrum on Feb 10, 2010, 01:06 am

Title: moon phasing
Post by: adambrum on Feb 10, 2010, 01:06 am
Does anyone an easy way to simulate moon phasing. I have found one example but i cant make head or tale of the coding, I know the bits i need are in there its just a little over my head. i have an rtc running so thats not a problem.

Any Ideas.

Thanks Adam
Title: Re: moon phasing
Post by: Grumpy_Mike on Feb 10, 2010, 10:47 am
So what sort of output do you need, graphical, text, LEDs?

or do you just want to calculate what the phase is from the RTC?
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 11:13 am
Just need an anolog out for leds.

It does not have to be spot on, It for a reef aquarium so im sure the fish will not be bothered if its not perfect.
Title: Re: moon phasing
Post by: GrooveFlotilla on Feb 10, 2010, 11:44 am
Is it the shape of the Moon, or its output you need to simulate?
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 12:20 pm
Its just the output i need.

because i have the rtc set up and running i have the day,month,and year variables available to use.
Title: Re: moon phasing
Post by: Grumpy_Mike on Feb 10, 2010, 12:27 pm
Quote
Just need an anolog out for leds.


Do you mean that you just want the equivalent light output?

Basically it is simple. You take an epoch, that is just a time when you know the moon is in an exact state, say full or new. Then you take the moon synodic period (29.530588 days), that is the apparent time it takes to orbit the Earth not the real sidereal period. And wind on the time and see how many orbits it has completed since then up to now. The fractional part of this count of orbits is how far through the cycle you are at the moment. The illumination approximates to a sin wave through the cycle.

see:-
http://starchild.gsfc.nasa.gov/docs/StarChild/questions/question32.html
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 12:51 pm
Do you mean that you just want the equivalent light output?

I should have said that in the first place  :)

I will go away and have a look at the epoch thing, sounds about right for what i need.

Edit, i have the new time libary so i have the use of unix time.

So the last full moon was 30/1/2010 at 6:18 which is unix time 1264832280 and a complete cycle is 2551442.8032 second

Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 01:56 pm
Quick play about and i have come up with the following.

The last full moon was at unix time 1264832280.

The time now is 1265804820

The difference is 972540

A full cycle is 2551442.803 seconds

So

( 255 / 2551442.803 ) * 972540 = 97.199

So today an anolog value of 97.199 would give the current moon phase, well sort of, need to do some reading on moon phase.

Does this look about right so far
Title: Re: moon phasing
Post by: PaulS on Feb 10, 2010, 02:07 pm
Quote
A full cycle is 2551442.803 seconds


If you round that off, you can use integer arithmetic.

Quote
( 255 / 2551442.803 ) * 972540 = 97.199


Do the multiplication first, and multiply by 100, then divide. The integer result will be a %-age. I doubt that the fish can distinguish between 14.3% and 15%, or, even if they can, do they care?

Where did the 255 come from?
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 02:13 pm
The 255 is the analog value for the pwm.

i will try rounding up and using % and see if i can get a more usable format
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 02:42 pm
Just tried this and i seems to work

Code: [Select]

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>

long dif;  
int moon;  

void setup()  {
 Serial.begin(9600);
 setSyncProvider(RTC.get);
}

void loop()
{
  delay(1000);
  Serial.println(moon);
 
  dif =(now()-1264832280);
  moon = (dif * 255 / 2551443);
}


How does that look ?
Title: Re: moon phasing
Post by: Grumpy_Mike on Feb 10, 2010, 02:58 pm
Quote
So today an anolog value of 97.199 would give the current moon phase,

Well I did look at the moon this morning driving in to work and it was a very thin crescent so I imagine the illumination would be close to zero today.
So 97 out of a full 255 doesn't sound right.
You need only take the fractional part of the dif not the whole of it. Plus if that is phase from new the light peaks at half way (50% phase) and then drops down again.

However, I assume you want to make the light the same a the moon contribution at night, when the moon is anything but full it is not up all night.

@PaulS - You need to avoid integer arithmetic on this because the rounding errors would accumulate every orbit period.  
Title: Re: moon phasing
Post by: PaulS on Feb 10, 2010, 03:00 pm
dif should be an unsigned long.

What does the 255 mean?

I'd use this:

Code: [Select]
#define CYCLELENGTH 2551443
moon = (dif * 255 / CYCLELENGTH);


It makes it clear(er) what 2551443 means.
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 03:46 pm
I have made the changes suggested.

When this code is sorted it will go in my main code which can fade the moonlight in and out at set times. What i need from this code is a max setting for the moon brightness to fade in and out too.

Think ineed to have a look at my maths again for the current moon
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 05:08 pm
My heads hurting now, Cant work the maths out.

So far i have

The last new moon on the 15/1/2010 at 7:10 which is unix time 1263539400

the last full moon on the 30/1/2010 at 6:18 which is unix time 1264832280

A full cycle is 2551442.803 seconds

A half cycle is 1275721.4015

So what i need to do is increase a value from 0-max over half a cycle then from max-0 for the other half of the cycle.

I just cant think of a way to do this ?
Title: Re: moon phasing
Post by: PaulS on Feb 10, 2010, 08:12 pm
You know when "now" is. You know when a cycle started. You should, therefore, be able to tell how far into that cycle you are.

The value that you are looking for starts at 0 when you are at the start of the cycle, and rises to 255, and then drops to 0. If you are less then 1/2 way though the cycle, the value will be:

(timeInCycle/lengthOfHalfCycle) * 255.

If you are more then 1/2 way through the cycle, the value will be:

255 - (((timeInCycle - lengthOfHalfCycle)/lengthOfHalfCycle) * 255)

This assumes you want a linear increase in brightness from start of cycle to midpoint of cycle, and a linear decrease in brightness from midpoint of cycle to end of cycle.

If not, you'll need to compute the value using the sin() function, with the percent through the cycle * 360 degrees (for a whole cycle) as the input value (may need to convert to radians). Using the sin() function, it won't matter which half of the cycle you are in. Multiply the output by 255 to get the PWM value.
Title: Re: moon phasing
Post by: adambrum on Feb 10, 2010, 10:11 pm
Stuck all ready !

I got what was said earlier about using the fractions for the cycle.

So what i was thinking was if i just used the fraction to 2 decimal places then i would get a 0-99 value depending on were i was in the cycle.

For example

1263539400 is the last new moon and would have a value of 1.00
1264815121 is the last full moon and would have a value of 1.50
and so on.

problem is how do i do the calculations in the arduino sketch, i take it done with floats ?

What i want to do is

timeincycle = ((current time - last new moon) / lenghtofhalfcycle)

So the current cycle would be for example 0.83 i just need the 83 part of this.

I do appriciate your help guys  :)

Title: Re: moon phasing
Post by: adambrum on Feb 11, 2010, 12:00 am
Ok then how do i get just the fraction part of a number for example here is a quick sketch will prints the value of 3.33 the only part i need is the 33. I can do it the otherway turning 33 into 3.3 but just not the way i need to do it.


here is the mock sketch

Code: [Select]

unsigned long x;
unsigned long y;
float z;

void setup()
{                
Serial.begin(9600);
}

void loop()                    
{
 x = 1000000000;
 z = (float) x / 300000000.0;
 
 delay(1000);
 Serial.println(z); // prints out 3.33
}
Title: Re: moon phasing
Post by: PaulS on Feb 11, 2010, 12:14 am
To extract the fractional part of a number:

Code: [Select]
float wholeNumber = 8.453;
int integerPart = wholeNumber;
float fractionalPart = wholeNumber - fractionalPart;


Then, you can multiply fractionalPart by 100, if you want two digits, and stuff the result into an integer:

Code: [Select]
int twoDigits = 100 * fractionalPart; // will contain 45

Title: Re: moon phasing
Post by: adambrum on Feb 11, 2010, 12:54 am
I added the new bits to the sketch and its not quite right. Next to the serial.print i have added whats being printed.

Code: [Select]
unsigned long x;
unsigned long y;
float z;
int twoDigits;

void setup()
{
Serial.begin(9600);
}

void loop()
{
 x = 1000000000;
 z = (float) x / 300000000.0;

 delay(2000);
 
float wholeNumber = z;
int integerPart = wholeNumber;
float fractionalPart = wholeNumber - fractionalPart;

Serial.print("z = ");  
Serial.println(z);                         //printing 3.33

Serial.print("wholeNumber");
Serial.println(wholeNumber);               //printing 3.33

Serial.print("fractionalPart = ");
Serial.println(fractionalPart);            //printing 3.33

Serial.print("twoDigits =");
Serial.println(twoDigits);                 //printing 0
 
int twoDigits = 100 * fractionalPart;
}
Title: Re: moon phasing
Post by: adambrum on Feb 11, 2010, 01:09 am
Sorted that one.

this line

float fractionalPart = wholeNumber - fractionalPart;

should have been

float fractionalPart = wholeNumber - integerPart;

Thanks for the help so far, this should keep me busy for a while but i think i have the makings of a code.
Title: Re: moon phasing
Post by: PaulS on Feb 11, 2010, 01:12 am
Damn keyboard didn't type what I was muttering to myself as I typed...
Title: Re: moon phasing
Post by: adambrum on Feb 11, 2010, 02:00 am
Thanks for all your help.

i should be able to tweak the code now to do what i want and the good thing is due to using a 0-99 int for the value i can assign differnt values to for any of the 0-99 ints so i should be able to get a really good simulation instead of just a liniar increase/decrease.

Again Thanks