SkobyMobil:
ist ja nett, das Du mir helfen möchtest- aber ich bekomme nicht einmal
ein "C-Programm" in den Arduino. Aber wohin damit?
Ich kann zwar C&P, aber die Fehler die dort dann auflaufen…
Das ist noch ne´ NUMMER zu groß!
Arduino-Sketche sind auch nur C-Programme.
Aus "main()" wird für einen Arduino-Sketch einfach mal "setup()" und die Ausgabe leite ich auf die serielle Schnittstelle, schon läßt sich das Programm kompilieren und ohne größere Änderungen auf den Arduino hochladen:
// C-Programm von http://lexikon.astronomie.info/zeitgleichung/neu.html
// umgeschrieben auf Arduino by 'jurs' for German Arduino forum
double pi2=6.283185307179586476925286766559;
double pi=3.1415926535897932384626433832795;
double RAD = 0.017453292519943295769236907684886;
double JulianischesDatum ( int Jahr, int Monat, int Tag,
int Stunde, int Minuten, double Sekunden )
// Gregorianischer Kalender
{
int Gregor;
if (Monat<=2)
{
Monat=Monat +12;
Jahr = Jahr -1;
}
Gregor = (Jahr/400)-(Jahr/100)+(Jahr/4); // Gregorianischer Kalender
return 2400000.5+365.0*Jahr - 679004.0 + Gregor
+ int(30.6001*(Monat+1)) + Tag + Stunde/24.0
+ Minuten/1440.0 + Sekunden/86400.0;
}
double InPi(double x)
{
int n = (int)(x/pi2);
x = x - n*pi2;
if (x<0) x +=pi2;
return x;
}
double eps(double T) // Neigung der Erdachse
{
return RAD*(23.43929111 + (-46.8150*T - 0.00059*T*T + 0.001813*T*T*T)/3600.0);
}
double BerechneZeitgleichung(double &DK,double T)
{
double RA_Mittel = 18.71506921
+ 2400.0513369*T +(2.5862e-5 - 1.72e-9*T)*T*T;
double M = InPi(pi2 * (0.993133 + 99.997361*T));
double L = InPi(pi2 * ( 0.7859453 + M/pi2
+ (6893.0*sin(M)+72.0*sin(2.0*M)+6191.2*T) / 1296.0e3));
double e = eps(T);
double RA = atan(tan(L)*cos(e));
if (RA<0.0) RA+=pi;
if (L>pi) RA+=pi;
RA = 24.0*RA/pi2;
DK = asin(sin(e)*sin(L));
// Damit 0<=RA_Mittel<24
RA_Mittel = 24.0*InPi(pi2*RA_Mittel/24.0)/pi2;
double dRA = RA_Mittel - RA;
if (dRA < -12.0) dRA+=24.0;
if (dRA > 12.0) dRA-=24.0;
dRA = dRA* 1.0027379;
return dRA ;
}
void setup()
{
Serial.begin(9600);
double JD2000 = 2451545.0;
double JD;
JD = JulianischesDatum(2005,9,30,12,0,0); // Testdatum
/*
// manuelle Dateneingabe
int year, month, day;
cout << "Berechnung Sonnenufgang und -untergang" << endl;
cout << "Jahr (YYYY): "; cin >> year;
cout << "Monat (MM): "; cin >> month;
cout << "Tag (DD): "; cin >> day;
JD = JulianischesDatum(year,month,day,12,0,0);
*/
double T = (JD - JD2000)/36525.0;
double DK;
double h = -50.0/60.0*RAD;
double B = 50.0*RAD; // geographische Breite
double GeographischeLaenge = 10.0;
//double Zeitzone = 0; //Weltzeit
//double Zeitzone = 1; //Winterzeit
double Zeitzone = 2.0; //Sommerzeit
double Zeitgleichung = BerechneZeitgleichung(DK,T);
double Minuten = Zeitgleichung*60.0;
double Zeitdifferenz = 12.0*acos((sin(h) - sin(B)*sin(DK)) / (cos(B)*cos(DK)))/pi;
double AufgangOrtszeit = 12.0 - Zeitdifferenz - Zeitgleichung;
double UntergangOrtszeit = 12.0 + Zeitdifferenz - Zeitgleichung;
double AufgangWeltzeit = AufgangOrtszeit - GeographischeLaenge /15.0;
double UntergangWeltzeit = UntergangOrtszeit - GeographischeLaenge /15.0;
double Aufgang = AufgangWeltzeit + Zeitzone; // In Stunden
if (Aufgang<0.0) Aufgang +=24.0;
else if (Aufgang>=24.0) Aufgang -=24.0;
double Untergang = UntergangWeltzeit + Zeitzone;
if (Untergang<0.0) Untergang +=24.0;
else if (Untergang>=24.0) Untergang -=24.0;
int AufgangMinuten = int(60.0*(Aufgang - (int)Aufgang)+0.5);
int AufgangStunden = (int)Aufgang;
if (AufgangMinuten>=60.0) { AufgangMinuten-=60.0; AufgangStunden++; }
else if (AufgangMinuten<0.0) {
AufgangMinuten+=60.0; AufgangStunden--;
if (AufgangStunden<0.0) AufgangStunden+=24.0;
}
int UntergangMinuten = int(60.0*(Untergang - (int)Untergang)+0.5);
int UntergangStunden = (int)Untergang;
if (UntergangMinuten>=60.0) { UntergangMinuten-=60.0; UntergangStunden++; }
else if (UntergangMinuten<0) {
UntergangMinuten+=60.0; UntergangStunden--;
if (UntergangStunden<0.0) UntergangStunden+=24.0;
}
Serial.print("Aufgang ");
Serial.print(AufgangStunden);
Serial.print(":");
if (AufgangMinuten<10.0) Serial.print("0");
Serial.print(AufgangMinuten);
Serial.println();
Serial.print("Untergang ");
Serial.print(UntergangStunden);
Serial.print(":");
if (UntergangMinuten<10.0) Serial.print("0");
Serial.print(UntergangMinuten);
// Vergleich mit CalSky.com
// Aufgang : 7h18.4m Untergang : 19h00.6m
}
void loop()
{}
Die Stellenzahl der Konstanten sind natürlich für den Arduino nur Fake, denn die einfach genauen Gleitkommazahlen sind nur auf 6 bis 7 signifikante Stellen genau.
Wenn ich die Tage mal Zeit finde, mache ich daraus mal eine schön mit Parametern aufrufbare Funktion.
Und wie ich gerade sehe, kann man dasselbe Programm nicht nur zur Berechnung der Sonnenauf- und Untergangszeiten verwenden, sondern mit einer relativ einfachen Erweiterung auch zur Berechnung von Dämmerungszeiten. Wenn man für die Konstante "h" nämlich andere Werte als -50 Bogenminuten ansetzt, könnte man auch die Zeiten für die bürgerliche, nautische und/oder astronomische Dämmerung errechnen:
Also die Zeiten, zu denen man nach Sonnenuntergang (bzw. vor Sonnenaufgang) noch im Freien Zeitung lesen kann, bei freiem Blick auf den Horizont noch die Horizontlinie erkennen kann, oder ab wann es pechschwarze Nacht ist. Obwohl das natürlich nur Rechenwerte wären, die nichts über die tatsächliche Helligkeit während der Dämmerung aussagen, da die Helligkeit nach Sonnenuntergang auch stark von der Bewölkung abhängig ist.
Die Zeiten für den Beginn der Morgendämmerung oder das Ende der Abenddämmerung brauchst Du nicht, sondern nur Sonnenaufgang und Sonnenuntergang? Oder sollten auch die Zeiten der Morgen-/Abenddämmerung berechnet werden können?