Sonnenaufgangszeit rechnen

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

r_robert:
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.

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 :wink:

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

Serial.print("Sunrise: %02d:%02d "),dawn/60, dawn%60;

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

r_robert:
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.

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 :wink:

Warum muss ich das Serial.println(sunrise%60); im setup ausführen?

r_robert:
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

Hi

WAS willst Du wirklich?
Entweder hast Du absolut nicht verstanden, welche Informationen Dir die Lib liefert, oder ich Dein Problem nicht.
if (sunset-sunrise>=16*60){
//mache was, wenn zwischen SonneAUFgang und SonnenUNTERgang mindestens 16 Stunden liegen
}

Die Rückgabewerte sind Zahlen von 0 bis 1439 (ein Tag hat 1440 Minuten).
Somit ist die Differenz dieser Werte ebenfalls in Minuten.
Dann musst Du nur noch diese Differenz mit der von Dir gedachten Zeit (in Minuten) vergleichen.

MfG

in Stunden und Minuten wäre es einfach übersichtlicher, aber ich rechnen nun einfach in Minuten weiter... Ist glaub ich das einfachste.
Danke für eure Hilfe..

[Ps.: Bin leider erst Anfänger beim Programmieren.. :slight_smile: ]

r_robert:
[Ps.: Bin leider erst Anfänger beim Programmieren.. :slight_smile: ]

leider? erst?
Nicht doch!

postmaster-ino hat recht, wenn es um die Rechnerei innerhalb deines Codes geht.
Ich habe Dir gezeigt, wie Du an die fehlenden Daten bei der Ausgabe kommst.

Ich gebe mir aus Überzeugung Mühe jedem weiterzuhelfen. Und das tuen hier auch viele andere. Da spielt es keine Rolle, ob "Anfänger" oder "Fortgeschrittener" (Ab wann ist man das?)

r_robert:
in Stunden und Minuten wäre es einfach übersichtlicher, ...

Für Dich schon, weil Du es so gewohnt bist, ein µC sieht das aber ganz anders, denn der kann nur binär. Daher rechnen auch bekannte Tabellenkalkulationen mit Sekunden seit 1900 oder seit 1970 (Unixzeit). Man muß sich klar machen, daß Zeit immer relativ1) ist. Wir geben die Tageszeit relativ zu Mitternacht an, ebenso wie das christliche Datum relativ zur Geburt eines Menschen2). Die Entstehung unseres Universims als absoluten Nullpunkt der Zeit wäre eventuell eine Möglichkeit, aber selbst die PTB in Braunschweig hat da keine passende Uhr.

Der leider in Forum nicht mehr aktive jurs hat allerdings Zeiten auch als ganze Zahlen gespeichert. Beispielsweise 20:15 Uhr als Zahl 2015. Eine Divisuion durch 100 bringt die Stunden, Modulo 100 die Minuten. Das hat durchaus praktischen Nutzen.

Rechnen würde ich, wie schon gesagt, in Minuten, Anzeige dann in hh:mm. Eine kleine Funktion kann helfen:

char zeit[] = {"00:00"};

char * zeitanzeige(uint16_t minuten) {
  byte h = minuten / 60;
  byte m = minuten % 60;
  snprintf(zeit, sizeof(zeit), "%2d:%2d", h, m);
  return zeit;
}

void setup()
{
  Serial.begin(115200);
  Serial.println("Anfang");
}

void loop() {
  static uint16_t zeitinminuten = (10 * 60) + 44;
  Serial.println(zeitinminuten);
  Serial.println(zeitanzeige(zeitinminuten));
  zeitinminuten++;
  delay(1000UL * 60);
}

Anm.:

  1. Ganz unabhängig von Überlegungen zur Raumzeit der Relativitätstheorie!
  2. Wobei Jesus tatsächlich wohl nicht im Jahr 0 geboren wurde.

EDIT: "1000" geändert in "100" siehe #19. Danke!

agmue:
Der leider in Forum nicht mehr aktive jurs hat allerdings Zeiten auch als ganze Zahlen gespeichert. Beispielsweise 20:15 Uhr als Zahl 2015. Eine Division durch 1000 bringt die Stunden, Modulo 1000 die Minuten. Das hat durchaus praktischen Nutzen.

Müsste es nicht 100 sein, statt 1000?

so bin nun endlich wieder einmal dazugekommen bei meiner Lichtsteuerung für den Hühnerstall weiterzumachen.

if {sonnenuntergang-sonnenaufgang<=960min) => Licht einschalten

Wie schaffe ich es dann das falls das licht eingeschalten wird, es sich nach 16 Stunden (inkl. Tageslicht) wieder ausschaltet?
Muss ich irgendwie in einer Schleife hochzählen?

r_robert:
Wie schaffe ich es dann das falls das licht eingeschalten wird, es sich nach 16 Stunden (inkl. Tageslicht) wieder ausschaltet?
Muss ich irgendwie in einer Schleife hochzählen?

Was heisst incl. Tageslicht?
Du möchtest, das nach 16 Stunden die Lampe ausgeht?

Dann:
Zeit merken. gemerkte Zeit mit der aktuellen Zeit prüfen Wenn aktuelle Zeit >16 Stunden als gemerkte Zeit -> Licht aus.

