Cant set date to zero

Hi group,
Found this code here.
Now I want to set de curent-time to zero like this:

#include <TimeLib.h>
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println();
  setTime(0, 0, 0, 0, 0, 0);
}

But the date /time is set to:
0:00:00 31 12 1999 and not 0:00:00 00 00 0000
How do I get the day, month and year to zero(o)??

God only knows why you would want to do that, but it sounds like you just want to count elapsed time. In that event, you might just write a new set of dummy values starting from the clock's zero and subtract the "zero" from them each time round the loop. This might save some grief when dealing with the Julian calender.
It is likely that you don't need the clock at all, just the 1hz pip, and maybe don't need the library either.

There is no month 0 and day 0.

This library starts the year in 1970, the month in 1 and the day in 1.

  • Years start from 1970

Ref: GitHub - PaulStoffregen/Time: Time library for Arduino

Take a look at the source code for setTime():

void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
 // year can be given as full four digit year or two digts (2010 or 10 for 2010);  
 //it is converted to years since 1970
  if( yr > 99)
      yr = yr - 1970;
  else
      yr += 30;  
  tm.Year = yr;
  tm.Month = mnth;
  tm.Day = dy;
  tm.Hour = hr;
  tm.Minute = min;
  tm.Second = sec;
  setTime(makeTime(tm));
}

So a year parameter of 0 is recorded as 30 years past the Epoch or 2000. And, days of the month start at 1, not 0. So, the result makes perfect sense, your setting the time to 1 day before Jan 1, 2000. That's Dec 31, 1999.

1 Like

The short answer is: you don't.

The slightly longer answer is that the Unix epoch is the number of seconds elapsed since Jan 1, 1970 midnight UTC.

And if you look in the source at setTime, you'll see the following:

void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
 // year can be given as full four digit year or two digts (2010 or 10 for 2010);  
 //it is converted to years since 1970
  if( yr > 99)
      yr = yr - 1970;
  else
      yr += 30;  

So your year 0 gets converted to 30, which means 30 years past Jan 1, 1970. And since days are counted from 1, not 0, you end up on Dec 31, 1999 rather than Jan 1, 2000.

Edit: and I see I'm not the only one to know far more about the internals of Unix time than anyone ever wanted to know. :slight_smile:

And I am a 70year old beginner. So how do I create a one second counter??

unsigned long timer, timeout = 1000; // one second timeout

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

void loop() {
  if (millis() - timer > timeout) { // timeout has expired
    timer = millis(); // start new timer
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // change LED state
  }
}

RTCs typically have a 1Hz square wave output. That may be all you need. All Arduinos have an internal millisecond facility and you may not even need an RTC. If you were a bit more forthcoming about what you want to do, you will get all the support you need. At the moment you are just fartarsing around in the dark, and taking two forum threads to do it.
Defining "stuff" might be a good place to start...

So, this thread is nothing put a massive XY Problem.

1 Like

DDMMYYYY

I am a 75 year old, and I can even write some code for you, but I need to better understand your need.
After all, there is no day 0 and month 0.
Do you want to count the number of seconds, minutes, hours, days, months and years without taking into account the variation of months 28, 29, 30, 31 days and leap years?
Please describe your need in detail.

Ps:
see if this code help:


// Parts of this code was modified from : 
// https://github.com/PaulStoffregen/Time/blob/master/Time.cpp

