Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 05:37 10 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Moon Phase

Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 09:06pm 01 May 2018
Copy link to clipboard 
Print this post

Has anyone weitten code to calculate the Moon Phase for the Micromite or Micromite+?
I don't need anything complex like times or anything, just the phase on a given day
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2139
Posted: 09:15pm 01 May 2018
Copy link to clipboard 
Print this post

  lew247 said   Has anyone weitten code to calculate the Moon Phase for the Micromite or Micromite+?
I don't need anything complex like times or anything, just the phase on a given day


forum member cdeagle specialises in this maths-heavy, astronomical kind of stuff... have a look through his posts
 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 09:41pm 01 May 2018
Copy link to clipboard 
Print this post

There's some simple calc's here that might serve the purpose.

Moon Phase Calcs.

Phil.

Edit;- Think I still have my Casio FX-201P sitting somewhere.

Sheesh, I read 1976 when I clicked on it's link on that page....Edited by Phil23 2018-05-03
 
piclover
Senior Member

Joined: 14/06/2015
Location: France
Posts: 134
Posted: 11:13pm 01 May 2018
Copy link to clipboard 
Print this post

Here's a extract of my meteo station program (which gives Moon phase and age, among other things). I hope I did not forget any chunk of code.


REM Global variables declaration
OPTION EXPLICIT
REM tz is the time zone (e.g. 2.0 for UTC+2)
REM moonphase is the percentage of the moon disk that is lit
REM moonage is the number of days since last new moon
DIM FLOAT tz,moonphase,moonage

REM Constants
CONST TO_DEG=57.2957795131
CONST TO_RAD=1.74532925199e-2

tz=2.0
ComputeMoonPhase()
PRINT "Moon: "+STR$(moonphase*100.0,2,0)+"% "+STR$(moonage,2,1)+"d"

REM Computes the number of Julian days elapsed since 2000-01-01 12:00 UTC for
REM date d$ and time t$ (leave the latter empty to get the elapsed time in full
REM days). Note: t$ is the local time (the time zone is subtracted from it).
FUNCTION JD2000(d$,t$)
LOCAL FLOAT jd
LOCAL INTEGER day,month,year,hour,min,sec
day=VAL(LEFT$(d$,2)):month=VAL(MID$(d$,4,2)):year=VAL(RIGHT$(d$,4))-2000
jd=365*year+(year+3)\4+275*month\9-((month+9)\12)*(1+((year MOD 4)+2)\3)+day-31
IF LEN(t$)=8 THEN
hour=VAL(LEFT$(t$,2))-tz:min=VAL(MID$(t$,4,2)):sec=VAL(RIGHT$(t$,4))
jd=jd+hour/24.0+min/1440.0+sec/3600.0
ENDIF
JD2000=jd
END FUNCTION

