Go Down

Topic: Sonnenaufgangszeit rechnen (Read 1 time) previous topic - next topic

r_robert

Code: [Select]
// accompanies thread in German Arduino forum: http://forum.arduino.cc/index.php?topic=313942.0
// Compare results against: http://www.esrl.noaa.gov/gmd/grad/solcalc/
// Results are reasonable, but not too accurate, so do not use this for scientific purposes!

#include <avr/pgmspace.h> // save RAM with AVR/Atmega controllers in some functions using PROGMEM
#include <Wire.h>  // include Wire library for I2C devices
#include "jursRTCtimeEasy.h" // include RTC time library
#include "sunrise.h" // include library for sunrise/sunset calculations

/*void serialTask()
{ // Check Serial input for time setting command
  char* command=readSerialCommand();
  if (command!=NULL) // we have found a command from Serial
  {
    Serial.print(command);Serial.print('\t');
    if (strncmp_P(command,PSTR("setc "),5)==0 || strncmp_P(command,PSTR("setd "),5)==0) // compare for command
    {
      if (handleRtcCommand(command)) Serial.println(F("OK"));
      else Serial.println(F("ERROR: invalid time not set"));
    }
    else Serial.println(F("Unknown command")); // handle other commands here
  }
}
*/

enum {DAY, NIGHT, DAWN};
int getDayState(sTime time, int dawn, int sunrise, int sunset, int dusk)
{ // returns DAY, NIGHT or DAWN value, depending on time and sun position
  int minuteAfterMidnight= time.bHour*60+time.bMinute;
  if (minuteAfterMidnight>=sunrise && minuteAfterMidnight<sunset) return DAY;
  else if (minuteAfterMidnight<dawn || minuteAfterMidnight>=dusk) return NIGHT;
  else return DAWN;
}
 
#define UPDATEINTERVAL 10000  // milliseconds
#define LAT 46.95  // latitude in degrees, south is negative (used in sun calculation)
#define LON 15.05  // longitude in degrees, west is negative (used in sun calculation)

const char timeFormat[] PROGMEM="%02d.%02d.%04d  %02d:%02d:%02d";
void rtcTask()
{
  static unsigned long lastUpdate; // remember last time this function has run
  sTime time; // variable to hold current time/timezone
  char buf[61]; // variable for output formatting
  if (millis()-lastUpdate>=UPDATEINTERVAL)
  {
    lastUpdate+=UPDATEINTERVAL;
   
    RTCreadLocalTime(time); // read localTime (use summertime, if applicable)
    snprintf_P(buf,sizeof(buf),timeFormat,time.bDay,time.bMonth,time.iYear,time.bHour,time.bMinute,time.bSecond);
    if (time.sTimezone==TIMEZONE+1); // strcat(buf," *"); // indicates summertime
    Serial.println(buf);   // show it on serial

    // now do the calculation for dawn/sunrise/sunset/dusk times today
    int sunrise, sunset, dawn, dusk;
    sunCalc(time.iYear,time.bMonth,time.bDay,time.sTimezone, LAT, LON, sunrise, sunset, dawn, dusk);

    snprintf_P(buf, sizeof(buf), PSTR("Dawn: %02d:%02d,  Sunrise: %02d:%02d,  Sunset: %02d:%02d,  Dusk: %02d:%02d"), dawn/60, dawn%60, sunrise/60, sunrise%60, sunset/60, sunset%60, dusk/60, dusk%60);
    Serial.println(buf);

       

    // Finally find out whether we have DAY, NIGHT or TWILIGHT time of the day
    switch (getDayState(time, dawn, sunrise, sunset, dusk))
    {
      case DAY: Serial.println("DAY");break;
      case NIGHT: Serial.println("NIGHT");break;
      default:  Serial.println("TWILIGHT");break;
      Serial.println(dawn);
    }
    Serial.println();
   
  } 
}

 
/*void usage()
{ // show some information about program usage
  Serial.println(F("\nRTC date and time library demo by 'jurs' for German Arduino forum\n"));
  Serial.println(F("Usage for setting RTC date/time from Serial monitor in format"));
  Serial.println(F("\nOr you can use German date formatting with the 'setd' command:"));
  Serial.println(F("setd 24.12.2016 9:30:12     (24. Dezember 2016 um 9:30:12 Uhr)"));
  Serial.println(F("Time setting is in local time during summertime!\n\n"));
}
*/

void setup()
{
  Serial.begin(9600);
//  usage();
  if (RTCinit()) Serial.println(F("RTC OK"));
  else Serial.println(F("RTC/I2C ERROR"));
}

void loop()
{
//  serialTask();
  rtcTask();
}



Hallo, ich hab folgenden Sonnenaufgang Sketch in Verwendung. Nun würde ich gern mit der Sonnenaufgangszeit bzw. Untergangszeit weiterrechnen. Will nämlich für meinen Hühnerstall eine zusätzliche Beleuchtung im Stall einschalten wenn zwischen Sonnenaufgangzeit und Untergangszeit <16h liegen.
Wie kann ich sowas am Besten angehen? DANKE

gregorss

Wie kann ich sowas am Besten angehen? DANKE
if(sonnenuntergangszeit-sonnenaufgangszeit < 16)
{
  beleuchtungeinschalten();
}


Gruß

Gregor
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

r_robert

#2
May 26, 2020, 09:57 pm Last Edit: May 26, 2020, 09:58 pm by r_robert
Die Sonneuntergangszeit bekomme ich aber getrennt (Minuten und Stunden extra) aus dem obrigen Sketch. Brauch ich hier nicht eine zusammengefügte Variable?

