Skip to content

Commit fe2163e

Browse files
committed
Add new function for moon illumination
1 parent d05ad91 commit fe2163e

File tree

2 files changed

+95
-7
lines changed

2 files changed

+95
-7
lines changed

src/Astronomy.cpp

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ See more at https://thingpulse.com
2525
#include <time.h>
2626
#include "Astronomy.h"
2727

28+
/* pi/180 */
29+
#define RPD 1.74532925199e-2
30+
2831
Astronomy::Astronomy() {
2932

3033
}
3134

3235
/**
33-
* Convenience method to calculate moonphase by unix time stamp.
34-
* See calculateMoonPhase(int year, int month, int day) for more details.
35-
*/
36+
* Convenience method to calculate moon phase by unix time stamp. See calculateMoonPhase(int year, int month, int day)
37+
* for details.
38+
*/
3639
uint8_t Astronomy::calculateMoonPhase(time_t timestamp) {
3740
struct tm* timeInfo;
3841
timeInfo = localtime(&timestamp);
@@ -78,3 +81,84 @@ uint8_t Astronomy::calculateMoonPhase(uint16_t year, uint8_t month, uint8_t day)
7881
phase = phase & 7; // 0 and 8 are the same so turn 8 into 0
7982
return phase;
8083
}
84+
85+
/**
86+
* Convenience method to calculate moon phase and illumination by unix time stamp. See
87+
* calculateMoonData(int year, int month, int day) for details.
88+
*/
89+
Astronomy::MoonData Astronomy::calculateMoonData(time_t timestamp) {
90+
struct tm* timeInfo;
91+
timeInfo = localtime(&timestamp);
92+
return calculateMoonData(timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, timeInfo->tm_mday);
93+
}
94+
/**
95+
* Calculates the moon phase and illumination for a given date, accurate to 1 segment.
96+
* The result is in the range 0..7 for the phase.
97+
* 0 => new moon
98+
* 4 => full moon
99+
* Illumination ranges from 0.0 (new moon) to 1.0 (full moon).
100+
*
101+
* Source: Hugh from https://www.voidware.com
102+
*/
103+
Astronomy::MoonData Astronomy::calculateMoonData(uint16_t year, uint8_t month, uint8_t day) {
104+
105+
MoonData moonData;
106+
107+
// from Gregorian year, month, day, calculate the Julian Day number
108+
uint8_t c;
109+
uint32_t jd;
110+
if (month < 3) {
111+
--year;
112+
month += 10;
113+
} else month -= 2;
114+
115+
c = year / 100;
116+
jd += 30.59 * month;
117+
jd += 365.25 * year;
118+
jd += day;
119+
jd += c / 4 - c;
120+
121+
// adjust to Julian centuries from noon, the day specified.
122+
double t = (jd - 730455.5) / 36525;
123+
124+
// following calculation from Astronomical Algorithms, Jean Meeus
125+
// D, M, MM from (47.2, 47.3, 47.3 page 338)
126+
127+
// mean elongation of the moon
128+
double D = 297.8501921 + t * (445267.1114034 +
129+
t * (-0.0018819 + t * (1.0 / 545868 - t / 113065000)));
130+
131+
// suns mean anomaly
132+
double M = 357.5291092 + t * (35999.0502909 + t * (-0.0001536 + t / 24490000));
133+
134+
// moons mean anomaly
135+
double MM = 134.9633964 +
136+
t * (477198.8675055 + t * (0.0087414 + t * (1.0 / 69699 - t / 14712000)));
137+
138+
// (48.4 p346)
139+
double i = 180 - D
140+
- 6.289 * sin(MM * RPD)
141+
+ 2.100 * sin(M * RPD)
142+
- 1.274 * sin((2 * D - MM) * RPD)
143+
- 0.658 * sin(2 * D * RPD)
144+
- 0.214 * sin(2 * MM * RPD)
145+
- 0.110 * sin(D * RPD);
146+
147+
if (i < 0) i = -i;
148+
if (i >= 360) i -= floor(i / 360) * 360;
149+
150+
// (48.1 p 345)
151+
// this is the proportion illuminated calculated from `i`, the phase angle
152+
double k = (1 + cos(i * RPD)) / 2;
153+
154+
// but for the `phase` don't use the phase angle
155+
// instead just consider the 0-360 cycle to get equal parts per phase
156+
uint8_t ki = i / 22.5;
157+
if (++ki == 16) ki = 0;
158+
ki = (ki / 2 + 4) & 7;
159+
160+
moonData.phase = ki;
161+
moonData.illumination = k;
162+
163+
return moonData;
164+
}

src/Astronomy.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,21 @@ See more at https://thingpulse.com
2626
#pragma once
2727
#include "Arduino.h"
2828

29-
typedef struct AstronomyData {
30-
31-
} AstronomyData;
3229

3330
class Astronomy {
3431
private:
3532

36-
3733
public:
34+
typedef struct MoonData {
35+
uint8_t phase;
36+
double illumination;
37+
} MoonData;
38+
3839
Astronomy();
40+
3941
uint8_t calculateMoonPhase(time_t timestamp);
4042
uint8_t calculateMoonPhase(uint16_t year, uint8_t month, uint8_t day);
43+
MoonData calculateMoonData(time_t timestamp);
44+
MoonData calculateMoonData(uint16_t year, uint8_t month, uint8_t day);
4145

4246
};

0 commit comments

Comments
 (0)