Monitoring getTime() for successful retrieval of network timestamp?

I am using the function getTime() to acquire the UNIX epoch time off
the local network and then use function setTime() to load the UNO WiFi Rev2 RTC. This is accomplished in the void setup() section. My concern regards reinitialization after a power outage. It takes several minutes for my LAN router to start back up after losing power. If there is a problem securing the local network timestamp by the UNO I do not want it sit in a while loop for an extended period if getTime() requests are going unanswered. I would rather it continue on to the void loop() without the RTC being set.
Any suggestions on how to handle this contingency?

#include <SPI.h>
#include <WiFiNINA.h>
#include <TimeLib.h>
#include "arduino_secrets.h"

int reconnects = 0;  // how many times you've reconnected to the network

unsigned long epoch;
unsigned long actualTime;
unsigned long oldTime;

void setup() {
  Serial.begin(115200);

  connectToNetwork();
 do {
    Serial.println("Attempting to get network time");
    epoch = WiFi.getTime();
    delay(5000);
  } while (epoch == 0);

  int hr = ((epoch - 18000) % 86400L) / 3600;
  int min = (epoch % 3600) / 60;
  int sec = (epoch % 60);

  setTime(hr, min, sec, 1, 1, 1);  // set UNO RTC; day, month, year not needed
}

void loop() {
  actualTime = now();  // get actual system timestamp

  if (actualTime != oldTime) {  // make actions if flag is fired:

    oldTime = actualTime;

    Serial.println();
    Serial.print("RTC: Hour = ");
    Serial.print(hour(actualTime));
    Serial.print("/ Minute = ");
    Serial.print(minute(actualTime));
    Serial.print("/ Second = ");
    Serial.println(second(actualTime));

    int HOUR = hour(actualTime);
    int MINUTE = minute(actualTime);
    int SECOND = second(actualTime);

    if (HOUR == 23 && MINUTE == 59 && SECOND >= 58) {
      // set runtime counters to zero
      Serial.println();
      Serial.println("Midnight is upon us. Reset counters. ");

    } else {
      Serial.println();
      Serial.println("Not time yet. ");
    }
    delay(2000);  // wait on system time to rollover
  }
}

void connectToNetwork() {
  // try to connect to the network:
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("Attempting to connect to: " + String(SECRET_SSID));
    //Connect to WPA / WPA2 network:
    WiFi.begin(SECRET_SSID, SECRET_PASS);
    delay(2000);
  }
  Serial.println("connected to: " + String(SECRET_SSID));
  
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  Serial.print("  Signal Strength: ");
  Serial.println(WiFi.RSSI());

  // increment the reconnect count:
  reconnects++;
}

I do a similar thing but I use a RTC module with a battery so it keeps great time. Every day or so I check it against NTP and so far the worse has been about one second.

You are not using the AT4809 real time counter, you are just setting the time library to an external time, and it is advanced by the millis() timer.

As @gilshultz says, the way to be sure to recover from a power outage without waiting for network connection is to use a DS3231

1 Like

It was my understanding the WiFi Rev2 has an onboard crystal/ Real Time Clock. Not just a counter.

What does it mean when you say "setting the time library?" How is the time library utilized as a
clock in essence?
It matters not I suppose as long as the setTime() function successfully executes. I just do not want the "do - while" loop of the getTime function getting stuck and hanging the processor up.

It is a counter based on a reasonably accurate oscillator which can be set to trigger an interrupt. It is not like what most people consider to be a RealTimeClock(RTC) like the DS3231 which keeps time/day/year values in storage registers.
http://ww1.microchip.com/downloads/en/AppNotes/AN2711-RTCC-calibration-and-compensation-on-AVR-MCUs-00002711A.pdf

You could use it a a clock source as an alternative to the millis() based on the system timer but the accuracy of the two methods would need to be tested.

I think you are just fine using setTime() with the TimeLibrary. If the accuracy is not good enough over long periods, you can set the TimeLibrary synchProvider to use the time you get from WiFi.getTime().

1 Like

That is a good idea. I am displaying the RTC [Real Time Counter now instead of Real Time Clock] on my webpage so I can track it fairly easily. The sync function could become handy at
some point. :+1:

You have an RTC on your board. I feel like we've discussed this before. A few times.

Do you know what an RTC is? Do you know what it does?

Does RTC in relation to the WiFi Rev2 mean Real Time Clock or Real Time Counter?

For consideration:

Update for use RTC ATMEGA4809 circuit embedded in Arduino Uno WiFi rev 2 #122

https://github.com/PaulStoffregen/Time/issues/122

Features:

  • use internal RTC circuit for real clock in board (not based on millis() function)
  • additional attach/detach interrupt function to run user function at adjustable freq. synchronized by RTC
  • adjustable top syncho between RTC and real second when setTime is called
  • 100% compatible with 328p code (run without RTC) if interrupt are not used

Current limitation:

  • use only external quartz for the moment.

There is a fork of the Stoffregen library which supports using the counter as a clock source as an alternative to millis().

https://github.com/goodchip/Time

It has not been merged into the main branch.

There were some early issues with the external crystal clock on the WiFi Rev2 and there is a long thread about problems with the RTC here

https://forum.arduino.cc/t/atmega4809-rtc-module/571988

I do not really see the advantage of wandering off the main path of using the millis() timer with network updates unless you know what you are doing. I do not think the RTC registers are persistent through a power cessation.

If power failures and time keeping is the main issue, then the DS3231 is the answer.

I concur. I have something that is working and for just resetting counters at midnite the getTime()/setTime() approach is plenty adequate.

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