I just used a triangle wave to represent the cos() term. Please feel free to modify the program, check the result against accurate calculations and let us know how that improves the result.

Note that not only does the length of the lunar cycle vary from 29.5309 days, the actual illumination depends on the position of the Sun relative to the observer's position, similar to the calculations in the following more complicated, somewhat more precise program EDIT: (not for Arduino):

```
/* standalone moon phase calculation */
// accurate to about 2% of "fraction illuminated" as compared to the U.S. Navy Astronomical
// Applications Department web page http://aa.usno.navy.mil/data/docs/MoonFraction.php
#include <stdio.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795
#define RAD (PI/180.0)
#define SMALL_FLOAT (1e-12)
typedef struct {
int year,month,day;
double hour;
} TimePlace;
void JulianToDate(TimePlace* now, double jd)
{
long jdi, b;
long c,d,e,g,g1;
jd += 0.5;
jdi = jd;
if (jdi > 2299160) {
long a = (jdi - 1867216.25)/36524.25;
b = jdi + 1 + a - a/4;
}
else b = jdi;
c = b + 1524;
d = (c - 122.1)/365.25;
e = 365.25 * d;
g = (c - e)/30.6001;
g1 = 30.6001 * g;
now->day = c - e - g1;
now->hour = (jd - jdi) * 24.0;
if (g <= 13) now->month = g - 1;
else now->month = g - 13;
if (now->month > 2) now->year = d - 4716;
else now->year = d - 4715;
}
double
Julian(int year,int month,double day)
{
/*
Returns the number of julian days for the specified day.
*/
int a,b,c,e;
if (month < 3) {
year--;
month += 12;
}
if (year > 1582 || (year == 1582 && month>10) ||
(year == 1582 && month==10 && day > 15)) {
a=year/100;
b=2-a+a/4;
}
c = 365.25*year;
e = 30.6001*(month+1);
return b+c+e+day+1720994.5;
}
double sun_position(double j)
{
double n,x,e,l,dl,v;
double m2;
int i;
n=360/365.2422*j;
i=n/360;
n=n-i*360.0;
x=n-3.762863;
if (x<0) x += 360;
x *= RAD;
e=x;
do {
dl=e-.016718*sin(e)-x;
e=e-dl/(1-.016718*cos(e));
} while (fabs(dl)>=SMALL_FLOAT);
v=360/PI*atan(1.01686011182*tan(e/2));
l=v+282.596403;
i=l/360;
l=l-i*360.0;
return l;
}
double moon_position(double j, double ls)
{
double ms,l,mm,n,ev,sms,z,x,lm,bm,ae,ec;
double d;
double ds, as, dm;
int i;
/* ls = sun_position(j) */
ms = 0.985647332099*j - 3.762863;
if (ms < 0) ms += 360.0;
l = 13.176396*j + 64.975464;
i = l/360;
l = l - i*360.0;
if (l < 0) l += 360.0;
mm = l-0.1114041*j-349.383063;
i = mm/360;
mm -= i*360.0;
n = 151.950429 - 0.0529539*j;
i = n/360;
n -= i*360.0;
ev = 1.2739*sin((2*(l-ls)-mm)*RAD);
sms = sin(ms*RAD);
ae = 0.1858*sms;
mm += ev-ae- 0.37*sms;
ec = 6.2886*sin(mm*RAD);
l += ev+ec-ae+ 0.214*sin(2*mm*RAD);
l= 0.6583*sin(2*(l-ls)*RAD)+l;
return l;
}
double moon_phase(int year,int month,int day, double hour, int* ip)
{
/*
Calculates the phase of the moon at
the given epoch.
returns the moon phase as a real number (0-1)
*/
double j= Julian(year,month,(double)day+hour/24.0)-2444238.5;
double ls = sun_position(j);
double lm = moon_position(j, ls);
double t = lm - ls;
if (t < 0) t += 360;
*ip = (int)((t + 22.5)/45) & 0x7;
return (1.0 - cos((lm - ls)*RAD))/2;
}
static void nextDay(int* y, int* m, int* d, double dd)
{
TimePlace tp;
double jd = Julian(*y, *m, (double)*d);
jd += dd;
JulianToDate(&tp, jd);
*y = tp.year;
*m = tp.month;
*d = tp.day;
}
main()
{
int y, m, d;
int m0;
int h;
int i;
double step = 1;
int begun = 0;
double pmax = 0;
double pmin = 1;
int ymax, mmax, dmax, hmax;
int ymin, mmin, dmin, hmin;
double plast = 0;
printf("tabulation of the phase of the moon for one month\n\n");
printf("year: "); fflush(stdout);
scanf("%d", &y);
printf("month: "); fflush(stdout);
scanf("%d", &m);
d = 1;
m0 = m;
printf("\nDate Time Phase Segment\n");
for (;;) {
double p;
int ip;
for (h = 0; h < 24; h += step) {
p = moon_phase(y, m, d, h, &ip);
if (begun) {
if (p > plast && p > pmax) {
pmax = p;
ymax = y;
mmax = m;
dmax = d;
hmax = h;
}
else if (pmax) {
printf("%04d/%02d/%02d %02d:00 (fullest)\n",
ymax, mmax, dmax, hmax);
pmax = 0;
}
if (p < plast && p < pmin) {
pmin = p;
ymin = y;
mmin = m;
dmin = d;
hmin = h;
}
else if (pmin < 1) {
printf("%04d/%02d/%02d %02d:00 (newest)\n",
ymin, mmin, dmin, hmin);
pmin = 1.0;
}
if (h == 16) {
printf("%04d/%02d/%02d %02d:00 %5.1f%% (%d)\n",
y, m, d, h, floor(p*1000+0.5)/10, ip);
}
}
else begun = 1;
plast = p;
}
nextDay(&y, &m, &d, 1.0);
if (m != m0) break;
}
return 0;
}
```