A simple clock that doesn't behave like a normal clock should

I am working on a project where some lights will be automatically adjusted during the day, so that will require a clock that will provide variables for hours, minutes and seconds . It should also be atjustable wih the help of two buttons. However, it seems that my if statement if(seconds >= 60){seconds = 0; } doesn't work and i don't know why. In the output code i first pushed the minute button and then the hour button. Please help ! :slight_smile:

//    {}

const int hButt = 9;
const int mButt = 7;
unsigned long hours, minutes, seconds;
int timeklikk = 0;
int minuttklikk = 0;

/////////////////////////////////////////////////////////////////////////////
void setup() {

  Serial.begin(9600); 
  pinMode(hButt, INPUT); // Button to adjust hour
  pinMode(mButt, INPUT); // Button to adjust minute
}

/////////////////////////////////////////////////////////////////////////////
void loop() {

  unsigned long seconds = millis() / 1000; // Seconds after starting sketch
  seconds = seconds + timeklikk*3600 + minuttklikk*60; // Justert ant sek

  boolean bstH = digitalRead(hButt);  // Hour button state
  boolean bstM = digitalRead(mButt); // Minute button state
  if(bstH == HIGH){timeklikk++;}    // Justere hour
  if(bstM == HIGH){minuttklikk++;} // Justere minute

  Serial.println(seconds); // Print the number of seconds after launch
/*
  unsigned long hours   = t / 3600; // Antall timer
  unsigned long minutes = t / 60;  // Antall minutter
  unsigned long seconds = t;      // Number of 

  while(seconds >= 86400) {seconds = 0;} // Reset number of seconds after a day
  if(hours >= 24)    {hours   - 24;}    // Reset number of hours after a day
  if(minutes  >= 60) {minutes - 60;}   // Reset number of minutes  after an hour
  if(seconds  >= 60) {seconds - 60;}  // Reset number of seconds after a minute
  
  incrementTime();
*/
  if(seconds > 60){
    //seconds = 0;     // Doesn't work ?
    //seconds = seconds - 60;
    seconds = seconds - seconds;
    minutes++;
    if(minutes > 60){
      minutes = 0;
      hours++;
      if(hours > 24){
        hours = 0;
      }
    }
  }

  // Printe tiden som 19:46:03
  if(hours < 10){Serial.print("0");}
  Serial.print(hours);
  Serial.print(":");

  if(minutes < 10){Serial.print("0");}
  Serial.print(minutes);
  Serial.print(":");
  if(seconds < 10){Serial.print("0");}
  Serial.println(seconds);

  delay(1000);
}
/*
void incrementTime(){

  if(seconds >= 60){
    seconds = 0;
    minutes++;
    if(minutes >= 60){
      minutes = 0;
      hours++;
      if(hours >= 24){
        hours = 0;
      }
    }
  }
}
*/
0

00:00:00

1

00:00:01

2

00:00:02

3

00:00:03

4

00:00:04

65

00:01:00

66

00:02:00

67

00:03:00

68

00:04:00

69

00:05:00

70

00:06:00

71

00:07:00

72

00:08:00

73

00:09:00

3674

00:10:00

7275

00:11:00

7276

00:12:00

7277

00:13:00

7278

00:14:00

7279

00:15:00

7280

00:16:00

Have you ever think when you restart your board you will have to setup the time every time.This is bad and not a good practice.You should use an RTC for what you wont to do ...

I know that is not optimal, but right now i don't have an RTC chip. Besides, i am fairly new to Arduino and i could use the practice of making a clock :slight_smile:

Of course "seconds = 0;" doesn't work because at the top of loop() you re-calculate seconds:

  unsigned long seconds = millis() / 1000; // Seconds after starting sketch
  seconds = seconds + timeklikk*3600 + minuttklikk*60; // Justert ant sek

I suggest you organize your code to count seconds indefinitely in an unsigned long variable. That will last far beyond your's and your children's lifetimes.