SUB ComputeMoonPhase()
LOCAL FLOAT jd,N,M,Ec,Ls,ml,MM,MN,Ev,Ae,A3,MmP,mEc,A4,lP,V,lPP,NP,y,x
LOCAL FLOAT Lm,BM,delta
REM Constants for the Sun and the Moon at julian date 1980-01-00
CONST MAfactor=0.9856473321
CONST Elonge=278.83354
CONST Elongp=282.596403
CONST Eccent=0.016718
CONST Eccent2=1.016860112
CONST Mlfactor=13.1763966
CONST Mmlong=64.975464
CONST MMfactor=0.1114041
CONST Mmlongp=349.383063
CONST Mlnode=151.950429
CONST MNfactor=0.0529539
CONST Evfactor=1.2739
CONST Aefactor=0.1858
CONST A3factor=0.37
CONST mEcfactor=6.2886
CONST A4factor=0.214
CONST Vfactor=0.6583
CONST NPfactor=0.16
CONST CosMinc=0.995970321:REM COS(TO_RAD*5.145396)
CONST SinMinc=8.9683442e-2:REM SIN(TO_RAD*5.145396)
CONST Synmonth=29.53058868
REM Was 1e-6 in initial algorithm, but we only have simple precision floats
CONST EPSILON=1e-5
REM 7306=days elapsed between 2000-01-01 and 1980-01-00=1979-12-31
jd=JD2000(DATE$,TIME$)+7306
N=MAfactor*jd:N=N-N\360*360.0
M=N+Elonge-Elongp:M=M-M\360*360.0:M=TO_RAD*M
Ec=M
DO
delta=Ec-Eccent*SIN(Ec)-M
Ec=Ec-delta/(1-Eccent*COS(Ec))
LOOP UNTIL ABS(delta)<=EPSILON
Ec=Eccent2*TAN(Ec/2.0):Ec=2*TO_DEG*ATN(Ec)
Ls=Ec+Elongp:Ls=Ls-Ls\360*360.0
ml=Mlfactor*jd+Mmlong:ml=ml-ml\360*360.0
MM=ml-MMfactor*jd-Mmlongp:MM=MM-MM\360*360.0
MN=Mlnode-MNfactor*jd
Ev=Evfactor*SIN(TO_RAD*(2*(ml-Ls)-MM))
Ae=Aefactor*SIN(M):A3=A3factor*SIN(M)
MmP=MM+Ev-Ae-A3
mEc=mEcfactor*SIN(TO_RAD*MmP):A4=A4factor*SIN(TO_RAD*2*MmP)
lP=ml+Ev+mEc-Ae+A4
V=Vfactor*SIN(TO_RAD*2*(lP-Ls)):lPP=lP+V
NP=MN-NPfactor*SIN(M)
y=SIN(TO_RAD*(lPP-NP))*CosMinc:x=COS(TO_RAD*(lPP-NP))
Lm=TO_DEG*ATAN2(y,x)+NP
BM=TO_DEG*ASIN(SIN(TO_RAD*(lPP-NP))*SinMinc)
moonage=lPP-Ls
moonage=moonage-moonage\360*360.0:IF moonage<0 THEN moonage=moonage+360.0
moonphase=0.5-COS(TO_RAD*moonage)/2.0
moonage=Synmonth*moonage/360.0
END SUB


The original algorithm was written in PHP and is available here.Edited by piclover 2018-05-03
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2139
Posted: 01:46pm 02 May 2018
Copy link to clipboard 
Print this post

  Phil23 said   There's some simple calc's here that might serve the purpose.

Moon Phase Calcs.

Phil.



Thanks for that link Phil. Based on the first algorithm (which the author says seems more accurate) I trans-coded (and simplified) the C to give the following function:


Function MoonPhase(y As Integer,m As Integer,d As Integer) As Integer
'calculates the moon phase (0-7), accurate to 1 segment.
'0 => new moon, 4 => full moon, 7= last part of third quarter ( before new)

Local Float jd

If m<3 Then y=y-1:m=m+12

m=m+1

jd=(((365.25*y)+(30.6*m)+d)-694039.09)/29.53 'total days divided by the moon cycle
MoonPhase=Fix((jd-Int(jd))*8) Mod 7
End Function


The phases seem to be broadly correct but only accurate to the nearest day; it doesn't work to hours. As an example, the full moon on December 22 here in the UK is at 17:48 - that is a good portion into the next day and the function returns a 5 (next segment after a full moon... however if you get the phase for the preceding day, it does return a 4 (full moon). This might also be down to the single precision of MMBasic (non MMX) as the original does specify double. So if you went out at 00:01 on 21/12 you might be irritated to see it not a full moon when this algorithm says it is, but at 23:59 the same day it would be hard to tell (besides the fact the moon would have gone - but let's ignore that )

I don't think the algorithm is accurate enough for astronomical stuff but within a day makes it good for anything that just needs an indication or to know if it's worth going hunting.

Good findEdited by CaptainBoing 2018-05-04
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 08:25am 03 May 2018
Copy link to clipboard 
Print this post

I've done a lot of research trying to find an accurate but simple enough routine
I've found a few examples but they are all too complex for me to decipher
From what I've found the enclosed C code 2018-05-03_182843_LunarPhase.zip
seems to be very accurate
it's part of this program which calculates planatery hours
I can't convert C to MM Basic accurately though

Another good accurate one is this page but it's too complex for me to try and find the right part of it to use.

This one also is reasonably accurate but it's in Python and I can't convert from that

Ideally I'd like the Lunar day in numbers but quarters/half/full would do

Edited by lew247 2018-05-04
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2139
Posted: 11:58am 03 May 2018
Copy link to clipboard 
Print this post

  lew247 said  

