UNO WiFi Rev2 Real Time Clock Link & Set to NTP & reset millis() [SOLVED: post #17]

I have a need to reset my UNO WiFi Rev2 millis() function at midnight each new day to clear accrued data based on a 24 hour timeframe that runs midnite to midnite.
Is there a way to use "rtc.setTime" in conjunction with a NTP timestamp request.
I know there is serial routines for setting the time in the timeLIB.h library but I want the UNO to update its time after rebooting from a power outage/interruption.
At its simplest millis() get reset at 1 second after midnight.
Any leads are appreciated....

No, you don't. Just grab the millis() value at 1 second after midnight and use that as the basis for the next day's worth of time calculations.

1 Like

Just save the value 1 second after midnight and subtract that from the timestamps during the day.

I am unclear about your suggestion. Does the UNO RTC "know" the time automatically by being on the LAN? Otherwise what is it referencing as far the current time of day?
I understand the bit about using the millis() value at 1 sec after midnight. Which leads to another question: how large does millis() grow to if the controller never experiences a power outage or is reset? I assume it just keeps storing the 'ginormous' value.

see post 4....

millis() is an unsigned long, which is a 32-bit unsigned binary number. Maximum value is 4294967295, after which it rolls over to 0. This takes a bit over 49 days. If you do the calculations correctly with unsigned math, you will not have any problems calculating time intervals between two values of millis() even if the time period crosses the rollover, as long as the interval does not exceed the rollover period.

You would need to get the time from an NTP server if the UNO WiFi Rev2 lost power, there is no battery backup for the internal RTC.

Your original Problem Statement was:

From that I made the assumption that you already had a way to know the real time and were asking "Once I see it's midnight, who do I reset millis()?"

Perhaps you state your real question more clearly.

An RTC is just like the clock on your wall. You set it once and then just keep reading from it.

The RTC gives you the time. millis tells you how long the board has been on. If you have the RTC and need the time of day then don't mess with millis at all.

10-4...thanks ou for that info...

I am doing that NTP timestamp retreival with an 8266. Will the same code work with the UNO if I reference the correct UNO library files?

Just to be clear, or you using an UNO, or an UNO WiFi Rev2? There is a major difference between the two.

UNO WiFi Rev2

I have installed and successfully ran:

WiFiUdpNtpClient.ino

Using localPort 2390 this gives me seconds since Jan1 1900, UNIX time, & UTC Time on serial terminal.
Does this code go ahead and update the processor time or do I need to do something with
RTC set time to make that happen?
Also I got a message to "Please upgrade the firmware." Is this a good idea [i assume using the firmware upgrader tool?
update: upgrade firmware was in regard to checking for "fv < WIFI_FIRMWARE_LATEST_VERSION" which may not apply to wifi Rev2...???

Note: Unfortunately this code is not compatible with UNO WiFi Rev2 the search continues...

Ok, it looks like after perusing the web and using google Chrome's new Generative AI search tool that this is what I am looking for to get the RTC set on the UNO WiFi Rev2:

...kudos to GitHub....

:

I took some code from a source off the web wrote by Tom Igoe (honestly do not remember where as I have been to so many locations looking for something to work with) and gutted it to
get the UNIX epoch time value. I am getting a good result on the
serial monitor.
Questions:

  1. Is this time request coming from the local server I am connected to for web access?
  2. Is it now just a matter of converting the millis() value to seconds
    and comparing that with the epoch time value to see if "X" period of time has transpired?
  3. Is the UNO Wifi Rev2 RTC updated with this value? I do not think so with the current code.
/*
    Setting the time using WiFi.getTime();

    WiFi.getTime() connects to network time servers and gets the
    UNIX epoch (seconds since 1/1/1970, 00:00:00). It then sets
    the realtime clock epoch with that time

    created 30 April 2019
    modified 26 Apr 2021
    by Tom Igoe
*/
#include <SPI.h>
#include <WiFiNINA.h> 
#include <time.h>
#include "arduino_secrets.h"

int reconnects = 0; // how many times you've reconnected to the network
int lastSecond;     // last second value, for watching passing seconds

unsigned long startTime;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  while (!Serial); 
  connectToNetwork();
}

void loop() {
  // if you disconnected from the network, reconnect:
  if (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, LOW);
    connectToNetwork();
  } 
}
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));
  // You're connected, turn on the LED:
  digitalWrite(LED_BUILTIN, HIGH);

  // set the time from the network:
  unsigned long epoch;
  do {
    Serial.println("Attempting to get network time");
    epoch = WiFi.getTime();
    delay(2000);
  } while (epoch == 0);

  startTime = epoch;

  // increment the reconnect count:
  reconnects++;
  Serial.println();
  Serial.print(" The time is: ");
   Serial.println(startTime);
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  Serial.print("  Signal Strength: ");
  Serial.println(WiFi.RSSI());
}

