Mondphasen berechnen

Hallo,

ich versuche mithilfe des Arduinos und "simpler" Mathematik (synodische Periode) die aktuelle Mondphase zu berechnen.
Dafür muss ich die Zeitspanne eines vergangenen Vollmondes, bis zum jetztigen Zeitpunkt (RTC) ausrechnen.
Das Problem:
Ich habe noch nicht mit Zeit gerechnet. Mein bisheriger Ansatz war der Versuch, alle Jahre, Monate, Tage, usw. einzelnt auszurechnen (siehe mein Code).
Das das sehr unschön aussieht brauche ich wohl keinem zu sagen, davon mal abgesehen, funktioniert es nicht. Der Code spuckt immer falsche Ergebnisse aus. Richtig Falsch. Nicht nur um ein paar Tage, wie ich es noch verstehen könnte, da meine Berechnung ja sehr ungenau ist (ein Monat = 30,5 Tage).
Ich habe versucht mit verschiedenen Libarys meine Zeitrechnung zu schreiben, aber wirklich voran komme ich nicht, auch weil nicht alle mit dem RTC Modul kompatibel sind?...

Wäre schön wenn mir jemand helfen könnte.

LG :slight_smile:

Tage_Seit_Letztem_Vollmond = ((Time.year() - LastFullmoonYear) * 365.00)    +    ((Time.month() - LastFullmoonMonth) * 30.5)    +    (Time.day() - LastFullmoonDay)    +    ((Time.hour() - LastFullmoonHour) / 24.00);



void MoonUpdate() {                                                                                         // bestimme den Status des Mondes (Akutelle Phase)

    double MoonPhaseAsFloat = MoonUpdateDouble();
    Serial.println("Calculated moon result: " + String(MoonPhaseAsFloat,2));
    if(MoonPhaseAsFloat == 0.0) 
      MoonPhaseAsFloat = 1.00;
      
    if(MoonPhaseAsFloat < 0.25)                                                                             // Abnehmender Dreiviertel Mond
    {
      Serial.println("Abnehmender Dreiviertel Mond");
      MoonPhase = 5;
    }
    else if (MoonPhaseAsFloat == 0.25)                                                                      // Abnehmender Halbmond
    {
      Serial.println("Abnehmender Halbmond");
      MoonPhase = 6;
    }
    else if(0.25 < MoonPhaseAsFloat && MoonPhaseAsFloat < 0.50)                                             // Abnehmende Sichel
    {
      Serial.println("Abnehmende Sichel");
      MoonPhase = 7;
    }
    else if(MoonPhaseAsFloat == 0.50)                                                                       // Neumond
    {
      Serial.println("Neumond");
      MoonPhase = 0;
    }
    else if(0.50 < MoonPhaseAsFloat && MoonPhaseAsFloat < 0.75)                                             // Zunehmende Sichel
    {
      Serial.println("Zunehmende Sichel");
      MoonPhase = 1;
    }
    else if(MoonPhaseAsFloat == 0.75)                                                                       // Zunehmender Halbmond
    {
      Serial.println("Zunehmender Halbmond");
      MoonPhase = 2;
    }
    else if(0.75 < MoonPhaseAsFloat && MoonPhaseAsFloat < 1.00)                                             // Zunehmender Dreiviertel Mond
    {
      Serial.println("Zunehmender Dreiviertel Mond");
      MoonPhase = 3;
    }
    else //MoonPhaseAsFloat == 1                                                                            // Vollmond
    {
      Serial.println("Vollmond");
      MoonPhase = 4;
    }
}

double MoonUpdateDouble()                                                                                   // Berechne die Aktuelle Mondphase (1 = Vollmond / 0.5 = Neumond)
{
  double dDaySinceLastFullmoon = Tage_Seit_Letztem_Vollmond / 29.53;
  int iToHundret = (dDaySinceLastFullmoon - int(dDaySinceLastFullmoon)) * 100;
  return (double) iToHundret / 100; //Needed to get only 2 decimal places
}

Bin mit diesem Code zufrieden:

// Moon phase, takes three parameters: the year (4 digits), the month and the day.
// The function returns fraction full, float 0-1 (e.g. 0 for new, .25 for crescent, .5 for quarter, .75 for gibbous and 1 for full).
// Also calculates phase and age in days. This version uses a cosine function to model the illumination fraction.
// Calculated at noon, based on new moon Jan 6, 2000 @18:00, illumination accurate to about 5%, at least for years 1900-2100.
// Modified from post at http://www.nano-reef.com/topic/217305-a-lunar-phase-function-for-the-arduino/
// S. J. Remington 11/2016

float MoonPhase(int nYear, int nMonth, int nDay) // calculate the current phase of the moon
{
  float age, phase, frac, days_since;
  long YY, MM, K1, K2, K3, JD;
  YY = nYear - floor((12 - nMonth) / 10);
  MM = nMonth + 9;
  if (MM >= 12)
  {
    MM = MM - 12;
  }
  K1 = floor(365.25 * (YY + 4712));
  K2 = floor(30.6 * MM + 0.5);
  K3 = floor(floor((YY / 100) + 49) * 0.75) - 38;
  JD = K1 + K2 + nDay + 59;  //Julian day
  if (JD > 2299160) //1582, Gregorian calendar
  {
    JD = JD - K3;
  }

  // Serial.print(" JD ");  //Julian Day, checked OK
  // Serial.print(JD);
  // Serial.print(" ");

  days_since = JD - 2451550L; //since noon on Jan. 6, 2000 (new moon @18:00)
  phase = (days_since - 0.25) / 29.53059; //0.25 = correct for 6 pm that day
  phase -= floor(phase);  //phase in cycle
  age = phase * 29.53059;

  // calculate fraction full
  frac = (1.0 - cos(phase * 2 * PI)) * 0.5;

  // Serial.print("Moon Age ");
  // Serial.print(age);

  return frac; //phase or age or frac, as desired
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (int i = 1; i < 32; i++) {  // lunar calendar for month
    Serial.print("2016 Dec ");
    Serial.print(i);
    float frac = MoonPhase(2016, 12, i);
    Serial.print(" Moon phase ");
    Serial.println(frac);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}
2 Likes

:warning:
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
mfg ein Moderator.

Danke :slight_smile:

Was muss ich ändern um den Standort / die Startzeit (Orientierungs Voll/Neumond) zu verändern?

LG

Die Formel basiert auf ganzen Tagen. Sie sagt dir also nicht, um wieviel Uhr genau Vollmond ist.
Sie gibt dir einen ganzen Tag lang genau dieselbe Mondphase zurück.
Am nächsten Tag hat sich phase um ca. 0,033863 verändert und frac ändert sich zwischen 0.03 und 0.1 täglich.
Wenn du ihr generell traust, müsstest du noch verifizieren, auf welche Zeitzone sich das angegebene "18:00 Uhr" ( -0.25 ) bezieht. Und dort bei Bedarf etwas ändern.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.