Ideally I'd like the Lunar day in numbers but quarters/half/full would do



you have that above but the small inaccuracies are down (I am convinced) to the single precision maths of MMBasic. Unless you are using an MMX (or CMM?)

here is an example :

> a=0.5
> ? a
0.5
>
> a=694039.09
> ? a
694039


see how the variable can't hold the detail AND the significant digits? this will definitely affect any scientific grade calculations... it is a microcontroller after all, need to keep expectation in perspective.

There are possibly ways around this, but then you aren't going top get a precise function is seven lines of code (how simple do you want?)
Edited by CaptainBoing 2018-05-04
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10066
Posted: 02:28pm 03 May 2018
Copy link to clipboard 
Print this post

MM+ is also now double precision in Geoff's latest release.

The attached seems to work well. The phases aren't strictly correct as Full, Third quarter, new, and first quarter are strictly only one day - see this reference

Note that you can include the hour in the call to moonphase and this can be a float so you can get the precise times of the various phases. The attached uses hour = 0, i.e.the start of the day specified.

  Quote  > RUN
2018 May 1 99.01% Full
2018 May 2 96.04% Waning Gibbous
2018 May 3 91.31% Waning Gibbous
2018 May 4 85.09% Waning Gibbous
2018 May 5 77.67% Waning Gibbous
2018 May 6 69.32% Waning Gibbous
2018 May 7 60.29% Third Quarter
2018 May 8 50.85% Third Quarter
2018 May 9 41.26% Third Quarter
2018 May 10 31.81% Third Quarter
2018 May 11 22.83% Waning Crescent
2018 May 12 14.72% Waning Crescent
2018 May 13 7.95% Waning Crescent
2018 May 14 3.00% New
2018 May 15 0.35% New
2018 May 16 0.35% New
2018 May 17 3.17% New
2018 May 18 8.69% Waxing Crescent
2018 May 19 16.56% Waxing Crescent
2018 May 20 26.22% Waxing Crescent
2018 May 21 37.01% First Quarter
2018 May 22 48.28% First Quarter
2018 May 23 59.42% First Quarter
2018 May 24 69.89% Waxing Gibbous
2018 May 25 79.25% Waxing Gibbous
2018 May 26 87.12% Waxing Gibbous
2018 May 27 93.24% Waxing Gibbous
2018 May 28 97.44% Full
2018 May 29 99.64% Full
2018 May 30 99.85% Full
2018 May 31 98.14% Full
>



option explicit
option default none
dim integer k, a%
dim phase$(7)=("New", "Waxing Crescent","First Quarter","Waxing Gibbous", "Full", "Waning Gibbous", "Third Quarter", "Waning Crescent")
for k=1 to 31:? "2018 May ",k,str$(moon_phase(2018,5,k,0,a%),3,2)+"% ",phase$(a%):next k
end
function Julian(year as integer,month as integer,day as float) as float
' Returns the number of julian days for the specified day.
local integer a,b=0,c,e
if month < 3) then
year=year-1
month =month+12
endif
if (year > 1582 OR (year = 1582 and month>10) or (year = 1582 and month=10 and day > 15)) then
a=year/100
b=2-a+a/4
endif
c = 365.25*year
e = 30.6001*(month+1)
Julian= b+c+e+day+1720992.5
end function

function sun_position(j as float) as float
local float n,x,e,l,dl,v
local float SMALL_FLOAT
local integer i
SMALL_FLOAT=2.718281828^(-12)
n=360/365.2422*j
i=n\360
n=n-i*360.0
x=n-3.762863
if x<0 then x = x+ 360
x=rad(x)
e = x
do
dl = e - 0.016718 * sin(e) - x
e = e - dl/ (1 - 0.016718 * cos(e))
loop while abs(dl)>=SMALL_FLOAT
v=360/PI*atn(1.01686011182*tan(e/2))
l=v+282.596403
i=l\360
l=l-i*360.0
sun_position= l
end function

function moon_position(j as float, ls as float) as float

local float ms,l,mm,n,ev,sms,ae,ec
local integer i