Then when you want to display the time just convert that number to hours, minutes, seconds.

You should be aware that an Arduino is not a good time keeper - its clock is probably not running at exactly 16 MHz.

...R

There's a nice library that "adds timekeeping functionality to Arduino with or without external timekeeping hardware" that takes care of the minutiae of timekeeping (pun intended):

http://playground.arduino.cc/Code/Time

You can set the time from your attached computer via the USB port with the included processing example.

-transfinite

There's a nice library that "adds timekeeping functionality to Arduino with or without external timekeeping hardware" that takes care of the minutiae of timekeeping (pun intended):

I second that :slight_smile:

Robin2:
I suggest you organize your code to count seconds indefinitely in an unsigned long variable. That will last far beyond your's and your children's lifetimes.

Then when you want to display the time just convert that number to hours, minutes, seconds.

You should be aware that an Arduino is not a good time keeper - its clock is probably not running at exactly 16 MHz.

...R

I don't know why i didn't think of that, thank you :slight_smile: I got it working now, at least until the tenth hour, when this happens:

00:00:00       Number of seconds: 0
00:00:01       Number of seconds: 1
00:00:02       Number of seconds: 2
00:00:03       Number of seconds: 3
00:00:04       Number of seconds: 4
00:00:05       Number of seconds: 5
00:01:06       Number of seconds: 66
00:01:07       Number of seconds: 67
00:01:08       Number of seconds: 68
00:02:09       Number of seconds: 129
00:03:10       Number of seconds: 190
00:04:11       Number of seconds: 251
00:05:12       Number of seconds: 312
01:05:13       Number of seconds: 3913
02:05:14       Number of seconds: 7514
03:05:15       Number of seconds: 11115
03:05:16       Number of seconds: 11116
03:05:17       Number of seconds: 11117
03:06:18       Number of seconds: 11178
03:06:19       Number of seconds: 11179
03:06:20       Number of seconds: 11180
03:06:21       Number of seconds: 11181
03:06:22       Number of seconds: 11182
03:06:23       Number of seconds: 11183
04:06:24       Number of seconds: 14784
05:06:25       Number of seconds: 18385
06:06:26       Number of seconds: 21986
07:06:27       Number of seconds: 25587
08:06:28       Number of seconds: 29188
09:06:29       Number of seconds: 32789
1193038:22:30       Number of seconds: 4294851750
1193038:22:31       Number of seconds: 4294851751
1193038:23:32       Number of seconds: 4294851812
1193038:24:33       Number of seconds: 4294851873
1193038:25:34       Number of seconds: 4294851934
1193039:25:35       Number of seconds: 4294855535
1193040:25:36       Number of seconds: 4294859136
1193041:25:37       Number of seconds: 4294862737
1193042:25:38       Number of seconds: 4294866338
1193042:25:39       Number of seconds: 4294866339
1193042:25:40       Number of seconds: 4294866340
1193042:25:41       Number of seconds: 4294866341
1193042:25:42       Number of seconds: 4294866342
1193042:25:43       Number of seconds: 4294866343
1193042:25:44       Number of seconds: 4294866344
1193042:25:45       Number of seconds: 4294866345
1193042:25:46       Number of seconds: 4294866346
1193042:25:47       Number of seconds: 4294866347
1193042:25:48       Number of seconds: 4294866348
1193042:25:49       Number of seconds: 4294866349
1193042:25:50       Number of seconds: 4294866350
1193042:25:51       Number of seconds: 4294866351
1193042:25:52       Number of seconds: 4294866352
1193042:25:53       Number of seconds: 4294866353
1193042:25:54       Number of seconds: 4294866354
1193042:25:55       Number of seconds: 4294866355
1193042:25:56       Number of seconds: 4294866356
1193042:25:57       Number of seconds: 4294866357
1193042:25:58       Number of seconds: 4294866358
1193042:25:59       Number of seconds: 4294866359
1193042:26:00       Number of seconds: 4294866360
1193042:26:01       Number of seconds: 4294866361