Code: [Select]
int sunrise, sunset, dawn, dusk;
    sunCalc(time.iYear,time.bMonth,time.bDay,time.sTimezone, LAT, LON, sunrise, sunset, dawn, dusk);

    snprintf_P(buf, sizeof(buf), PSTR("Dawn: %02d:%02d,  Sunrise: %02d:%02d,  Sunset: %02d:%02d,  Dusk: %02d:%02d"), dawn/60, dawn%60, sunrise/60, sunrise%60, sunset/60, sunset%60, dusk/60, dusk%60);
    Serial.println(buf);

postmaster-ino

Hi

Du bekommst alle vier Werte in 'Minute am Tag' - Die kann man direkt miteinander verrechnen, man muß halt schauen, ob die Differenz 'die in 16 Stunden enthaltenen Minuten' überschreitet.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

r_robert

Dann wäre der Code so?

Code: [Select]
if(sunrise-sunset< 960)
{
  beleuchtungeinschalten();
}

postmaster-ino

Hi

Wenn Du in UNSIGNED rechnest, passt Das immer.
sunrise - Sonnenaufgang
sunset - Sonnenuntergang
dawn - Morgen- Dämmerung
dusk - Abend-Dämmerung
Jeweils als 'Startminute'.
Wenn müsstest Du sunset-sunrise nutzen, oder?

Da der Sonnenuntergang wohl erst nach dem Aufgang kommt, ist Das der größere Wert.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

r_robert

Hallo
ja stimmt ich muss  sunset-sunrise  rechnen.
Wie könnte ich mit der Uhrzeit (z.B.: von der sunset) anstatt UNSIGNED wirklich als Uhrzeit ausgeben und damit rechnen? Danke schon wieder einmal vorab :-)

postmaster-ino

Hi

Reine Theorie!
So wie ich Das verstehe, gibt die Funktion die Zeitpunkte als 'Minute am Tag' zurück.

Wenn her Sonnenaufgang um 6:00h, ist der Wert wohl 360.
Wenn der Sonnenuntergang nun um 18:00h ist, dieser Wert wohl 1080.
Die Differenz wäre 720, was geteilt durch 60 - Du ahnst Es schon, 12 (Stunden) ergibt.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

r_robert

Hab das jetzt einmal via serialprint ausgegeben.
So bekomme ich bei der Sunrise nur 5 anstatt 5:13Uhr heraus

Quote
27.05.2020  21:50:46
Dawn: 04:42,  Sunrise: 05:13,  Sunset: 20:41,  Dusk: 21:12
sunrise: 313
sunrise/60: 5


postmaster-ino

Hi

Wie hat denn der Erbauer der Funktion die Minuten_am_Tag wieder in Stunden und Minuten umgewandelt?

Stunden per Division
Minuten per Modulo

Was willst Du nun aber mit den Stunden und Minuten? Damit lässt sich nur schwer rechnen.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

my_xy_projekt

#10
May 27, 2020, 10:42 pm Last Edit: May 27, 2020, 10:43 pm by my_xy_projekt
So bekomme ich bei der Sunrise nur 5 anstatt 5:13Uhr heraus
Stimmt. Das macht genau das, was Du willst.
Das was Du suchst, nennt sich Rest einer Division.

Code: [Select]

unsigned long sunrise=313;

void setup() {
  Serial.begin(115200);
  Serial.println(sunrise%60);
  // put your setup code here, to run once:
}

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


Den Rest bekommst Du hin ;)

r_robert

Code: [Select]
snprintf_P(buf, sizeof(buf), PSTR("Dawn: %02d:%02d,  Sunrise: %02d:%02d,  Sunset: %02d:%02d,  Dusk: %02d:%02d"), dawn/60, dawn%60, sunrise/60, sunrise%60, sunset/60, sunset%60, dusk/60, dusk%60);

ich habs jetzt so ausgeben probiert
Code: [Select]
Serial.print("Sunrise: %02d:%02d "),dawn/60, dawn%60;

Kann ich die Stunden (5) und Minuten (13) nicht irgendwie in eine Variable zusammenfassen?

my_xy_projekt

Kann ich die Stunden (5) und Minuten (13) nicht irgendwie in eine Variable zusammenfassen?
????
Du hast die doch in einer Variablen.
Das rausrechnen kannst Du jederzeit wiederholen.

r_robert

Quote
void setup() {
  Serial.begin(115200);
  Serial.println(sunrise%60);
  // put your setup code here, to run once:
}

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


Den Rest bekommst Du hin ;)
Warum muss ich das  Serial.println(sunrise%60); im setup ausführen?

my_xy_projekt

#14
May 27, 2020, 10:54 pm Last Edit: May 27, 2020, 10:58 pm by my_xy_projekt
Warum muss ich das  Serial.println(sunrise%60); im setup ausführen?
Musst Du nicht.
Ich wollte Dir zeigen, Wie Du zu der Ausgabe kommst, die Du benötigst.
Im Loop würde das die ganze Zeit den Ser.Mon zuschieben.

[edit]
OH entschuldige, Du hast nicht mitbekommen, das meine Variable sunrise oben zum Code gehörte. War mein Fehler beim formatieren.
Wenn Du jetzt den vollständigen Code nimmst und bei Dir ausführst, dann bekommst Du die Lösung.
[/edit

Go Up