Time.h - timeStatus()

Hallo zusammen :slight_smile:

Mit einem ESP8266 NodeMCU Amica beziehe ich die aktuelle Uhrzeit von einem Server per NTP. Das funktioniert soweit super. Ein setSyncInterval(600) sorgt dafür, dass die Uhrzeit alle 10 Minuten synchronisiert wird. Nun habe ich in der Dokumentation die Funktion timeStatus() gesehen und frage mich, ob ich damit nicht einen Sync “bei Bedarf” realisieren kann. In der Dokumentation steht, dass diese Funktion eine 1 zurück liefert (so deute ich das jedenfalls), wenn die Uhrzeit nicht mehr synchron zu der auf dem Server ist.

Denke ich hier falsch? Für mein Projekt reicht mir eine Genauigkeit im Bereich von ein, zwei Minuten und daher würde ein wesentlich längerer Synchronisaionsintervall (z. B. drei, vier mal täglich) sicher ausreichen.

Viele Grüße vom
Schattenfänger

Da es mehrere Time.h gibt, solltest Du uns einen Link geben, welche Du einsetzt.

Gruß Tommy

Diese hier: GitHub - PaulStoffregen/Time: Time library for Arduino

War mir gar nicht bewusst, dass eh mehrere gibt. Sorry.

Durch die Statusabfrage wird kein Sync zwischen den syncIntervallen angestoßen.
Wenn Du einen externen NTP-Server nutzt, kann es Dir mit Abfrage aller 10 Minuten sehr schnell passieren, dass Du dort gesperrt wirst.
Unter 1 Stunde sollte man nicht gehen. 4 Stunden genügen auch.

Gruß Tommy

timeStatus ist ein enum mit 3 Werten:

typedef enum {timeNotSet, timeNeedsSync, timeSet
}  timeStatus_t ;

Wenn du eine Synchronisation erzwingen willst, setze in deinem Programm im gewissen Abständen den Status auf timeNotSet

setTimeStatus(timeNotSet);

Damit wird die Zeit erneut vom NTP-Server geholt.

const int NTP_PACKET_SIZE = 48;     // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address) {
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
               // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, local_timePort); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

bool getNtpTime(char* ntpServerName) {
  Serial.print("NTP request...");
  if (timeStatus() == timeSet) {
    Serial.println(F(" not necessary"));
    return true;
  }
 
  IPAddress ntpServerIP; // NTP server's ip address
 
  while (Udp.parsePacket() > 0); // discard any previously received packets
  Serial.print(F("\r\nTransmit NTP Request"));
  // get a random server from the pool
  WiFi.hostByName(ntpServerName, ntpServerIP);
  Serial.print("\r\n" + String(ntpServerName) + ", IP: " + ntpServerIP.toString());
  sendNTPpacket(ntpServerIP);
  unsigned long beginWait = millis();
  while (millis() - beginWait < 3000) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.print(F("\r\nReceived NTP Response: "));
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 = (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      setTime(secsSince1900 - 2208988800UL);
      //setTime(23, 55, 0, 30, 3, 2016); //simulate time for test
      return true;
    }
  }
  Serial.print(F("\r\nFATAL ERROR: No NTP Response."));
  return false; // return 0 if unable to get the time
}

freddy64:
timeStatus ist ein enum mit 3 Werten:

typedef enum {timeNotSet, timeNeedsSync, timeSet

}  timeStatus_t ;

Falsch! Das enum heißt timeStatus_t. timeStatus() ist eine Methode.

Gruß Tommy

OK _t vergessen. SORRY

Bei mir gibt es keine Methoden. Das ist doch scheiß Krampf aus Java.

Es sind alles Funktionen, egal ob void foo() oder int foo() oder sonst was.
void foo() ist eine Funktion, die keinen Wert zurück liefert.

Was ist, wenn einer "Methode" ein Zeiger übergeben wird, dessen Wert in der "Methode" geändert wird?

void foo(int &bar) {
bar = 55;
}

Ist das eine Methode oder eine Funktion?

Der Unterschied zwischen einer Funktion und einer Methode ist dass eine Methode zu einem Objekt gehört und daher den this-Zeiger auf ihr Objekt als versteckten Parameter hat. Der Unterschied ist an manchen Stellen wichtig. Vor allem bei Funktionszeigern

Aber ich zeige doch immer auf ein Objekt, wenn ich auf darin enthaltene Variablen oder Funktionen (wenn sie public sind) zugreifen will.

myObject obj();
obj.foo();
obj. bar = 1;

wenn die Variablen protected sind, müssen eben Funktionen wie get() und set() vorhanden sein, um auf Eigenschaften des Objektes zuzugreifen

Wie ich es von der Windows Programmierung her kenne:
auf dem Stack -> wie oben
Nach Ablauf der Gültigkeit des Objektes wird dieses automatisch im Speicher gelöscht

auf dem Heap
myObject obj = new myObject();

obj->foo();

wenn das Objekt nicht mehr benötigt wird:
delete obj;

Wenn man delete vergisst, zeigt das der Debugger nach Programmende an.
Detected memory leaks...
Object created in file xxx line yyy but not deleted.

Das ist ein Gesetz der Programmierer:
Verlasse den Speicher so, wie du ihn vorgefunden hast !!!

Ist aber heutzutage bei den vielen GB Arbeitsspeicher egal. Immer rein mit dem Schrott und wenn der Kasten nicht mehr will -> Neustart.
Java ist das Beste Beispiel dafür.
Die Softwarefirma erspart sich die Kompilierung und den Vertrieb für die verschiedenen Betriebssysteme.
Der Endanwender bekommt graue Haare, weil er 5 mal täglich den PC neu starten muss.

Man kann (wenn man kann) mit JAVA serverseitig stabile Applikationen bauen.
Wenn man aber den Unterschied zwischen Funktion unf Methode nicht begreifen will, dann wird das nicht funktionieren.

Egal in welcher Programmiersprache.

Gruß Tommy

Das hat mit dem Thema überhaupt nichts zu tun

Und C++ ist Speicherlecks weit fehleranfälliger als Java

Klar, weil JAVA den Aufräumer hat.
Mir ging es eigentlich nur um seine Ignorierung des Unterschiedes zwischen Methode und Funktion. Wenn das nicht so rüber gekommen ist - mein Fehler.

Gruz Tommy

War auch gar nicht auf dich bezogen :slight_smile: Mein Betrag ist nur eine Minute älter als deiner

Klar, weil JAVA den Aufräumer hat.

Genau.....

Schon mal in einer Firma als Admin gearbeitet, wo 50 ehemalige Hausfrauen in Teilzeit mit der "ultimativen Java Scheiße" arbeiten müssen?

Viel Spaß

Nö, aber Server mit JAVA stabil am Laufen gehabt.
Wenn Ihr Hausfrauen an die Programmentwicklung setzt, ist die Sprache egal. Es geht schief.

Was ist denn das für eine seltsame Firma? Die kann aber nicht als Vergleich für normale Entwicklung gelten.

Gruß Tommy