No. You're talking about two different clocks.

If you set your clock on the wall tot he correct time and then I come over for a visit. As soon as I walk in you also start a stopwatch. They're two completely different clocks. You can't then use a reading from one and a reading from the other to determine anything.

The RTC is like the clock on the wall that knows the real time.
millis() is the stopwatch. It only knows how long since it was started.

An Arduino doesn't even have the concept of "system time". That's a PC thing. Forget about that.

If you want to determine if a time period has elapsed then you must use the same clock both times.

You can use either clock. It doesn't matter.

You can check millis and record the value and then later check it again and subtract and you will know how long it has been.

You can take a unix timestamp and record it and then later take another time stamp and subtract and you will know how long it has been.

But you can't take a unix time stamp and compare it in any way with millis. They're two different clocks.

1 Like

No. Not in the code you have. You would need to set the time on the RTC once you get it from the web. There's a function for that but I don't have it in front of me. You should only have to do this once at setup and the RTC will keep good time as long as it has power.

But none of that has anything to do with millis. The RTC has nothing to do with millis. RTC keeps unix time for you. millis is milliseconds since last reset.

I understand the distinction now. So I am still in a quandry about doing a midnite timer reset. It looks like I am going to have to somehow get an NTP timestamp and set the Wifi Rev2 RTC and then trigger a flag to reset my millis() counter based on 1 second into the new chronological day.
There is not a lot of documentation related to the UNO WiFi Rev2 regarding its RTC and accessing it that I have found. The ESP32 has more info in that regard from what I can tell.

What is this midnight timer reset? No, you have an RTC. You don't ever need to reset anything. Ever. Do you run around the house every night at midnight resetting all your clocks?

You get the NTP timestamp and set the RTC once. Only once ever. If you keep a battery backup you can even take the line completely out of the code after that. The RTC will keep the unix time.

If you want to know how long it has been since midnight in order to take a timestamp, then you do unix time mod 86400.

secsSinceMidnight = unixTime % 86400;

That works every day all year long because unix time started at midnight.

You don't ever have to reset anything. You have a clock running. Just read it and get the number you need.

1 Like

I'm having difficulty finding any evidence that Uno Wifi Rev2 actually has a built-in R(eal) T(ime) C(lock).

What's called the "RTC" in the ATMEGA4809 datasheet is a 16-bit R(eal) T(ime) C(ounter).

Looking at the Uno Wifi Rev2's schematic, I see no on-board RTC.

If anyone has such evidence, please post it.

That line of code may be the ticket. Here is how I am currently doing it with an ESP32 and your suggestion may be much simpler:

#include "hashtag_includes.h"  // see tabs at top
#include "constants.h"

void setTimezone(const char* timezone) {
  Serial.print("Setting Timezone to ");
  Serial.println(timezone);
  setenv("TZ", timezone, 1);
  tzset();
}

void initTime(const char* timezone) {
  struct tm timeinfo;

  Serial.println("Getting time from NTP server");
  configTime(0, 0, "pool.ntp.org");  // First connect to NTP server, use 0 TZ offset
  if (!getLocalTime(&timeinfo)) {
    Serial.println("  Failed to obtain time");
    return;
  }
  Serial.println("OK, Got the time from NTP");
  setTimezone(timezone);  // then set your timezone
}

void printLocalTime() {  // this function monitors current time of day to initiate
                         // pump counter reset at midnight
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  int time_hour = timeinfo.tm_hour;  // tm structure element "hour" from time.h
  int time_min = timeinfo.tm_min;    //                     "minute"  "    "
  int time_sec = timeinfo.tm_sec;    //                      "second"

  if (time_hour == hour_trigger && time_min == min_trigger && time_sec == sec_trigger) {
    Serial.println("Reset counters...");
    counter_reset = true;
    delay(1000);  // used to avoid conflict as time rolls over to new day
  }

  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z ");
}

I found this:

https://github.com/arduino/ArduinoCore-megaavr/issues/27