#include <TimerOne.h>
const int led = LED_BUILTIN;  // the pin with a LED
volatile bool printOut = false;
volatile unsigned long blinkCount = 0; // use volatile for shared variables
volatile unsigned long myTime = 0;
unsigned int mySeconds = 0;
unsigned int myMinutes = 0;
unsigned int myHours = 0;
unsigned int myDay = 0;
unsigned int Wday = 0;
unsigned int myMonth = 0;
unsigned int myYear =  0;
//----------------------------------------------------------------
void setup() {
  pinMode(led, OUTPUT);
  //Timer1.initialize(100000);  // Test with velocity time x 10
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(blinkLED); // blinkLED to run every 1 seconds
  Serial.begin(9600);
}
//-------------------------------------------------------------------
void blinkLED() {
  blinkCount ++ ; // 1 second;
  //blinkCount += 60UL ; // test with  1 minute;  
  //blinkCount += 3600UL ; // test with 1 hour;
  //blinkCount += 3600UL * 24UL; // test with 1 day;
  digitalWrite(led, !digitalRead(led));
  printOut = true;
}
//-------------------------------------------------------------------
void loop() {
  if (printOut == true) {
    breakTime();
    if (myHours < 10)
      Serial.print("0");
    Serial.print(myHours);
    Serial.print(":");
    if (myMinutes < 10)
      Serial.print("0");
    Serial.print(myMinutes);
    Serial.print(":");
    if (mySeconds < 10)
      Serial.print("0");
    Serial.print(mySeconds);
    Serial.print(" ");
    if (myDay < 10)
      Serial.print("0");
    Serial.print(myDay);
    Serial.print("/");
    if (myMonth < 10)
      Serial.print("0");
    Serial.print(myMonth);
    Serial.print("/");
    if (myYear < 10)
      Serial.print("000");
    if (myYear >= 10 and myYear < 100)
      Serial.print("00");
    if (myYear >= 100 and myYear < 1000)
      Serial.print("0");
    Serial.print(myYear);
    Serial.print(" ");
    printOut = false;
    Serial.println(" ");
  }
}
//-------------------------------------------------------------------
#define LEAP_YEAR(Y)     ( (((Y))>0) && !(((Y))%4) && ( (((Y))%100) || !(((Y))%400) ) )
static  const uint8_t monthDays[] = {30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30}; // this array starts from 0
//-------------------------------------------------------------------
void breakTime() {
  uint8_t year;
  uint8_t month, monthLength;
  unsigned long days;

  myTime = blinkCount;
  mySeconds = myTime % 60;
  myTime /= 60; // now it is minutes
  myMinutes = myTime % 60;
  myTime /= 60; // now it is hours
  myHours = myTime % 24;
  myTime /= 24; // now it is days
  Wday = ((myTime + 4) % 7) + 1;  // Sunday is day 1

  year = 0;
  days = 0;
  while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= myTime) {
    year++;
  }
  myYear = year; // year is offset from 1970
  days -= LEAP_YEAR(year) ? 366 : 365;
  myTime  -= days; // now it is days in this year, starting at 0

  days = 0;
  month = 0;
  monthLength = 0;
  for (month = 0; month < 12; month++) {
    if (month == 1) { // february
      if (LEAP_YEAR(year)) {
        monthLength = 28;
      } else {
        monthLength = 27;
      }
    } else {
      monthLength = monthDays[month];
    }

    if (myTime >= monthLength) {
      myTime -= monthLength;
    } else {
      break;
    }
  }
  myMonth = month ;  // jan is month 1
  myDay = myTime ;     // day of month
}

First thanx for your answer but I think that the supplied code is a sort of overkill.
What I need is a clock that starts when the UNO starts and show that clock on a LCD. It should show seconds, minutes, hours and day's
Harry

Check out the millis function. It will give you the uptime in milliseconds. It just takes a little bitnof math if you want hours, minutes, and seconds from that. No libraries needed.

1 Like

You are absolutely right. Using millis() is very simple and does not require any additional library.
But there is a problem with millis():
The value of millis() returns to zero after 47 days 17 hours 2 minutes 47 seconds and 295 msec. Count equals Dec 4,294,967,295 Hex 0xFFFF FFFF.

If the Op does not need to count days greater than +- 48 days, then the solution with millis() is the best.

How many days at all?

THe LCD is I2C?

Even if he wants to run for more, surely in that 48 days there is time to update a second variable and keep track of the number of rollovers.

So you don't want a clock; you want something that shows the elapsed time since power on.

You'll have to massage this for your particular LCD library.

Five minute sketch: no warranty is expressed or implied.

#include <LiquidCrystal_I2C.h>

const uint8_t cols = 16;
const uint8_t rows = 2;
LiquidCrystal_I2C lcd(0x27);

void setup() {
   lcd.begin(cols, rows);
   lcd.backlight();
}

uint16_t seconds = 0, minutes = 0, hours = 0, days = 0;