ms = 0.985647332099 * j - 3.762863
if ms < 0 then ms =ms + 360.0
l = 13.176396 * j + 64.975464
i = l \ 360
l = l - i * 360.0
if l < 0 then l = l + 360.0
mm = l - 0.1114041 * j - 349.383063
i = mm \ 360
mm = mm - i * 360.0
n = 151.950429 - 0.0529539 * j
i = n \ 360
n = n- i * 360.0
ev = 1.2739 * sin(RAD((2*(l-ls)-mm)))
sms = sin(RAD(ms))
ae = 0.1858*sms
mm =mm+ ev-ae- 0.37*sms
ec = 6.2886*sin(RAD(mm))
l =l + ev + ec -ae + 0.214 * sin(RAD(2*mm))
l= 0.6583*sin(RAD(2*(l-ls)))+l
moon_position= l
end function

function moon_phase(year as integer,month as integer,day as integer, hour as float, ip as integer) as float


' Calculates more accurately than Moon_phase , the phase of the moon at
' the given epoch.
' returns the moon phase as a real number (0-1)
'

local float j= Julian(year,month,day+hour/24.0)-2444238.5
local float ls = sun_position(j)
local float lm = moon_position(j, ls)

local float t = lm - ls
if t < 0 then t = t + 360
ip = INT((t + 22.5)/45) AND 7
moon_phase = ((1.0 - cos(RAD(lm - ls)))/2)*100
end function
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 05:48pm 03 May 2018
Copy link to clipboard 
Print this post

Wow
That's impressive

Edited by lew247 2018-05-05
 
piclover
Senior Member

Joined: 14/06/2015
Location: France
Posts: 134
Posted: 10:23pm 03 May 2018
Copy link to clipboard 
Print this post

  lew247 said  
This one also is reasonably accurate but it's in Python and I can't convert from that[/quote]
This is the same algorithm as the one I converted from PHP (see my post above).Edited by piclover 2018-05-05
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 06:33am 04 May 2018
Copy link to clipboard 
Print this post

  piclover said  This is the same algorithm as the one I converted from PHP (see my post above).


I had to change line 80 to [quote]Lm=TO_DEG*(ATN(y)/ ATN(x))+NP[/quote]

The results of both for today

Piclover's Moon: 83% 18.8d (number of days since last new moon)

Matherp's 2018 May 4 85.10% Waning Gibbous
Edited by lew247 2018-05-05
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:17pm 04 May 2018
Copy link to clipboard 
Print this post

Anyone able to tell me why I cannot get this to work?
It always prints the last item (Waning Crescent) and never the correct one
I've tried every combination I can think of including VAL(STR(moonage)) changing the numbers to strings and using STR(moonage) and every combination I can think of with IF and ELSE IF

I know I could use Peter's code but this one is very accurate
[quote]'Global variables declaration
cls
OPTION EXPLICIT
' tz is the time zone (e.g. 2.0 for UTC+2)
' moonphase is the percentage of the moon disk that is lit
' moonage is the number of days since last new moon
DIM FLOAT tz,moonphase,moonage

' Constants
CONST TO_DEG=57.2957795131
CONST TO_RAD=1.74532925199e-2

tz=0.0
ComputeMoonPhase()
PRINT "Moon: "+STR$(moonphase*100.0,2,0)+"% "+STR$(moonage,2,1)+"d"
MoonImage


Sub MoonImage
if moonage < 1.5 then
Text 280,310, "New Moon" , LB,4, 1, RGB(white)
endif

if moonage > 1.5 < 2.75 then
Text 280,310, "Waxing Crescent" , LB,4, 1, RGB(white)
endif

if moonage > 2.75 < 4 then
Text 280,310, "Waxing Crescent" , LB,4, 1, RGB(white)
endif

if moonage > 4 < 6.4 then
Text 280,310, "Waxing Crescent" , LB,4, 1, RGB(white)
print val(STR$(moonage,2,1))
endif

if moonage > 6.4 < 8 then
Text 280,310, "First Quarter" , LB,4, 1, RGB(white)
endif

if moonage > 8 < 10 then
Text 280,310, "Waxing Gibbous", LB,4, 1, RGB(white)
endif

if moonage > 10 < 12 then
Text 280,310, "Waxing Gibbous" , LB,4, 1, RGB(white)
endif

