# Clock having time dilation

So I made a clock but now for some reason it has time dilation.

It started 16:30 4/1/2018 but at 07:30 it was at around 7:07. I belive this has to do with CPU speed but I’m new to this. Help?!

Code

``````#include <LiquidCrystal.h>

LiquidCrystal lcd(6, 7, 13, 12, 11, 10);

/* Todays date*/
int seconds = 50;
int minutes = 34;
int hours = 7;
int day = 2;
int month = 4;
int year = 2018;
/*Maximum date*/
int mseconds = 60;
int mminutes = 60;
int mhours = 24;
int mday = 30;
int mmonth = 13;
/*Alarm settings*/
int aseconds = 0;
int aminutes = 35;
int ahours = 7;
int amonth = 4;
int ayear = 2018;
int sound = 3000;

void setup() {
lcd.begin(16, 2);
}

void loop() {
delay(1000);
if (month == 1)
{
mday = 32;
}
if (month == 2)
{
mday = 29;
}
if (month == 3)
{
mday = 32;
}
if (month == 4)
{
mday = 31;
}
if (month == 5)
{
mday = 32;
}
if (month == 6)
{
mday = 31;
}
if (month == 7)
{
mday = 32;
}
if (month == 8)
{
mday = 32;
}
if (month == 9)
{
mday = 31;
}
if (month == 10)
{
mday = 32;
}
if (month == 11)
{
mday = 31;
}
if (month == 12)
{
mday = 32;
}

seconds = seconds + 1;
if (seconds == mseconds)
{
seconds = 0;
minutes = minutes + 1;
if (minutes == mminutes)
{
minutes = 0;
hours = hours + 1;
if (hours == mhours)
{
hours = 0;
day = day + 1;
if (day == mday)
{
day = 1;
month = month + 1;
if (month == mmonth)
{
month = 1;
year = year + 1;
}
}
}
}
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print(month);
lcd.print("/");
lcd.print(day);
lcd.print("/");
lcd.print(year);
lcd.setCursor(0,2);
lcd.print(hours);
lcd.print(":");
lcd.print(minutes);
lcd.print(":");
lcd.print(seconds);
alarm();
}

int alarm()
{
if (seconds == aseconds)
{
if (minutes == aminutes)
{
if (hours == ahours)
{
{
if (month == amonth)
{
if (year == ayear)
{
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
tone(5, sound);
delay(250);
noTone(5);
tone(5, sound);
delay(250);
noTone(5);
delay(1000);
seconds = seconds + 15;
}
}
}
}
}
}
}
``````

Code updated

You are correct.

Paul

``````int aday = 2 || 3 || 4 || 5 || 6 || 9 || 10 || 11 || 12 || 13 || 16 || 17 || 18 || 19 || 20 || 23 || 24 ||25 || 26 || 27 || 30;
``````

I have never seen a variable initialized that way. Print the value of aday in setup(). Is the value what you expect?

Seem a bit of a long winded way to get aday = 1.

Think about what your sketch does: It waits 1 second using the delay() function. THEN it begins calculating the seconds, minutes, hours etc. numbers. This also takes some time. Only when all calculations are done and sent to the LCD then the next delay() is called. This will not keep the correct time even if the processor speed is correct.
Search the forum for "timing without delay" will give you tons of tutorials of how this can be done right

groundFungus:

``````int aday = 2 || 3 || 4 || 5 || 6 || 9 || 10 || 11 || 12 || 13 || 16 || 17 || 18 || 19 || 20 || 23 || 24 ||25 || 26 || 27 || 30;
``````

I have never seen a variable initialized that way. Print the value of aday in setup(). Is the value what you expect?

Seem a bit of a long winded way to get aday = 1.

I got that fixed. I placed the numbers in different variables (ex. aday2).

``````int aday = 2;
``````

int amonth = 4;
int ayear = 2018;

Are you trying to make an alarm which sounds only on weekdays? If so:

• April 28 is not a weekday: it is a Saturday.
• You forgot Monday, April 30.
• What will you do once April is over?
• There are easier ways to get at the day of the week.
``````int yearday = 0;
int weekday = 0;

// This next part figures out the day of the year.
// We number the days of the year from 1 to 365.
yearday = day;
if (month > 1)  yearday = yearday + 31;
if (month > 2)  yearday = yearday + 28; // TODO: take care of leap years!
if (month > 3)  yearday = yearday + 31;
if (month > 4)  yearday = yearday + 30;
if (month > 5)  yearday = yearday + 31;
if (month > 6)  yearday = yearday + 30;
if (month > 7)  yearday = yearday + 31;
if (month > 8)  yearday = yearday + 31;
if (month > 9)  yearday = yearday + 30;
if (month > 10) yearday = yearday + 31;
if (month > 11) yearday = yearday + 30;

// This next part assumes that the year begins on a Monday.
// It will work all right for 2018, which indeed began on a Monday.
// To work with other years, it will need to be changed.
// We are numbering the days of the week as follows:
// Monday is day 1, Tuesday is day 2, and so forth. Sunday is day 7.
// Because the year 2018 began on a Monday, we start by doing this:
weekday = yearday;
// For the first seven days of the year 2018, this will suffice.
// (That is because day 1 of the year 2018 falls on day 1 of the week, etc.)
// But as soon as we get to day 8 of the year and beyond, we get garbage.
// (After all, a week has only 7 days!)
// Here is how we clean up the garbage:
while (weekday > 7) {
weekday = weekday - 7;
}
// What that does is, it subtracts 7 days (one whole week) at a time
// until it gets a number in the range 1 through 7.
// Because of the "while" keyword, it will keep subtracting
// until our number is small enough.
``````

Then, for the alarm, don't check the value of `day`. Check the value of `weekday`.

olf2012:
Think about what your sketch does: It waits 1 second using the delay() function. THEN it begins calculating the seconds, minutes, hours etc. numbers. This also takes some time. Only when all calculations are done and sent to the LCD then the next delay() is called.

Yes, that’s what’s going on.

By doing the math, it seems that the code is going through the loop once every 1026 milliseconds.
The “lazy” way to fix this would be shorten the `delay` time by 26 milliseconds: use `delay(974)` instead of `delay(1000)`. Crude, but perhaps good enough for a hobby project.

A less lazy way to fix it would be to use a different way of keeping time, several of which are mentioned here:

When it gets to 10cm, push!