void loop() {
   static uint32_t lastTime = -1000;
   static uint32_t count = 0;
   uint32_t now = millis();

   if( now - lastTime >= 1000 ) {
      lastTime = now;
      now = count;
      ++count;

      seconds = now % 60;
      now /= 60;
      minutes = now % 60;
      now /= 60;
      hours = now % 24;
      days = now / 24;

      lcd.home();
      lcd.print(days);
      lcd.print(':');
      if( hours < 10 ) {
         lcd.print('0');
      }
      lcd.print(hours);
      lcd.print(':');
      if( minutes < 10 ) {
         lcd.print('0');
      }
      lcd.print(minutes);
      lcd.print(':');
      if( seconds < 10 ) {
         lcd.print('0');
      }
      lcd.print(seconds);
   }
}

Try this code:

simulated at : Time_Day_LCD - Wokwi ESP32, STM32, Arduino Simulator


// Parts of this code was modified from :
// https://github.com/PaulStoffregen/Time/blob/master/Time.cpp

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);  // Display I2C 16x2
#include <TimerOne.h>
const int led = LED_BUILTIN;  // the pin with a LED
volatile bool printOut = false;
volatile unsigned long blinkCount = 0; // use volatile for shared variables
volatile unsigned long myTime = 0;
unsigned int mySeconds = 0;
unsigned int myMinutes = 0;
unsigned int myHours = 0;
unsigned int myDay = 0;

//----------------------------------------------------------------
void setup() {
  lcd.begin(16, 2);
  lcd.backlight();
  lcd.clear();
  pinMode(led, OUTPUT);
  //Timer1.initialize(100000);  // Test with velocity time x 10
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(blinkLED); // blinkLED to run every 1 seconds
  Serial.begin(9600);
  lcd.setCursor(1, 0);
  lcd.print("HH MM SS");
  lcd.setCursor(11, 0);
  lcd.print("DDDD");
}
//-------------------------------------------------------------------
void blinkLED() {
  blinkCount ++ ; // 1 second;
  //blinkCount += 60UL ; // test with  1 minute;
  //blinkCount += 3600UL ; // test with 1 hour;
  //blinkCount += 3600UL * 24UL; // test with 1 day;
  digitalWrite(led, !digitalRead(led));
  printOut = true;
}
//-------------------------------------------------------------------
void loop() {
  if (printOut == true) {
    myTime = blinkCount;
    mySeconds = myTime % 60;
    myTime /= 60; // now it is minutes
    myMinutes = myTime % 60;
    myTime /= 60; // now it is hours
    myHours = myTime % 24;
    myTime /= 24; // now it is days
    myDay = myTime % 24;
    lcd.setCursor(1, 1);
    if (myHours < 10)
      lcd.print("0");
    lcd.print(myHours);
    lcd.print(":");
    if (myMinutes < 10)
      lcd.print("0");
    lcd.print(myMinutes);
    lcd.print(":");
    if (mySeconds < 10)
      lcd.print("0");
    lcd.print(mySeconds);
    lcd.print(" ");
    lcd.print("    ");
    lcd.setCursor(11, 1);
    if (myDay < 10)
      lcd.print("000");
    if (myDay >= 10 and myDay < 100)
      lcd.print("00");
    if (myDay >= 100 and myDay < 1000)
      lcd.print("0");
    lcd.print(myDay);
    printOut = false;
  }
}

Thnx, this would take me a hour. For me to understand whats going on I wrote code for only seconds.

static uint32_t lastTime = -1000;
static uint32_t count = 0;
uint32_t now = millis();

void printDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0

  Serial.print(":");
  if (digits < 10)
    //Serial.print('0');
    Serial.print('0');
  //Serial.print(digits);
  Serial.print(digits);
}

void setup() {
  Serial.begin(9600);
}

uint16_t seconds = 0, minutes = 0, hours = 0, days = 0;

void loop() {
  if (now - lastTime >= 1000) {
    lastTime = now;
    now = count;
    ++count;

    seconds = now % 60;
    now /= 60;
    minutes = now % 60;
    now /= 60;
    hours = now % 24;
    days = now / 24;
    Serial.println(seconds);
    printDigits(seconds);
      Serial.println();
    
  }
}

It compiles correct but the output is only 2 rows:
00:15:01.725 -> 0
00:15:01.725 -> :00
any idea why??

Look at where now is updated in your code, and where it is in mine.