if moonage > 12 < 14 then
Text 280,310, "Waxing Gibbous" , LB,4, 1, RGB(white)
endif

if moonage > 14 < 15.25 then
Text 280,310, "Full Moon" , LB,4, 1, RGB(white)
endif

if moonage > 15 < 18 then
Text 280,310, "Waning Gibbous" , LB,4, 1, RGB(white)
endif

if moonage > 18 and moonage < 20 then
Text 280,310, "Waning Gibbous" , LB,4, 1, RGB(white)
print moonage " test"
endif

if moonage > 20 < 22.3 then
Text 280,310, "Waning Gibbous" , LB,4, 1, RGB(white)
endif

if moonage > 22.3 < 24 then
Text 280,310, "Last Quarter" , LB,4, 1, RGB(white)
endif

if moonage > 24 < 26 then
Text 280,310, "Waning Crescent" , LB,4, 1, RGB(white)
endif

if moonage > 26 < 28. then
Text 280,310, "Waning Crescent" , LB,4, 1, RGB(white)
endif

if moonage > 28 then
Text 280,310, "Waning Crescent" , LB,4, 1, RGB(white)
ENDIF
End sub

' Computes the number of Julian days elapsed since 2000-01-01 12:00 UTC for
' date d$ and time t$ (leave the latter empty to get the elapsed time in full
' days). Note: t$ is the local time (the time zone is subtracted from it).
FUNCTION JD2000(d$,t$)
LOCAL FLOAT jd
LOCAL INTEGER day,month,year,hour,min,sec
day=VAL(LEFT$(d$,2)):month=VAL(MID$(d$,4,2)):year=VAL(RIGHT$(d$,4))-2000
jd=365*year+(year+3)\4+275*month\9-((month+9)\12)*(1+((year MOD 4)+2)\3)+day-31
IF LEN(t$)=8 THEN
hour=VAL(LEFT$(t$,2))-tz:min=VAL(MID$(t$,4,2)):sec=VAL(RIGHT$(t$,4))
jd=jd+hour/24.0+min/1440.0+sec/3600.0
ENDIF
JD2000=jd
END FUNCTION

SUB ComputeMoonPhase()
LOCAL FLOAT jd,N,M,Ec,Ls,ml,MM,MN,Ev,Ae,A3,MmP,mEc,A4,lP,V,lPP,NP,y,x
LOCAL FLOAT Lm,BM,delta
' Constants for the Sun and the Moon at julian date 1980-01-00
CONST MAfactor=0.9856473321
CONST Elonge=278.83354
CONST Elongp=282.596403
CONST Eccent=0.016718
CONST Eccent2=1.016860112
CONST Mlfactor=13.1763966
CONST Mmlong=64.975464
CONST MMfactor=0.1114041
CONST Mmlongp=349.383063
CONST Mlnode=151.950429
CONST MNfactor=0.0529539
CONST Evfactor=1.2739
CONST Aefactor=0.1858
CONST A3factor=0.37
CONST mEcfactor=6.2886
CONST A4factor=0.214
CONST Vfactor=0.6583
CONST NPfactor=0.16
CONST CosMinc=0.995970321:' COS(TO_RAD*5.145396)
CONST SinMinc=8.9683442e-2:' SIN(TO_RAD*5.145396)
CONST Synmonth=29.53058868
' Was 1e-6 in initial algorithm, but we only have simple precision floats
CONST EPSILON=1e-5
' 7306=days elapsed between 2000-01-01 and 1980-01-00=1979-12-31
jd=JD2000(DATE$,TIME$)+7306
N=MAfactor*jd:N=N-N\360*360.0
M=N+Elonge-Elongp:M=M-M\360*360.0:M=TO_RAD*M
Ec=M
DO
delta=Ec-Eccent*SIN(Ec)-M
Ec=Ec-delta/(1-Eccent*COS(Ec))
LOOP UNTIL ABS(delta)<=EPSILON
Ec=Eccent2*TAN(Ec/2.0):Ec=2*TO_DEG*ATN(Ec)
Ls=Ec+Elongp:Ls=Ls-Ls\360*360.0
ml=Mlfactor*jd+Mmlong:ml=ml-ml\360*360.0
MM=ml-MMfactor*jd-Mmlongp:MM=MM-MM\360*360.0
MN=Mlnode-MNfactor*jd
Ev=Evfactor*SIN(TO_RAD*(2*(ml-Ls)-MM))
Ae=Aefactor*SIN(M):A3=A3factor*SIN(M)
MmP=MM+Ev-Ae-A3
mEc=mEcfactor*SIN(TO_RAD*MmP):A4=A4factor*SIN(TO_RAD*2*MmP)
lP=ml+Ev+mEc-Ae+A4
V=Vfactor*SIN(TO_RAD*2*(lP-Ls)):lPP=lP+V
NP=MN-NPfactor*SIN(M)
y=SIN(TO_RAD*(lPP-NP))*CosMinc:x=COS(TO_RAD*(lPP-NP))
Lm=TO_DEG*(ATN(y)/ ATN(x))+NP
BM=TO_DEG*ASIN(SIN(TO_RAD*(lPP-NP))*SinMinc)
moonage=lPP-Ls
moonage=moonage-moonage\360*360.0:IF moonage<0 THEN moonage=moonage+360.0
moonphase=0.5-COS(TO_RAD*moonage)/2.0
moonage=Synmonth*moonage/360.0
END SUB[/quote]Edited by lew247 2018-05-05
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6219
Posted: 10:50pm 04 May 2018
Copy link to clipboard 
Print this post