in millisekunden gerechnet:
1000ms -> 1sek
60sek -> 1min
60min -> 1h
also millis() merken und wenn millis()-gemerktemills nach 10006060*16 stimmt, dann Licht aus.

Das Licht soll erst dann eingehen wenn die hühnerklappe geschlossen wird, davor gibt es eh Tageslicht..

Die Zeit muss ich mir in der if Abfrage von "Licht ein" merken oder?
Wie merk ich mir die Zeit? (blöde Frage :frowning: )

r_robert:
Das Licht soll erst dann eingehen wenn die hühnerklappe geschlossen wird, davor gibt es eh Tageslicht..

Die Zeit muss ich mir in der if Abfrage von "Licht ein" merken oder?
Wie merk ich mir die Zeit? (blöde Frage :frowning: )

Ok, das Licht soll erst dann AN gehen, wenn Klappe zu?
Das ist zu lösen, ist aber hier nicht Aufagbe.

Wenn also:
if {sonnenuntergang-sonnenaufgang<=960min)
{
// Licht einschalten
// Zeit merken
// Eine Statusvariable setzen

if (statsuvariable gesetzt UND millis()-gemerkteZeit>16 Stunden)
[
// Licht ausschalten
// Statusvariable löschen

Das geht auch einfacher; u.a. wenn der Sonnenaufgang früher als nach 16Std kommt, das Tageslicht da ist, kann Licht aus und Statusvariable gelöscht werden.. usw.

hab das jetzt im Code wie folgt ergänzt. Die Lampe schaltet aber nicht aus... Hab die 960 zum Testen auch schon mal um einige runtergeschraubt... hab ich irgendwo eine Fehler im Code?

   if (diff <= 960 && digitalRead(pinendtasterunten) == _pushed )
 {
  Serial.print("lampe einschalten");
   digitalWrite(pinlicht, _AN);
   Zeit = millis();
   Serial.print("Zeit: ");
   Serial.println(Zeit);
   Statusvariable = 1;
   Serial.print("Statusvariable: ");
   Serial.println(Statusvariable);
   Serial.print("millis()-Zeit: ");
   Serial.println(millis()-Zeit);
 } 
  if (Statusvariable == 1 && millis()-Zeit>960)
  {
   digitalWrite(pinlicht, _AUS);
   Serial.print("lampe ausschalten");
   Statusvariable = 0;
   Serial.print("Statusvariable: ");
   Serial.println(Statusvariable);
   Serial.print("millis()-Zeit: ");
   Serial.println(millis()-Zeit);
  }
 
  }

r_robert:
hab ich irgendwo eine Fehler im Code?

Wenn der Code compiliert, ist er erstmal fehlerfrei.
Der Fehler liegt wohl eher in der Logik.

Was heisst "geht nicht aus"
Dafür gäbe es zwei Gründe:

  1. _pushed ist immer true
  2. Zeit wird irgendwoanders erneut gesetzt

Ich denke es ist 1.
Du musst vermeiden, das die erste Bedingung immer wieder erfüllt wird.
Das ginge wie folgt:
if ((diff <= 960) && (digitalRead(pinendtasterunten) == _pushed) && (Statusvariable == LOW) )

Wie Du siehst, ist bei mir Statusvariable ein boolcher Ausdruck. Mach das bitte auch. Und dann schreib true/false oder HIGH/LOW sonst erkennt man nicht, was das macht.

Mit der Prüfung der Statusvariablen wird die Bedingung nicht mehr erfüllt, wenn sie gesetzt ist.

Hallo,

in den älteren Threads wirst du fündig.

https://forum.arduino.cc/index.php?topic=313047.0

https://forum.arduino.cc/index.php?topic=313942.0

Kann es sein das ich "Zeit = millis()" nicht mit den "960 Minuten" vergleichen kann? ((millis()-Zeit > 960 )) Muss ich die millis in Minuten umrechen?

   if ((diff <= 960) && (digitalRead(pinendtasterunten) == _pushed) && (Status == LOW))
 {
  Serial.println("lampe einschalten");
   digitalWrite(pinlicht, _AN);
   Zeit = millis();
   Serial.print("Zeit: ");
   Serial.println(Zeit);
   Serial.print("digitalRead(pinmotorrunter): ");
   Serial.println(digitalRead(pinmotorrunter));
   Status = HIGH;
   Serial.print("Statusvariable: ");
   Serial.println(Status);
   Serial.print("millis()-Zeit: ");
   Serial.println(millis()-Zeit);
 } 
  if ((Status == HIGH) && (millis()-Zeit > 960 ))
  {
   digitalWrite(pinlicht, _AUS);
   Serial.println("lampe ausschalten");
   Status = LOW;
   Serial.print("Statusvariable: ");
   Serial.println(Status);
   Serial.print("millis()-Zeit: ");
   Serial.println(millis()-Zeit);
  }

millis sind Millisekunden. 960 Minuten sind

unsigned long intervall = 1000UL*60*960;

1000 ms * 60 Sekunden * 960 Minuten

UL wegen unsigned long

Gruß Tommy