Seems to be working good except for that 10th hour, where 4294815361 seconds is added for no apparent reason ... I know i could use the time library but i'd like to code the entire thing myself :slight_smile:

Here is the new code

// Timeminus.ino
const int hButt = 9;
const int mButt = 7;
int timeklikk = 0;
int minuttklikk = 0;
unsigned long hours, minutes, seconds, days;
unsigned long tHours, tMinutes, tSeconds;

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

void loop() {

	unsigned long t = millis() / 1000; // Number of seconds after launch

	int bstH = digitalRead(hButt); // Hour button state
	int bstM = digitalRead(mButt); // Minute button state
	if(bstH == HIGH){timeklikk++;}   // Justere time
	if(bstM == HIGH){minuttklikk++;} // Justere minutt
	t = t + timeklikk*3600 + minuttklikk*60; // Justert ant sek

	hours = t / 3600;	// Number of hours
	tMinutes = t - hours*3600;	// Number of seconds minus those in full hours
	minutes = tMinutes / 60;	// Number of minutes
	tSeconds = t - hours*3600 - minutes*60;	// Number of seconds minus those in full hours and minutes
	seconds = tSeconds;		// Number of seconds

	days = hours / 24;	// Number of days
	if(days++){t = t - 86400;}	// Reset every day

  // Print everything
  if(hours < 10){Serial.print("0");}
  Serial.print(hours);
  Serial.print(":");
  if(minutes < 10){Serial.print("0");}
  Serial.print(minutes);
  Serial.print(":");
  if(seconds < 10){Serial.print("0");}
  Serial.print(seconds);
  Serial.print("       Number of seconds: ");
  Serial.println(t);
  delay(1000);
}

SirEmrys:
Seems to be working good except for that 10th hour, where 4294815361 seconds is added for no apparent reason ...

Well you would choose a very complicated way to update the value of seconds.

I intended you do the seconds value first and figure out everything else from the seconds

if (millis() - prevMillis >= 1000) {
    prevMillis += 1000;
    seconds ++;
}

Ensure that prevMillis is an unsigned long.

...R

Wow thank you so much that did it :slight_smile:

Here is the working code if anyone is interested

// Time_V4.ino
const int hButt = 9;
const int mButt = 7;
unsigned short hours, minutes, seconds;
unsigned long prevMillis;
int bstateH = 0;
int bstateM = 0;
int lastBstateH = 0;
int lastBstateM = 0;

void setup() {
	Serial.begin(9600); 
	pinMode(hButt, INPUT);
	pinMode(mButt, INPUT);
}

void loop() {

	incrementTime();
	knappstyring();

}

void incrementTime(){

	if (millis() - prevMillis >= 1000) {	// Legge til ett sekund
		prevMillis += 1000;
		seconds ++;
		printAltSammen();}

	if (seconds >= 60) {	// Legge til ett minutt om det har gått 60 sekunder
		minutes++;
		seconds = 0;}

	if (minutes >= 60) {	// Legge til en time om det har gått 60 minutter
		hours++;
		minutes = 0;}

	if (hours >= 24) {hours = 0;}	// Tilbakestille når klokken har fullført ett døgn
}

void printAltSammen(){
	// Printe alt sammen
	if(hours < 10){Serial.print("0");}
	Serial.print(hours);
	Serial.print(":");
	if(minutes < 10){Serial.print("0");}
	Serial.print(minutes);
	Serial.print(":");
	if(seconds < 10){Serial.print("0");}
	Serial.println(seconds);	
}

void knappstyring() {

	bstateH = digitalRead(hButt);
	bstateM = digitalRead(mButt);

	if (bstateH != lastBstateH) {
		if (bstateH == HIGH) {
			hours++;
		} 
		else {}
	}
	lastBstateH = bstateH;

	if (bstateM != lastBstateM) {
		if (bstateM == HIGH) {
			minutes++;
		} 
		else {}
	}
	lastBstateM = bstateM;
}