Try this
  Quote  SUB MoonImage
IF moonage < 1.5 THEN
TEXT 280,310, "New Moon" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 2.75 THEN
TEXT 280,310, "Waxing Crescent" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 4 THEN
TEXT 280,310, "Waxing Crescent" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 6.4 THEN
TEXT 280,310, "Waxing Crescent" , LB,4, 1, RGB(WHITE)
PRINT VAL(STR$(moonage,2,1))
ELSEIF moonage < 10 THEN
TEXT 280,310, "Waxing Gibbous", LB,4, 1, RGB(WHITE)
ELSEIF moonage < 12 THEN
TEXT 280,310, "Waxing Gibbous" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 14 THEN
TEXT 280,310, "Waxing Gibbous" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 15.25 THEN
TEXT 280,310, "Full Moon" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 18 THEN
TEXT 280,310, "Waning Gibbous" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 20 THEN
TEXT 280,310, "Waning Gibbous" , LB,4, 1, RGB(WHITE)
PRINT moonage " test"
ELSEIF moonage < 22.3 THEN
TEXT 280,310, "Waning Gibbous" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 24 THEN
TEXT 280,310, "Last Quarter" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 26 THEN
TEXT 280,310, "Waning Crescent" , LB,4, 1, RGB(WHITE)
ELSEIF moonage < 28 THEN
TEXT 280,310, "Waning Crescent" , LB,4, 1, RGB(WHITE)
ELSE
TEXT 280,310, "Waning Crescent" , LB,4, 1, RGB(WHITE)
ENDIF
END SUB



Untested

Jim
VK7JH
MMedit
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2139
Posted: 06:57am 05 May 2018
Copy link to clipboard 
Print this post

  lew247 said   Anyone able to tell me why I cannot get this to work?



Only glanced at it but the syntax is all wrong in the IF statements. You have stuff like


if moonage > 2.75 < 4 then


but that makes no sense, It should be

if moonage > 2.75 and moonage < 4 then


This long list of IFs is quite inefficient too... consider using SELECT ... CASE ...

so the above would look like

Select Case moonage
Case 2.75 To 4
...



you can also dispense with a lot of the repetitive stuff by only taking action when you need to e.g.


Select Case moonage
Case 2.75 To 4
x$="Waxing Crescent"
Case ...
Case ...
etc...
End Select

Text 280,310,x$, LB,4, 1, RGB(white)



this is a lot faster as in your code each IF will be tested regardless of if you have already made a choice. With Select/Case the code doesn't execute the remainder of tests - it jumps out as soon as a decision has been made. The code is smaller and more compact by only having the Text.... on one line at the expense of a variable.

Also, you have holes in your moon phase tests... consider this:

if moonage > 24 < 26 then
Text 280,310, "Waning Crescent" , LB,4, 1, RGB(white)
endif

if moonage > 26 < 28. then
Text 280,310, "Waning Crescent" , LB,4, 1, RGB(white)
endif
[/code]

