My timer doesn't work as expected.

Hi all,

I'm a complete noob, but I think I am learning this language ok. Until this happens:

I wrote a simple timer program. I was expecting to see the seconds revert to 0 when they got to 60, but as you can see from the attachments, they continued to count upwards. Then a very weird thing happened. It jumped from 19552 to 25874 and then from 25927 to -32410...

So what happened. Is my code incorrect to get the seconds to start back at zero when they reach 60, and then add a 1 in the minutes place???

int seconds;
int minutes;
int hours;

void setup() {
    seconds = 0;
    minutes = 0;
    hours = 0;
    Serial.begin(9600);
}

void loop() {
    Serial.print (seconds);
    Serial.print (":");
    Serial.print (minutes);
    Serial.print (":");
    Serial.println (hours);
    delay(1000);
    seconds++;
    if (seconds == 60);
    {
      minutes++;
      seconds = 0;
    }
    if (minutes == 60);
    {
      hours++;
      minutes = 0;
 //     seconds = 0;
    }
}

There should be no semicolon after "if"

  if (seconds == 60);

The trailing semicolon should not be there. It will be the only code that is executed dependant on seconds equalling 60

The OP has probably understood that every C Language line should be terminated by a semicolon, and accordingly he has placed a terminating semicolon at the end of the if() structure. Hopefully, some one will explain that all lines of C Language are not be terminated by semicolons. What are those lines that need semicolon terminations?

The OP has probably understood that every C Language line should be terminated by a semicolon,

Lines of code have no meaning in C, statements and conditionals are what matters

Each statement needs to be terminated with a semicolon so that the compiler knows where it ends
eg

x = 123;
char c = 'z';
period = start - end;

Conditionals should not be followed by a semicolon
eg

if (x == 9)
while (z < 456)

@OP

Alternate version of your timer/clock using % (modulus) and / (division) operators.

int seconds;
int minutes;
int hours;

void setup() 
{
    seconds = 0;
    minutes = 0;
    hours = 0;
    Serial.begin(9600);
}

void loop() 
{
    Serial.print (seconds);
    Serial.print (":");
    Serial.print (minutes);
    Serial.print (":");
    Serial.println (hours);
    //--------------------
    delay(10);
    seconds++;
    byte x = seconds;
    seconds = x%60;      //takes the remainder : shows: 0 - 59 - 0
    //----------------
    minutes += x/60;    //accumulates minutes
    byte y = minutes;
    //----------------
    minutes = y%60;      //shows minutes: 0 - 59 - 0
    hours += y/60;       //accumulates hours
    //-----------------
}

GolamMostafa:
The OP has probably understood that every C Language line should be terminated by a semicolon, and accordingly he has placed a terminating semicolon at the end of the if() structure. Hopefully, some one will explain that all lines of C Language are not be terminated by semicolons. What are those lines that need semicolon terminations?

The failure is thinking in terms of lines instead of statements.

GolamMostafa:
@OP

Alternate version of your timer/clock using % (modulus) and / (division) operators.

The code you post cannot work, and why would you introduce (double) division when it is not needed?

Danois90:
The code you post cannot work, and why would you introduce (double) division when it is not needed?

Have you run these codes? I tested these codes prior to posting. You may suggest modifications and improvements -- you just can't say that the codes are not working!

GolamMostafa:
Have you run these codes? I tested these codes prior to posting. You may suggest modifications and improvements -- you just can't say that the codes are not working!

You code would cause seconds to be increased ~100 times per second, this is IMHO defunct behaviour :slight_smile:

Very awesome!!! Thank you. So lesson learned; no semicolon after conditional statements. Is that because the curly bracket is there?

Second, what about the jump in seconds? Did anybody see a reason for that? And why would they jump from a high positive to a high negative?

Croy007:
Is that because the curly bracket is there?

No. It's because the language is poorly designed. There are countless syntactically valid constructs that are handily discarded by the optimizer because they have no side-effects. Welcome to C++.

Do your current and future self a favour. Always use curly brackets with conditionals. (And don't put semicolons immediately after the closing parenthesis of if-statements. :wink: )

And why would they jump from a high positive to a high negative?

Excellent observation. That would be a symptom of an integer overflow.

No. It's because the language is poorly designed. There are countless syntactically valid constructs that are handily discarded by the optimizer because they have no side-effects. Welcome to C++.

Excellent. So all of our programming is based on a "poorly designed", dare I say it, flawed, language. Got it! How did we get to here, wow. Looks like my brain will force me to learn some history now, haha!

Excellent observation. That would be a symptom of an integer overflow.

So to cure the integer overflow, I would use long? But even that has a limitation, correct?

Croy007:
So to cure the integer overflow, I would use long?

That only delays the inevitable. All C integer datatypes have a fixed size so they eventually overflow. The C / C++ language does not include run-time range checking so the result for signed datatypes is exactly what you observed.

But even that has a limitation, correct?

Correct.

How did we get to here, wow.

A combination of things like "highly portable", "market dominance", and "monopolist practices".

Thank you all for helping. Now on to the next programming failure haha!!!

Danois90:
The code you post cannot work, and why would you introduce (double) division when it is not needed?

Danois90:
You code would cause seconds to be increased ~100 times per second, this is IMHO defunct behaviour :slight_smile:

Now, you have discovered that the codes are working but at a speed of x100 times! This is expected as the time scale of the Time-Tick has been reduced to only 10 ms in place of 1000 ms. Why? Who is going to wait for an hour to see the hour-hand UP?