what if moonage is exactly 26?

Edited by CaptainBoing 2018-05-06
 
rave
Newbie

Joined: 24/02/2018
Location: United States
Posts: 28
Posted: 12:42am 07 May 2018
Copy link to clipboard 
Print this post

  lew247 said   Has anyone weitten code to calculate the Moon Phase for the Micromite or Micromite+?
I don't need anything complex like times or anything, just the phase on a given day


Here is MMBasic 4.5 program to display the moon phase:

http://fruitoftheshed.com/MMBasic.MOON-BAS-lunar-calendar-with-graphics-and-simple-GUI.ashx

Programmed for the colour maximite, the program displays the moon phase both in text and graphically, for dates after 1582.

The arithmetic is rather straightforward, no complex astrophysics software was used. No attempt was made to take the time zone of the viewer into account, but that does not matter too much to just calculate the moon phase as a rough measure anyway.

' return days since 01-01-0001 without Julian calendar correction
FUNCTION Days(d$)
LOCAL d,m,y,a
d = VAL(MID$(d$,1,2))
m = VAL(MID$(d$,4,2))
y = VAL(MID$(d$,7,4))
a = INT((14-m)/12)
m = m+12*a
y = y-a
Days = 365*y+INT(y/4)-INT(y/100)+INT(y/400)+INT((153*m-457)/5)+d-306
END FUNCTION

' returns the moon phase for phase 0<=p<=4
FUNCTION MoonPhase$(p)
IF p < 0.1 THEN
MoonPhase$ = "New"
ELSEIF p < 0.9 THEN
MoonPhase$ = "Waxing Crescent"
ELSEIF p < 1.1 THEN
MoonPhase$ = "First Quarter"
ELSEIF p < 1.9 THEN
MoonPhase$ = "Waxing Gibbous"
ELSEIF p < 2.1 THEN
MoonPhase$ = "Full"
ELSEIF p < 2.9 THEN
MoonPhase$ = "Waning Gibbous"
ELSEIF p < 3.1 THEN
MoonPhase$ = "Third Quarter"
ELSEIF p < 3.9 THEN
MoonPhase$ = "Waning Crescent"
ELSE
MoonPhase$ = "New"
ENDIF
END FUNCTION

d = Days(d$)+19
p = d/29.530588
p = p-INT(p)
phase = 4*p
PRINT MoonPhase$(phase)


- Rob
 
piclover
Senior Member

Joined: 14/06/2015
Location: France
Posts: 134
Posted: 02:10pm 08 May 2018
Copy link to clipboard 
Print this post

  lew247 said  
  piclover said  This is the same algorithm as the one I converted from PHP (see my post above).


I had to change line 80 to [quote]Lm=TO_DEG*(ATN(y)/ ATN(x))+NP[/quote][/quote]
Ah, yes, I forgot to include the ATAN2 function. Here it is:

FUNCTION ATAN2(y,x)
IF y<>0 THEN
ATAN2=2.0*ATN((SQR(x*x+y*y)-x)/y)
ELSEIF x>0 THEN
ATAN2=0
ELSE:REM Normally, it should cause an error for x=y=0
ATAN2=PI
ENDIF
END FUNCTION

Edited by piclover 2018-05-10
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 08:33pm 08 May 2018
Copy link to clipboard 
Print this post

  piclover said  
Ah, yes, I forgot to include the ATAN2 function. Here it is:

Thanks I didn't mention changing that, as it was so easy to do :)
It works brilliantly and it's accurate down to 0.001 of a Lunar day
 
piclover
Senior Member

Joined: 14/06/2015
Location: France
Posts: 134
Posted: 09:33pm 09 May 2018
Copy link to clipboard 
Print this post

  lew247 said  
  piclover said  
Ah, yes, I forgot to include the ATAN2 function. Here it is:

Thanks I didn't mention changing that, as it was so easy to do :)

Better using the function I wrote however, since it will never fail, while ATN(y)/ ATN(x) fails for x = 0...
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 265
Posted: 07:04pm 10 May 2018
Copy link to clipboard 
Print this post

Here's a link that provides more information about phases of the Moon

http://aa.usno.navy.mil/faq/docs/moon_phases.php
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025